diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..2874476cf --- /dev/null +++ b/.editorconfig @@ -0,0 +1,40 @@ +[*] +charset=utf-8 +end_of_line=lf +insert_final_newline=true +indent_style=space +indent_size=4 +ij_any_block_comment_add_space = false +ij_any_block_comment_at_first_column = false +ij_any_line_comment_at_first_column = false +ij_any_line_comment_add_space = true + +[*.tiny] +indent_style=tab + +[*.bat] +end_of_line=crlf + +[*.yml] +indent_size=2 + +[*.patch] +trim_trailing_whitespace=false + +[*.java] +ij_continuation_indent_size = 4 +ij_java_class_count_to_use_import_on_demand = 999999 +ij_java_insert_inner_class_imports = false +ij_java_names_count_to_use_import_on_demand = 999999 +ij_java_imports_layout = *,|,$* +ij_java_generate_final_locals = true +ij_java_generate_final_parameters = true + +[test-plugin/**/*.java] +ij_java_use_fq_class_names = false + +[Paper-Server/src/main/resources/data/**/*.json] +indent_size = 2 + +[paper-api-generator/generated/**/*.java] +ij_java_imports_layout = $*,|,* diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a26c1d6db..5319c15d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,34 +2,34 @@ name: Build Plazma on: push: - branches: [ "ver/*", "feat/*", "dev/*", "expr/*", "ench/*", "impl/*" ] + branches: [ "ver/*", "dev/*", "feat/**/*" ] workflow_dispatch: env: ORG_NAME: PlazmaMC MC_VERSION: 1.20.2 MAIN_BRANCH: ver/1.20.1 - DEBUG: 'false' jobs: release: strategy: matrix: - base_jdk: [17] - graal: [latest] + base_jdk: [21] os: [ubuntu-22.04] if: "!startsWith(github.event.commits[0].message, '[CI-Skip]')" runs-on: ${{ matrix.os }} steps: - - name: Checkout action - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Checkout pages - uses: actions/checkout@v3 + - name: Checkout javadocs + uses: actions/checkout@v4 + if: github.ref_name == env.MAIN_BRANCH with: + repository: PlazmaMC/Javadocs path: javadoc - ref: gh-pages + ref: main token: ${{ secrets.GH_PAT }} - name: Validate Gradle Wrapper @@ -40,7 +40,7 @@ jobs: with: github-token: ${{ secrets.GH_PAT }} java-version: ${{ matrix.base_jdk }} - version: ${{ matrix.graal }} + version: latest cache: 'gradle' - name: Configure Git @@ -75,7 +75,7 @@ jobs: ./gradlew publish --stacktrace - name: Upload Artifacts - if: env.DEBUG == 'true' || !startsWith(github.ref_name, 'ver/') + if: "!startsWith(github.ref_name, 'ver/')" uses: actions/upload-artifact@v3 with: name: Artifacts diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 4657bfc9b..5c9c7a341 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -2,15 +2,15 @@ name: Test Gradle build script on: push: - branches: [ "ver/*", "feat/*", "dev/*", "expr/*", "ench/*", "impl/*" ] + branches: [ "ver/*", "dev/*", "feat/**/*" ] workflow_dispatch: jobs: release: strategy: matrix: - jdk: [19.0.2+7] - java: ['temurin'] + jdk: [21] + java: ['zulu'] os: [ubuntu-22.04] if: "!contains(github.event.commits[0].message, '[CheckSkip]')" diff --git a/.github/workflows/javadocs.yml b/.github/workflows/javadocs.yml deleted file mode 100644 index 93742fc6c..000000000 --- a/.github/workflows/javadocs.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Deploy Javadocs - -on: - push: - branches: ["gh-pages"] - workflow_dispatch: - -permissions: - contents: read - pages: write - id-token: write - -concurrency: - group: "pages" - cancel-in-progress: true - -jobs: - build: - if: "!startsWith(github.event.commits[0].message, '[CI-Skip]')" - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Pages - uses: actions/configure-pages@v3 - - - name: Build with Jekyll - uses: actions/jekyll-build-pages@v1 - with: - source: ./ - destination: ./_site - - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 47e0781ec..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Test build with Normal JDK - -on: - push: - branches: [ "ver/*", "feat/*", "dev/*", "expr/*", "ench/*", "impl/*" ] - workflow_dispatch: - -jobs: - release: - strategy: - matrix: - jdk: [19.0.2+7] - java: ['temurin'] - os: [ubuntu-22.04] - - if: "!startsWith(github.event.commits[0].message, '[CI-Skip]')" - runs-on: ${{ matrix.os }} - steps: - - name: Checkout action - uses: actions/checkout@v3 - - - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 - - - name: Set up JDK ${{ matrix.java }} ${{ matrix.jdk }} - uses: actions/setup-java@v3 - with: - distribution: ${{ matrix.java }} - java-version: ${{ matrix.jdk }} - cache: 'gradle' - - - name: Test build - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" && git config --global user.name "github-actions[bot]" - ./gradlew applyPatches --stacktrace - ./gradlew build --stacktrace diff --git a/.upstream-data b/.upstream-data index ed8bc95a6..18151be12 100644 --- a/.upstream-data +++ b/.upstream-data @@ -1,2 +1,2 @@ -purpurCommit = 6a6706d3b4f934845a44ecd7533bf53966e4857c -pufferfishCommit = 2c3f3fd4e1df97dc7ff8d770061138144847850e +purpurCommit = c46cb7ef66675e00a48e20c40febed7ff914f35d +pufferfishCommit = bc89152d4cd4bb0f9644da2fe10774df4cc25661 diff --git a/build-data/dev-imports.txt b/build-data/dev-imports.txt new file mode 100644 index 000000000..302359e8a --- /dev/null +++ b/build-data/dev-imports.txt @@ -0,0 +1,15 @@ +# You can use this file to import files from minecraft libraries into the project +# format: +# +# both fully qualified and a file based syntax are accepted for : +# authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java +# datafixerupper com.mojang.datafixers.DataFixerBuilder +# datafixerupper com/mojang/datafixers/util/Either.java +# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId: +# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter +# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java +# To import minecraft data files, like the default chat type, use `mc_data` as the prefix: +# mc_data chat_type/chat.json +# mc_data dimension_type/overworld.json +# + diff --git a/build.gradle.kts b/build.gradle.kts index 2dfef4c9c..78cbe1e61 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { java `maven-publish` id("com.github.johnrengelman.shadow") version "8.1.1" apply false - id("io.papermc.paperweight.patcher") version "1.5.7-SNAPSHOT" + id("io.papermc.paperweight.patcher") version "1.5.10" } repositories { @@ -23,15 +23,38 @@ dependencies { paperclip("io.papermc:paperclip:3.0.3") } -subprojects { +allprojects { apply(plugin = "java") + apply(plugin = "maven-publish") java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + + publishing { + repositories { + maven { + name = "githubPackage" + url = uri("https://maven.pkg.github.com/PlazmaMC/Plazma") + + credentials { + username = System.getenv("GITHUB_USERNAME") + password = System.getenv("GITHUB_TOKEN") + } + } + + publications.register("gpr") { + from(components["java"]) + } + } + } +} + +subprojects { + apply(plugin = "java") tasks { withType().configureEach { options.compilerArgs.add("--add-modules=jdk.incubator.vector") - options.encoding = "UTF-8" + options.encoding = Charsets.UTF_8.name() options.release.set(17) } @@ -80,28 +103,39 @@ paperweight { } } -val upstreamTask = tasks.register("updateUpstream") { - val tempDir = layout.cacheDir("updateUpstream"); - val file = "gradle.properties"; +tasks { + generateDevelopmentBundle { + apiCoordinates.set("org.plazmamc.plazma:plazma-api") + mojangApiCoordinates.set("io.papermc.paper:paper-mojangapi") + libraryRepositories.addAll( + "https://repo.maven.apache.org/maven2/", + "https://papermc.io/repo/repository/maven-public/" + ) + } + + register("updateUpstream") { + val tempDir = layout.cacheDir("updateUpstream"); + val file = "gradle.properties"; - doFirst { - val apiResponse = layout.cache.resolve("apiResponse.json"); - download.get().download("https://api.github.com/repos/PaperMC/Paper/commits/master", apiResponse); - val latestCommit = gson.fromJson(apiResponse)["sha"].asString; + doFirst { + val apiResponse = layout.cache.resolve("apiResponse.json"); + download.get().download("https://api.github.com/repos/PaperMC/Paper/commits/master", apiResponse); + val latestCommit = gson.fromJson(apiResponse)["sha"].asString; - copy { - from(file) - into(tempDir) - filter { line: String -> - line.replace("paperCommit = .*".toRegex(), "paperCommit = $latestCommit") + copy { + from(file) + into(tempDir) + filter { line: String -> + line.replace("paperCommit = .*".toRegex(), "paperCommit = $latestCommit") + } } } - } - doLast { - copy { - from(tempDir.file("gradle.properties")) - into(project.file(file).parent) + doLast { + copy { + from(tempDir.file("gradle.properties")) + into(project.file(file).parent) + } } } } diff --git a/gradle.properties b/gradle.properties index 914b4914b..2853a2b56 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,8 @@ group = org.plazmamc.plazma version = 1.20.2-R0.1-SNAPSHOT +mcVersion = 1.20.2 -paperCommit = 38376f43a0c268e5223746cab13910f55e5ecf41 +paperCommit = 931781c220b98dde0159c9a3c8dce06c3b2b1e13 org.gradle.caching = true org.gradle.parallel = true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3fa8f862f..1af9e0930 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 0adc8e1a5..1aa94a426 100755 --- a/gradlew +++ b/gradlew @@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/patches/api/0001-Pufferfish-API-Changes.patch b/patches/api/0001-Pufferfish-API-Changes.patch index b5078eca4..aec2e5387 100644 --- a/patches/api/0001-Pufferfish-API-Changes.patch +++ b/patches/api/0001-Pufferfish-API-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Kevin Raneri -Date: Sat, 30 Sep 2023 09:45:48 +0000 +Date: Sun, 26 Nov 2023 23:32:01 +0000 Subject: [PATCH] Pufferfish API Changes Original: Kevin Raneri @@ -20,10 +20,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/build.gradle.kts b/build.gradle.kts -index 639651972fddce4dff63a0f0a7e566a15b9e2dd6..6c0df825238ca037abeb2ba619983b6f554180ea 100644 +index e827ee211e3c65dc68ac5867fd8476639df63645..b9c75a190dbd7a90ac5ef0fbc6e6fe34806acc4e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -46,6 +46,7 @@ dependencies { +@@ -47,6 +47,7 @@ dependencies { apiAndDocs("net.kyori:adventure-text-logger-slf4j") api("org.apache.logging.log4j:log4j-api:$log4jVersion") api("org.slf4j:slf4j-api:$slf4jVersion") @@ -31,21 +31,26 @@ index 639651972fddce4dff63a0f0a7e566a15b9e2dd6..6c0df825238ca037abeb2ba619983b6f implementation("org.ow2.asm:asm:9.4") implementation("org.ow2.asm:asm-commons:9.4") -@@ -102,6 +103,8 @@ tasks.jar { +@@ -106,6 +107,13 @@ val generateApiVersioningFile by tasks.registering { + } + } - tasks.withType { - val options = options as StandardJavadocDocletOptions -+ options.addStringOption("-add-modules", "jdk.incubator.vector") // Pufferfish -+ options.addStringOption("Xdoclint:none", "-quiet") // Pufferfish - options.overview = "src/main/javadoc/overview.html" - options.use() - options.isDocFilesSubDirs = true ++// Pufferfish Start ++tasks.withType { ++ val compilerArgs = options.compilerArgs ++ compilerArgs.add("--add-modules=jdk.incubator.vector") ++} ++// Pufferfish End ++ + tasks.jar { + from(generateApiVersioningFile.map { it.outputs.files.singleFile }) { + into("META-INF/maven/${project.group}/${project.name}") diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java new file mode 100644 -index 0000000000000000000000000000000000000000..ff42019da93c365ea1365e2e0f7c51b196a10948 +index 0000000000000000000000000000000000000000..10310fdd53de28efb8a8250f6d3b0c8eb08fb68a --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java -@@ -0,0 +1,162 @@ +@@ -0,0 +1,161 @@ +package gg.pufferfish.pufferfish.sentry; + +import com.google.gson.Gson; @@ -61,7 +66,6 @@ index 0000000000000000000000000000000000000000..ff42019da93c365ea1365e2e0f7c51b1 +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; -+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SentryContext { @@ -94,7 +98,7 @@ index 0000000000000000000000000000000000000000..ff42019da93c365ea1365e2e0f7c51b1 + ThreadContext.remove("pufferfishsentry_playerid"); + } + -+ public static void setEventContext(@NotNull Event event, @NotNull RegisteredListener registration) { ++ public static void setEventContext(Event event, RegisteredListener registration) { + setPluginContext(registration.getPlugin()); + + try { @@ -167,43 +171,43 @@ index 0000000000000000000000000000000000000000..ff42019da93c365ea1365e2e0f7c51b1 + private Event event; + private RegisteredListener registeredListener; + -+ public @Nullable Plugin getPlugin() { ++ public Plugin getPlugin() { + return plugin; + } + -+ public void setPlugin(@Nullable Plugin plugin) { ++ public void setPlugin(Plugin plugin) { + this.plugin = plugin; + } + -+ public @Nullable Command getCommand() { ++ public Command getCommand() { + return command; + } + -+ public void setCommand(@Nullable Command command) { ++ public void setCommand(Command command) { + this.command = command; + } + -+ public @Nullable String getCommandLine() { ++ public String getCommandLine() { + return commandLine; + } + -+ public void setCommandLine(@Nullable String commandLine) { ++ public void setCommandLine(String commandLine) { + this.commandLine = commandLine; + } + -+ public @Nullable Event getEvent() { ++ public Event getEvent() { + return event; + } + -+ public void setEvent(@Nullable Event event) { ++ public void setEvent(Event event) { + this.event = event; + } + -+ public @Nullable RegisteredListener getRegisteredListener() { ++ public RegisteredListener getRegisteredListener() { + return registeredListener; + } + -+ public void setRegisteredListener(@Nullable RegisteredListener registeredListener) { ++ public void setRegisteredListener(RegisteredListener registeredListener) { + this.registeredListener = registeredListener; + } + } @@ -385,7 +389,7 @@ index 0000000000000000000000000000000000000000..ae2464920c9412ac90b819a540ee58be + +} diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java -index 3a9aaca2e76411a9c27f9f5e0f22d060d5a66d06..9584e245144b561b4f6745b2f26a4f69a6f92891 100644 +index c80faa079eca1564847070f0338fc98024639829..e632d51d3487eb4807243b6705999ad124466bf5 100644 --- a/src/main/java/org/bukkit/map/MapPalette.java +++ b/src/main/java/org/bukkit/map/MapPalette.java @@ -1,6 +1,7 @@ @@ -476,10 +480,10 @@ index eaefbb00e9993d54906cc8cf35cf753c0d6c7707..301e82369603f3dd6e6c1bd380da4bac if (cloader instanceof PluginClassLoader) { diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..7572a0bf6614b02be3cbccc7b86e52ee1b8df621 100644 +index f9b57b872780aa6b9b959494874b57c7a8ff0c53..90953bfc81168068a281be4d2d3942d5e7dd69ff 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -48,6 +48,8 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -50,6 +50,8 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm private io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup classLoaderGroup; // Paper public io.papermc.paper.plugin.provider.entrypoint.DependencyContext dependencyContext; // Paper @@ -488,7 +492,7 @@ index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..7572a0bf6614b02be3cbccc7b86e52ee static { ClassLoader.registerAsParallelCapable(); } -@@ -183,6 +185,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -197,6 +199,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm throw new ClassNotFoundException(name); } @@ -496,7 +500,7 @@ index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..7572a0bf6614b02be3cbccc7b86e52ee @Override protected Class findClass(String name) throws ClassNotFoundException { if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) { -@@ -190,7 +193,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -204,7 +207,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm } Class result = classes.get(name); @@ -505,7 +509,7 @@ index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..7572a0bf6614b02be3cbccc7b86e52ee String path = name.replace('.', '/').concat(".class"); JarEntry entry = jar.getJarEntry(path); -@@ -237,6 +240,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -251,6 +254,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm this.setClass(name, result); // Paper } @@ -513,7 +517,7 @@ index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..7572a0bf6614b02be3cbccc7b86e52ee return result; } -@@ -251,6 +255,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -265,6 +269,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm // Paper end super.close(); } finally { diff --git a/patches/api/0002-Purpur-API-Changes.patch b/patches/api/0002-Purpur-API-Changes.patch index 9e84cb8be..b8242ad23 100644 --- a/patches/api/0002-Purpur-API-Changes.patch +++ b/patches/api/0002-Purpur-API-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath -Date: Sat, 30 Sep 2023 09:53:53 +0000 +Date: Sun, 26 Nov 2023 23:37:25 +0000 Subject: [PATCH] Purpur API Changes Original: PurpurMC @@ -24,6 +24,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +diff --git a/build.gradle.kts b/build.gradle.kts +index b9c75a190dbd7a90ac5ef0fbc6e6fe34806acc4e..41d7b75e904b94073dfcd12b776a7759a963b66f 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -126,6 +126,8 @@ tasks.jar { + } + + tasks.withType { ++ (options as StandardJavadocDocletOptions).addStringOption("-add-modules", "jdk.incubator.vector") // Purpur - our javadocs need this for pufferfish's SIMD patch ++ (options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet") // Purpur - silence Paper's bajillion javadoc warnings + val options = options as StandardJavadocDocletOptions + options.overview = "src/main/javadoc/overview.html" + options.use() diff --git a/src/main/java/co/aikar/timings/TimedEventExecutor.java b/src/main/java/co/aikar/timings/TimedEventExecutor.java index 8f29c1561ba5916cb5634392edd8bd2a5a294a51..6fbc64e0f214d0c8e5afcbe385e414a4e1fe1c72 100644 --- a/src/main/java/co/aikar/timings/TimedEventExecutor.java @@ -196,10 +209,10 @@ index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48c @Override diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index f78b5fd3c3347d28da58777bff88903d2eb140f6..584e3b08935f43beb27f478cc72229b6a5f40689 100644 +index 4863d9f21f0a0f11974be85360edc587ffd7eab3..8ea42a1f07df756bf504609d2bbff578f20bb808 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2756,4 +2756,127 @@ public final class Bukkit { +@@ -2832,4 +2832,127 @@ public final class Bukkit { public static Server.Spigot spigot() { return server.spigot(); } @@ -418,10 +431,10 @@ index 918a045165cdcde264bc24082b7afebb407271de..687d11619379aead7f665d4a5f8f8bcc + // Purpur end } diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index da6e36a16e609272b60fc41ff69a6fa3c34926c0..eba4e7ebe3530fd8cb3ecbe72f703932df8721c9 100644 +index 7ca70b269e15e818e61a9329e2775789abb4bc73..aa9ca3e33903747a455ad0949387684ce4b917af 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -11050,4 +11050,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -11054,4 +11054,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla public boolean isEnabledByFeature(@NotNull World world) { return Bukkit.getDataPackManager().isEnabledByFeature(this, world); } @@ -582,10 +595,10 @@ index bce07d84cafca677bb6fad78c21b82097f06430c..4ef0fa4f1ef72bb784674671473c6a32 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 8d8fe04e6b09d2a5b1cc05002073df5c58cdcb96..aaef58468a3c31f35e5067ed4263e9dd3fbddddd 100644 +index f1fa97d12f97baf97beb92ca0719cf3cf906b225..dd99f53e3d559685a4b3a454a9e607c310fc6aff 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2121,6 +2121,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2190,6 +2190,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Paper end @@ -604,7 +617,7 @@ index 8d8fe04e6b09d2a5b1cc05002073df5c58cdcb96..aaef58468a3c31f35e5067ed4263e9dd /** * Sends the component to the player * -@@ -2404,4 +2416,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2473,4 +2485,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ boolean isOwnedByCurrentRegion(@NotNull Entity entity); // Paper end - Folia region threading API @@ -711,10 +724,10 @@ index 8d8fe04e6b09d2a5b1cc05002073df5c58cdcb96..aaef58468a3c31f35e5067ed4263e9dd + // Purpur end } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index da524a71af74b02515b037f7fe09ba6988e2c8bf..3679c3b8d31ab8de08ecabd56bf92ffc062f971c 100644 +index f72f0f0f8eee95f95adc969d55ba7de82ee30e2a..2f1adae519e45743828be06df15b5f33045ae18b 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -4008,6 +4008,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -4211,6 +4211,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable public DragonBattle getEnderDragonBattle(); @@ -964,10 +977,10 @@ index 138d2530de2410f4a9424dabd3e5ce0cd1c1dcd2..10a8d64ad2da0be2c14f34c3e7d1957c // Paper start /** diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index 762cb07861ca8ff058ce8d57ea6c15df1e588bf3..98de85d1382fe84cdc2e2c9db04bf1b4f157291c 100644 +index d340ddcf6924cc834455de3acbbac91ab9c66e39..f21a0fa8420b3fd0a3655a0af998da8f8a66c4b1 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1049,4 +1049,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent +@@ -1065,4 +1065,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ @NotNull String getScoreboardEntryName(); // Paper end - entity scoreboard name @@ -1116,10 +1129,10 @@ index 58017fce436cdbda255f7172fbdadb726d4b113c..05600fc8bf2a61aca8094029bc4c208a + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 19e58e62ae442ef9be02ca7fa2f55e370a54afa4..994e026d68fcda9a4c34a8b161a06623f4437dff 100644 +index a599ed2795ba1baf2cbb465d1c7145580c27e1ea..298acbfb93663e40e627f6a47d51fd87a1551feb 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1192,4 +1192,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -1243,4 +1243,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setBodyYaw(float bodyYaw); // Paper end @@ -1187,10 +1200,10 @@ index bc84b892cae5fe7019a3ad481e9da79956efa1fe..48eb5b00c460cccde29d327cef1d63fc + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 20fa1024f9ad8f478a347be5c554b5e45b398a1c..0df709ed758401f04b3f565dc1f6492a55f5363c 100644 +index 9130a57cf6ef5d543703a03aeed07aa17b1ab7e8..fd465ab769b2ed9ff5c36d8479241aa8aa25953d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3278,4 +3278,122 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3370,4 +3370,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end @@ -1219,6 +1232,7 @@ index 20fa1024f9ad8f478a347be5c554b5e45b398a1c..0df709ed758401f04b3f565dc1f6492a + + /** + * Reset the idle timer back to 0 ++ * @deprecated Use {@link #resetIdleDuration()} instead + */ + void resetIdleTimer(); + @@ -1454,10 +1468,29 @@ index c60be4fd24c7fdf65251dd6169e5e1ac3b588d95..569deccd2f1cf21da9b5906433ac493c + boolean canDoUnsafeEnchants(); + + void setDoUnsafeEnchants(boolean canDoUnsafeEnchants); ++ // Purpur end + } +diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java +index 0217f98a74140bbae454d467de27c12b6060ca75..fba5b867ea9de36b45ef25c2a93fc436701bb3d9 100644 +--- a/src/main/java/org/bukkit/inventory/ItemFactory.java ++++ b/src/main/java/org/bukkit/inventory/ItemFactory.java +@@ -355,4 +355,14 @@ public interface ItemFactory { + */ + @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, boolean allowTreasure, @NotNull java.util.Random random); + // Paper end - enchantWithLevels API ++ ++ // Purpur start ++ /** ++ * Returns the lines of text shown when hovering over an item ++ * @param itemStack The ItemStack ++ * @param advanced Whether advanced tooltips are shown ++ * @return the list of Components ++ */ ++ @NotNull java.util.List getHoverLines(@NotNull ItemStack itemStack, boolean advanced); + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 0af73cc04edb93b9772136d4d808f657ea40e733..c733206b769d7a55076d863757fcac1a129033b7 100644 +index 0af73cc04edb93b9772136d4d808f657ea40e733..ed168cba3692f55ac976c6ef31525e83ae36f5f9 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -17,6 +17,18 @@ import org.bukkit.inventory.meta.ItemMeta; @@ -1479,7 +1512,7 @@ index 0af73cc04edb93b9772136d4d808f657ea40e733..c733206b769d7a55076d863757fcac1a /** * Represents a stack of items. -@@ -1005,4 +1017,626 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1005,4 +1017,635 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return type.isAir() || amount <= 0; } // Paper end @@ -2104,6 +2137,15 @@ index 0af73cc04edb93b9772136d4d808f657ea40e733..c733206b769d7a55076d863757fcac1a + } + return random.nextInt(unbreaking + 1) > 0; + } ++ ++ /** ++ * Returns the lines of text shown when hovering over the item ++ * @param advanced Whether advanced tooltips are shown ++ * @return the list of Components ++ */ ++ public @NotNull List getHoverLines(boolean advanced) { ++ return Bukkit.getItemFactory().getHoverLines(this, advanced); ++ } + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java @@ -4081,3 +4123,18 @@ index 12946bd55fcf7c40d39081779a7fa30049ee6165..9c2d605c50cbf9aefa56ec209df9f6ce + public void stopTiming() { /*handler.stopTiming();*/ } // Purpur } +diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java +index 88f1ca89fa640a686231b8eec87e70419b2d73ef..d6b91c49a267c89d7df2ddee7ccfe64675d117be 100644 +--- a/src/test/java/org/bukkit/AnnotationTest.java ++++ b/src/test/java/org/bukkit/AnnotationTest.java +@@ -47,6 +47,10 @@ public class AnnotationTest { + "org/bukkit/plugin/java/PluginClassLoader", + // Generic functional interface + "org/bukkit/util/Consumer", ++ // Purpur start ++ "gg/pufferfish/pufferfish/sentry/SentryContext", ++ "gg/pufferfish/pufferfish/sentry/SentryContext$State", ++ // Purpur end + // Paper start + "io/papermc/paper/util/TransformingRandomAccessList", + "io/papermc/paper/util/TransformingRandomAccessList$TransformedListIterator", diff --git a/patches/api/0003-Plazma-Configurations.patch b/patches/api/0003-Plazma-Configurations.patch index f37ec1827..87f6199a5 100644 --- a/patches/api/0003-Plazma-Configurations.patch +++ b/patches/api/0003-Plazma-Configurations.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Plazma Configurations diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index aaef58468a3c31f35e5067ed4263e9dd3fbddddd..0852f1a18106a81a60726756aae1d9c2ba30b111 100644 +index dd99f53e3d559685a4b3a454a9e607c310fc6aff..3a3713573ba37530449f9254c0a7205530c9737a 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2121,6 +2121,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2202,6 +2202,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } - // Paper end + // Purpur end + // Plazma start + @NotNull -+ public org.bukkit.configuration.file.YamlConfiguration getPlazmaConfiguration() { ++ public org.bukkit.configuration.file.YamlConfiguration getPlazmaConfig() { + throw new UnsupportedOperationException("Not supported yet."); + } + // Plazma end + - // Purpur start - @NotNull - public org.bukkit.configuration.file.YamlConfiguration getPurpurConfig() { + /** + * Sends the component to the player + * diff --git a/patches/api/0005-Optimize-spigot-event-bus.patch b/patches/api/0004-Optimize-spigot-event-bus.patch similarity index 100% rename from patches/api/0005-Optimize-spigot-event-bus.patch rename to patches/api/0004-Optimize-spigot-event-bus.patch diff --git a/patches/api/0004-Publish-Packages.patch b/patches/api/0004-Publish-Packages.patch deleted file mode 100644 index 0cbaa8269..000000000 --- a/patches/api/0004-Publish-Packages.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: IPECTER -Date: Mon, 19 Jun 2023 18:19:50 +0900 -Subject: [PATCH] Publish-Packages - - -diff --git a/build.gradle.kts b/build.gradle.kts -index 6c0df825238ca037abeb2ba619983b6f554180ea..54da0cab8681daac2dd9fbf0eb94de471819d4c8 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -171,3 +171,22 @@ tasks.check { - dependsOn(scanJar) - } - // Paper end -+// Plazma start -+publishing { -+ repositories { -+ maven { -+ name = "githubPackage" -+ url = uri("https://maven.pkg.github.com/PlazmaMC/Plazma") -+ -+ credentials.username = System.getenv("GITHUB_USERNAME") -+ credentials.password = System.getenv("GITHUB_TOKEN") -+ } -+ -+ publications { -+ register("gpr") { -+ from(components["java"]) -+ } -+ } -+ } -+} -+// Plazma end -\ No newline at end of file diff --git a/patches/api/0006-Implement-No-Chat-Reports.patch b/patches/api/0005-Implement-No-Chat-Reports.patch similarity index 100% rename from patches/api/0006-Implement-No-Chat-Reports.patch rename to patches/api/0005-Implement-No-Chat-Reports.patch diff --git a/patches/server/0001-Pufferfish-Server-Changes.patch b/patches/server/0001-Pufferfish-Server-Changes.patch index 1465866a3..ed2b98053 100644 --- a/patches/server/0001-Pufferfish-Server-Changes.patch +++ b/patches/server/0001-Pufferfish-Server-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Kevin Raneri -Date: Sat, 30 Sep 2023 09:45:47 +0000 +Date: Sat, 25 Nov 2023 11:51:41 +0000 Subject: [PATCH] Pufferfish Server Changes Original: Kevin Raneri @@ -20,10 +20,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/build.gradle.kts b/build.gradle.kts -index 683159586641dd9aa42ae96fa51602469755723f..de0a05602389ebb005bb7fd3c8d78da045d55bbe 100644 +index 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f97416864115f75ed5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -13,8 +13,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { +@@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { val alsoShade: Configuration by configurations.creating dependencies { @@ -34,18 +34,17 @@ index 683159586641dd9aa42ae96fa51602469755723f..de0a05602389ebb005bb7fd3c8d78da0 + implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") + } -+ implementation("com.github.technove:Flare:34637f3f87") // flare + // Pufferfish end // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -52,6 +57,13 @@ dependencies { +@@ -51,6 +55,13 @@ dependencies { runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") + // Pufferfish start + implementation("org.yaml:snakeyaml:1.32") -+ implementation ("me.carleslc.Simple-YAML:Simple-Yaml:1.8.4") { ++ implementation ("com.github.carleslc.Simple-YAML:Simple-Yaml:1.8.4") { + exclude(group="org.yaml", module="snakeyaml") + } + // Pufferfish end @@ -53,7 +52,22 @@ index 683159586641dd9aa42ae96fa51602469755723f..de0a05602389ebb005bb7fd3c8d78da0 testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("org.hamcrest:hamcrest:2.2") -@@ -72,7 +84,7 @@ tasks.jar { +@@ -58,6 +69,14 @@ dependencies { + } + + val craftbukkitPackageVersion = "1_20_R2" // Paper ++ ++// Pufferfish Start ++tasks.withType { ++ val compilerArgs = options.compilerArgs ++ compilerArgs.add("--add-modules=jdk.incubator.vector") ++} ++// Pufferfish End ++ + tasks.jar { + archiveClassifier.set("dev") + +@@ -70,7 +89,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -62,6 +76,15 @@ index 683159586641dd9aa42ae96fa51602469755723f..de0a05602389ebb005bb7fd3c8d78da0 "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, +@@ -210,7 +229,5 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> + } + tasks.registerRunTask("runDev") { + description = "Spin up a non-relocated Mojang-mapped test server" +- classpath(tasks.filterProjectDir.flatMap { it.outputJar }) +- classpath(runtimeClasspathForRunDev) +- jvmArgs("-DPaper.isRunDev=true") ++ classpath(sourceSets.main.map { it.runtimeClasspath }) + } diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java index a2f71a6d1a9e98133dff6cd0f625da9435a8af14..ff940e43ca35094bbcae6c7d471d3c4aeb7c1727 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java @@ -281,6 +304,126 @@ index 0000000000000000000000000000000000000000..aa8467b9dda1f7707e41f50ac7b3e9d7 + this.entries[toRemovePos] = new FluidDirectionEntry(data, flag); + } +} +diff --git a/src/main/java/gg/airplane/structs/ItemListWithBitset.java b/src/main/java/gg/airplane/structs/ItemListWithBitset.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1b7a4ee47f4445d7f2ac91d3a73ae113edbdddb2 +--- /dev/null ++++ b/src/main/java/gg/airplane/structs/ItemListWithBitset.java +@@ -0,0 +1,114 @@ ++package gg.airplane.structs; ++ ++import net.minecraft.core.NonNullList; ++import net.minecraft.world.item.ItemStack; ++import org.apache.commons.lang.Validate; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.util.AbstractList; ++import java.util.Arrays; ++import java.util.List; ++ ++public class ItemListWithBitset extends AbstractList { ++ public static ItemListWithBitset fromList(List list) { ++ if (list instanceof ItemListWithBitset ours) { ++ return ours; ++ } ++ return new ItemListWithBitset(list); ++ } ++ ++ private static ItemStack[] createArray(int size) { ++ ItemStack[] array = new ItemStack[size]; ++ Arrays.fill(array, ItemStack.EMPTY); ++ return array; ++ } ++ ++ private final ItemStack[] items; ++ ++ private long bitSet = 0; ++ private final long allBits; ++ ++ private static class OurNonNullList extends NonNullList { ++ protected OurNonNullList(List delegate) { ++ super(delegate, ItemStack.EMPTY); ++ } ++ } ++ ++ public final NonNullList nonNullList = new OurNonNullList(this); ++ ++ private ItemListWithBitset(List list) { ++ this(list.size()); ++ ++ for (int i = 0; i < list.size(); i++) { ++ this.set(i, list.get(i)); ++ } ++ } ++ ++ public ItemListWithBitset(int size) { ++ Validate.isTrue(size < Long.BYTES * 8, "size is too large"); ++ ++ this.items = createArray(size); ++ this.allBits = ((1L << size) - 1); ++ } ++ ++ public boolean isCompletelyEmpty() { ++ return this.bitSet == 0; ++ } ++ ++ public boolean hasFullStacks() { ++ return (this.bitSet & this.allBits) == allBits; ++ } ++ ++ @Override ++ public ItemStack set(int index, @NotNull ItemStack itemStack) { ++ ItemStack existing = this.items[index]; ++ ++ this.items[index] = itemStack; ++ ++ if (itemStack == ItemStack.EMPTY) { ++ this.bitSet &= ~(1L << index); ++ } else { ++ this.bitSet |= 1L << index; ++ } ++ ++ return existing; ++ } ++ ++ @NotNull ++ @Override ++ public ItemStack get(int var0) { ++ return this.items[var0]; ++ } ++ ++ @Override ++ public int size() { ++ return this.items.length; ++ } ++ ++ @Override ++ public void clear() { ++ Arrays.fill(this.items, ItemStack.EMPTY); ++ } ++ ++ // these are unsupported for block inventories which have a static size ++ @Override ++ public void add(int var0, ItemStack var1) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public ItemStack remove(int var0) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public String toString() { ++ return "ItemListWithBitset{" + ++ "items=" + Arrays.toString(items) + ++ ", bitSet=" + Long.toString(bitSet, 2) + ++ ", allBits=" + Long.toString(allBits, 2) + ++ ", size=" + this.items.length + ++ '}'; ++ } ++} diff --git a/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java b/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java new file mode 100644 index 0000000000000000000000000000000000000000..a7f297ebb569f7c1f205e967ca485be70013a714 @@ -482,10 +625,10 @@ index 0000000000000000000000000000000000000000..020368da69b9a492155f6de6297f7473 +} diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..7b091c1258c3f33933ec30a15d963e9d5f069ba7 +index 0000000000000000000000000000000000000000..cc66657cb4f978aa2df3ca1be6c683759952cc7a --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -@@ -0,0 +1,328 @@ +@@ -0,0 +1,294 @@ +package gg.pufferfish.pufferfish; + +import gg.pufferfish.pufferfish.simd.SIMDDetection; @@ -503,7 +646,6 @@ index 0000000000000000000000000000000000000000..7b091c1258c3f33933ec30a15d963e9d +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.List; -+import gg.pufferfish.pufferfish.flare.FlareCommand; +import net.minecraft.server.MinecraftServer; +import org.apache.logging.log4j.Level; +import org.bukkit.configuration.ConfigurationSection; @@ -512,13 +654,6 @@ index 0000000000000000000000000000000000000000..7b091c1258c3f33933ec30a15d963e9d +import org.simpleyaml.configuration.comments.CommentType; +import org.simpleyaml.configuration.file.YamlFile; +import org.simpleyaml.exceptions.InvalidConfigurationException; -+import org.bukkit.command.SimpleCommandMap; -+ -+import java.lang.reflect.Method; -+import java.lang.reflect.Modifier; -+import java.util.List; -+import java.net.URI; -+import java.util.Collections; + +public class PufferfishConfig { + @@ -778,38 +913,12 @@ index 0000000000000000000000000000000000000000..7b091c1258c3f33933ec30a15d963e9d + "the ender dragon whenever a player places an end crystal."); + } + -+ public static URI profileWebUrl; -+ private static void profilerOptions() { -+ profileWebUrl = URI.create(getString("flare.url", "https://flare.airplane.gg", "Sets the server to use for profiles.")); -+ -+ setComment("flare", "Configures Flare, the built-in profiler"); -+ } -+ -+ -+ public static String accessToken; -+ private static void airplaneWebServices() { -+ accessToken = getString("web-services.token", ""); -+ // todo lookup token (off-thread) and let users know if their token is valid -+ if (accessToken.length() > 0) { -+ gg.pufferfish.pufferfish.flare.FlareSetup.init(); // Pufferfish -+ SimpleCommandMap commandMap = MinecraftServer.getServer().server.getCommandMap(); -+ if (commandMap.getCommand("flare") == null) { -+ commandMap.register("flare", "Pufferfish", new FlareCommand()); -+ } -+ } -+ -+ setComment("web-services", "Options for connecting to Pufferfish/Airplane's online utilities"); -+ -+ } -+ + + public static boolean disableMethodProfiler; + public static boolean disableOutOfOrderChat; -+ public static boolean suppressNullIdDisconnections; + private static void miscSettings() { + disableMethodProfiler = getBoolean("misc.disable-method-profiler", true); + disableOutOfOrderChat = getBoolean("misc.disable-out-of-order-chat", false); -+ suppressNullIdDisconnections = getBoolean("misc.suppress-null-id-disconnections", false); + setComment("misc", "Settings for things that don't belong elsewhere"); + } + @@ -931,747 +1040,54 @@ index 0000000000000000000000000000000000000000..893d8c0946ef71a0561221dd76bffff0 + } catch (IOException | InterruptedException e) { + LOGGER.log(Level.WARNING, "Failed to look up version from Jenkins", e); + return text("Failed to retrieve version from server.", RED); -+ } -+ } -+ -+ // Based off code contributed by Techcable in Paper/GH-65 -+ private @NotNull Component fetchGithubVersion(final @NotNull String hash) { -+ final URI uri = URI.create(String.format(GITHUB_FORMAT, hash)); -+ final HttpRequest request = HttpRequest.newBuilder(uri).build(); -+ try { -+ final HttpResponse response = client.send(request, JSON_OBJECT_BODY_HANDLER); -+ if (response.statusCode() != 200) { -+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); -+ } -+ -+ final JsonObject obj = response.body(); -+ final int versionDiff = obj.get("behind_by").getAsInt(); -+ -+ return this.getResponseMessage(versionDiff); -+ } catch (IOException | InterruptedException e) { -+ LOGGER.log(Level.WARNING, "Failed to look up version from GitHub", e); -+ return text("Failed to retrieve version from server.", RED); -+ } -+ } -+ -+ private @NotNull Component getResponseMessage(final int versionDiff) { -+ return switch (Math.max(-1, Math.min(1, versionDiff))) { -+ case -1 -> text("You are running an unsupported version of Pufferfish.", RED); -+ case 0 -> text("You are on the latest version!", GREEN); -+ default -> text("You are running " + versionDiff + " version" + (versionDiff == 1 ? "" : "s") + " beyond. " + -+ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", -+ RED); -+ }; -+ } -+ -+ private @Nullable Component getHistory() { -+ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData(); -+ if (data == null) { -+ return null; -+ } -+ -+ final String oldVersion = data.getOldVersion(); -+ if (oldVersion == null) { -+ return null; -+ } -+ -+ return Component.text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/gg/pufferfish/pufferfish/compat/ServerConfigurations.java b/src/main/java/gg/pufferfish/pufferfish/compat/ServerConfigurations.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4ad189d52b27560424ddb311d0817a334637dc95 ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/compat/ServerConfigurations.java -@@ -0,0 +1,78 @@ -+package gg.pufferfish.pufferfish.compat; -+ -+import co.aikar.timings.TimingsManager; -+import com.google.common.io.Files; -+import org.bukkit.configuration.InvalidConfigurationException; -+import org.bukkit.configuration.file.YamlConfiguration; -+ -+import java.io.ByteArrayOutputStream; -+import java.io.File; -+import java.io.FileInputStream; -+import java.io.IOException; -+import java.nio.charset.StandardCharsets; -+import java.util.Arrays; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; -+import java.util.Properties; -+import java.util.stream.Collectors; -+ -+public class ServerConfigurations { -+ -+ public static final String[] configurationFiles = new String[]{ -+ "server.properties", -+ "bukkit.yml", -+ "spigot.yml", -+ // "paper.yml", // TODO: Figure out what to do with this. -+ "pufferfish.yml" -+ }; -+ -+ public static Map getCleanCopies() throws IOException { -+ Map files = new HashMap<>(configurationFiles.length); -+ for (String file : configurationFiles) { -+ files.put(file, getCleanCopy(file)); -+ } -+ return files; -+ } -+ -+ public static String getCleanCopy(String configName) throws IOException { -+ File file = new File(configName); -+ List hiddenConfigs = TimingsManager.hiddenConfigs; -+ -+ switch (Files.getFileExtension(configName)) { -+ case "properties": { -+ Properties properties = new Properties(); -+ try (FileInputStream inputStream = new FileInputStream(file)) { -+ properties.load(inputStream); -+ } -+ for (String hiddenConfig : hiddenConfigs) { -+ properties.remove(hiddenConfig); -+ } -+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); -+ properties.store(outputStream, ""); -+ return Arrays.stream(outputStream.toString() -+ .split("\n")) -+ .filter(line -> !line.startsWith("#")) -+ .collect(Collectors.joining("\n")); -+ } -+ case "yml": { -+ YamlConfiguration configuration = new YamlConfiguration(); -+ try { -+ configuration.load(file); -+ } catch (InvalidConfigurationException e) { -+ throw new IOException(e); -+ } -+ configuration.options().header(null); -+ for (String key : configuration.getKeys(true)) { -+ if (hiddenConfigs.contains(key)) { -+ configuration.set(key, null); -+ } -+ } -+ return configuration.saveToString(); -+ } -+ default: -+ throw new IllegalArgumentException("Bad file type " + configName); -+ } -+ } -+ -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/CustomCategories.java b/src/main/java/gg/pufferfish/pufferfish/flare/CustomCategories.java -new file mode 100644 -index 0000000000000000000000000000000000000000..401b42e29bccb5251684062f10b2e0f8b091bc95 ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/CustomCategories.java -@@ -0,0 +1,8 @@ -+package gg.pufferfish.pufferfish.flare; -+ -+import co.technove.flare.live.category.GraphCategory; -+ -+public class CustomCategories { -+ public static final GraphCategory MC_PERF = new GraphCategory("MC Performance"); -+ public static final GraphCategory ENTITIES_AND_CHUNKS = new GraphCategory("Entities & Chunks"); -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/FlareCommand.java b/src/main/java/gg/pufferfish/pufferfish/flare/FlareCommand.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3785d1512eb650f91d58903672c059e7449598fc ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/FlareCommand.java -@@ -0,0 +1,136 @@ -+package gg.pufferfish.pufferfish.flare; -+ -+import co.technove.flare.exceptions.UserReportableException; -+import co.technove.flare.internal.profiling.ProfileType; -+import gg.pufferfish.pufferfish.PufferfishConfig; -+import net.kyori.adventure.text.Component; -+import net.kyori.adventure.text.event.ClickEvent; -+import net.kyori.adventure.text.format.NamedTextColor; -+import net.kyori.adventure.text.format.TextColor; -+import net.kyori.adventure.text.format.TextDecoration; -+import net.minecraft.server.MinecraftServer; -+import org.apache.logging.log4j.Level; -+import org.bukkit.Bukkit; -+import org.bukkit.command.Command; -+import org.bukkit.command.CommandSender; -+import org.bukkit.command.ConsoleCommandSender; -+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; -+import org.bukkit.util.StringUtil; -+import org.jetbrains.annotations.NotNull; -+ -+import java.time.Duration; -+import java.util.ArrayList; -+import java.util.Collections; -+import java.util.List; -+ -+public class FlareCommand extends Command { -+ -+ private static final String BASE_URL = "https://blog.airplane.gg/flare-tutorial/#setting-the-access-token"; -+ private static final TextColor HEX = TextColor.fromHexString("#e3eaea"); -+ private static final Component PREFIX = Component.text() -+ .append(Component.text("Flare ✈") -+ .color(TextColor.fromHexString("#6a7eda")) -+ .decoration(TextDecoration.BOLD, true) -+ .append(Component.text(" ", HEX) -+ .decoration(TextDecoration.BOLD, false))) -+ .asComponent(); -+ -+ public FlareCommand() { -+ super("flare", "Profile your server with Flare", "/flare", Collections.singletonList("profile")); -+ this.setPermission("airplane.flare"); -+ } -+ -+ @Override -+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, String @NotNull [] args) { -+ if (!testPermission(sender)) return true; -+ if (PufferfishConfig.accessToken.length() == 0) { -+ Component clickable = Component.text(BASE_URL, HEX, TextDecoration.UNDERLINED).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, BASE_URL)); -+ -+ sender.sendMessage(PREFIX.append(Component.text("Flare currently requires an access token to use. To learn more, visit ").color(HEX).append(clickable))); -+ return true; -+ } -+ -+ if (!FlareSetup.isSupported()) { -+ sender.sendMessage(PREFIX.append( -+ Component.text("Profiling is not supported in this environment, check your startup logs for the error.", NamedTextColor.RED))); -+ return true; -+ } -+ if (ProfilingManager.isProfiling()) { -+ if (args.length == 1 && args[0].equalsIgnoreCase("status")) { -+ sender.sendMessage(PREFIX.append(Component.text("Current profile has been ran for " + ProfilingManager.getTimeRan().toString(), HEX))); -+ return true; -+ } -+ if (ProfilingManager.stop()) { -+ if (!(sender instanceof ConsoleCommandSender)) { -+ sender.sendMessage(PREFIX.append(Component.text("Profiling has been stopped.", HEX))); -+ } -+ } else { -+ sender.sendMessage(PREFIX.append(Component.text("Profiling has already been stopped.", HEX))); -+ } -+ } else { -+ ProfileType profileType = ProfileType.ITIMER; -+ if (args.length > 0) { -+ try { -+ profileType = ProfileType.valueOf(args[0].toUpperCase()); -+ } catch (Exception e) { -+ sender.sendMessage(PREFIX.append(Component -+ .text("Invalid profile type ", HEX) -+ .append(Component.text(args[0], HEX, TextDecoration.BOLD) -+ .append(Component.text("!", HEX))) -+ )); -+ } -+ } -+ ProfileType finalProfileType = profileType; -+ Bukkit.getScheduler().runTaskAsynchronously(new MinecraftInternalPlugin(), () -> { -+ try { -+ if (ProfilingManager.start(finalProfileType)) { -+ if (!(sender instanceof ConsoleCommandSender)) { -+ sender.sendMessage(PREFIX.append(Component -+ .text("Flare has been started: " + ProfilingManager.getProfilingUri(), HEX) -+ .clickEvent(ClickEvent.openUrl(ProfilingManager.getProfilingUri())) -+ )); -+ sender.sendMessage(PREFIX.append(Component.text(" Run /" + commandLabel + " to stop the Flare.", HEX))); -+ } -+ } else { -+ sender.sendMessage(PREFIX.append(Component -+ .text("Flare has already been started: " + ProfilingManager.getProfilingUri(), HEX) -+ .clickEvent(ClickEvent.openUrl(ProfilingManager.getProfilingUri())) -+ )); -+ } -+ } catch (UserReportableException e) { -+ sender.sendMessage(Component.text("Flare failed to start: " + e.getUserError(), NamedTextColor.RED)); -+ if (e.getCause() != null) { -+ MinecraftServer.LOGGER.warn("Flare failed to start", e); -+ } -+ } -+ }); -+ } -+ return true; -+ } -+ -+ @Override -+ public @NotNull List tabComplete(@NotNull CommandSender sender, @NotNull String alias, String @NotNull [] args) throws IllegalArgumentException { -+ List list = new ArrayList<>(); -+ if (ProfilingManager.isProfiling()) { -+ if (args.length == 1) { -+ String lastWord = args[0]; -+ if (StringUtil.startsWithIgnoreCase("status", lastWord)) { -+ list.add("status"); -+ } -+ if (StringUtil.startsWithIgnoreCase("stop", lastWord)) { -+ list.add("stop"); -+ } -+ } -+ } else { -+ if (args.length <= 1) { -+ String lastWord = args.length == 0 ? "" : args[0]; -+ for (ProfileType value : ProfileType.values()) { -+ if (StringUtil.startsWithIgnoreCase(value.getInternalName(), lastWord)) { -+ list.add(value.name().toLowerCase()); -+ } -+ } -+ } -+ } -+ return list; -+ } -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/FlareSetup.java b/src/main/java/gg/pufferfish/pufferfish/flare/FlareSetup.java -new file mode 100644 -index 0000000000000000000000000000000000000000..cd22e4dcc8b7b57b10a95ef084637249a98e524f ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/FlareSetup.java -@@ -0,0 +1,33 @@ -+package gg.pufferfish.pufferfish.flare; -+ -+import co.technove.flare.FlareInitializer; -+import co.technove.flare.internal.profiling.InitializationException; -+import net.minecraft.server.MinecraftServer; -+import org.apache.logging.log4j.Level; -+ -+public class FlareSetup { -+ -+ private static boolean initialized = false; -+ private static boolean supported = false; -+ -+ public static void init() { -+ if (initialized) { -+ return; -+ } -+ -+ initialized = true; -+ try { -+ for (String warning : FlareInitializer.initialize()) { -+ MinecraftServer.LOGGER.warn("Flare warning: " + warning); -+ } -+ supported = true; -+ } catch (InitializationException e) { -+ MinecraftServer.LOGGER.warn("Failed to enable Flare:", e); -+ } -+ } -+ -+ public static boolean isSupported() { -+ return supported; -+ } -+ -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/PluginLookup.java b/src/main/java/gg/pufferfish/pufferfish/flare/PluginLookup.java -new file mode 100644 -index 0000000000000000000000000000000000000000..74aab5eb4b54ffbaf19b8976ffb8ca4a64584006 ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/PluginLookup.java -@@ -0,0 +1,44 @@ -+package gg.pufferfish.pufferfish.flare; -+ -+import com.google.common.cache.Cache; -+import com.google.common.cache.CacheBuilder; -+import org.bukkit.Bukkit; -+import org.bukkit.plugin.Plugin; -+import org.bukkit.plugin.java.PluginClassLoader; -+ -+import java.util.Optional; -+import java.util.concurrent.TimeUnit; -+ -+public class PluginLookup { -+ private static final Cache pluginNameCache = CacheBuilder.newBuilder() -+ .expireAfterAccess(1, TimeUnit.MINUTES) -+ .maximumSize(1024) -+ .build(); -+ -+ public static Optional getPluginForClass(String name) { -+ if (name.startsWith("net.minecraft") || name.startsWith("java.") || name.startsWith("com.mojang") || -+ name.startsWith("com.google") || name.startsWith("it.unimi") || name.startsWith("sun")) { -+ return Optional.empty(); -+ } -+ -+ String existing = pluginNameCache.getIfPresent(name); -+ if (existing != null) { -+ return Optional.ofNullable(existing.isEmpty() ? null : existing); -+ } -+ -+ String newValue = ""; -+ -+ for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { -+ ClassLoader classLoader = plugin.getClass().getClassLoader(); -+ if (classLoader instanceof PluginClassLoader) { -+ if (((PluginClassLoader) classLoader)._airplane_hasClass(name)) { -+ newValue = plugin.getName(); -+ break; -+ } -+ } -+ } -+ -+ pluginNameCache.put(name, newValue); -+ return Optional.ofNullable(newValue.isEmpty() ? null : newValue); -+ } -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/ProfilingManager.java b/src/main/java/gg/pufferfish/pufferfish/flare/ProfilingManager.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e3f76eb11a261c3347f0cd89b5da309bc2dc82f9 ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/ProfilingManager.java -@@ -0,0 +1,151 @@ -+package gg.pufferfish.pufferfish.flare; -+ -+import co.technove.flare.Flare; -+import co.technove.flare.FlareAuth; -+import co.technove.flare.FlareBuilder; -+import co.technove.flare.exceptions.UserReportableException; -+import co.technove.flare.internal.profiling.ProfileType; -+import gg.pufferfish.pufferfish.PufferfishConfig; -+import gg.pufferfish.pufferfish.PufferfishLogger; -+import gg.pufferfish.pufferfish.compat.ServerConfigurations; -+import gg.pufferfish.pufferfish.flare.collectors.GCEventCollector; -+import gg.pufferfish.pufferfish.flare.collectors.StatCollector; -+import gg.pufferfish.pufferfish.flare.collectors.TPSCollector; -+import gg.pufferfish.pufferfish.flare.collectors.WorldCountCollector; -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; -+import org.bukkit.scheduler.BukkitTask; -+import oshi.SystemInfo; -+import oshi.hardware.CentralProcessor; -+import oshi.hardware.GlobalMemory; -+import oshi.hardware.HardwareAbstractionLayer; -+import oshi.hardware.VirtualMemory; -+import oshi.software.os.OperatingSystem; -+ -+import java.io.IOException; -+import java.net.URI; -+import java.time.Duration; -+import java.util.Objects; -+import java.util.logging.Level; -+ -+public class ProfilingManager { -+ -+ private static Flare currentFlare; -+ private static BukkitTask currentTask = null; -+ -+ public static synchronized boolean isProfiling() { -+ return currentFlare != null && currentFlare.isRunning(); -+ } -+ -+ public static synchronized String getProfilingUri() { -+ return Objects.requireNonNull(currentFlare).getURI().map(URI::toString).orElse("Flare is not running"); -+ } -+ -+ public static Duration getTimeRan() { -+ Flare flare = currentFlare; // copy reference so no need to sync -+ if (flare == null) { -+ return Duration.ofMillis(0); -+ } -+ return flare.getCurrentDuration(); -+ } -+ -+ public static synchronized boolean start(ProfileType profileType) throws UserReportableException { -+ if (currentFlare != null && !currentFlare.isRunning()) { -+ currentFlare = null; // errored out -+ } -+ if (isProfiling()) { -+ return false; -+ } -+ if (Bukkit.isPrimaryThread()) { -+ throw new UserReportableException("Profiles should be started off-thread"); -+ } -+ -+ try { -+ OperatingSystem os = new SystemInfo().getOperatingSystem(); -+ -+ SystemInfo systemInfo = new SystemInfo(); -+ HardwareAbstractionLayer hardware = systemInfo.getHardware(); -+ -+ CentralProcessor processor = hardware.getProcessor(); -+ CentralProcessor.ProcessorIdentifier processorIdentifier = processor.getProcessorIdentifier(); -+ -+ GlobalMemory memory = hardware.getMemory(); -+ VirtualMemory virtualMemory = memory.getVirtualMemory(); -+ -+ FlareBuilder builder = new FlareBuilder() -+ .withProfileType(profileType) -+ .withMemoryProfiling(true) -+ .withAuth(FlareAuth.fromTokenAndUrl(PufferfishConfig.accessToken, PufferfishConfig.profileWebUrl)) -+ -+ .withFiles(ServerConfigurations.getCleanCopies()) -+ .withVersion("Primary Version", Bukkit.getVersion()) -+ .withVersion("Bukkit Version", Bukkit.getBukkitVersion()) -+ .withVersion("Minecraft Version", Bukkit.getMinecraftVersion()) -+ -+ .withGraphCategories(CustomCategories.ENTITIES_AND_CHUNKS, CustomCategories.MC_PERF) -+ .withCollectors(new TPSCollector(), new WorldCountCollector(), new GCEventCollector(), new StatCollector()) -+ .withClassIdentifier(PluginLookup::getPluginForClass) -+ -+ .withHardware(new FlareBuilder.HardwareBuilder() -+ .setCoreCount(processor.getPhysicalProcessorCount()) -+ .setThreadCount(processor.getLogicalProcessorCount()) -+ .setCpuModel(processorIdentifier.getName()) -+ .setCpuFrequency(processor.getMaxFreq()) -+ -+ .setTotalMemory(memory.getTotal()) -+ .setTotalSwap(virtualMemory.getSwapTotal()) -+ .setTotalVirtual(virtualMemory.getVirtualMax()) -+ ) -+ -+ .withOperatingSystem(new FlareBuilder.OperatingSystemBuilder() -+ .setManufacturer(os.getManufacturer()) -+ .setFamily(os.getFamily()) -+ .setVersion(os.getVersionInfo().toString()) -+ .setBitness(os.getBitness()) -+ ); -+ -+ currentFlare = builder.build(); -+ } catch (IOException e) { -+ PufferfishLogger.LOGGER.log(Level.WARNING, "Failed to read configuration files:", e); -+ throw new UserReportableException("Failed to load configuration files, check logs for further details."); -+ } -+ -+ try { -+ currentFlare.start(); -+ } catch (IllegalStateException e) { -+ PufferfishLogger.LOGGER.log(Level.WARNING, "Error starting Flare:", e); -+ throw new UserReportableException("Failed to start Flare, check logs for further details."); -+ } -+ -+ currentTask = Bukkit.getScheduler().runTaskLater(new MinecraftInternalPlugin(), ProfilingManager::stop, 20 * 60 * 15); -+ PufferfishLogger.LOGGER.log(Level.INFO, "Flare has been started: " + getProfilingUri()); -+ return true; -+ } -+ -+ public static synchronized boolean stop() { -+ if (!isProfiling()) { -+ return false; -+ } -+ if (!currentFlare.isRunning()) { -+ currentFlare = null; -+ return true; -+ } -+ PufferfishLogger.LOGGER.log(Level.INFO, "Flare has been stopped: " + getProfilingUri()); -+ try { -+ currentFlare.stop(); -+ } catch (IllegalStateException e) { -+ PufferfishLogger.LOGGER.log(Level.WARNING, "Error occurred stopping Flare", e); -+ } -+ currentFlare = null; -+ -+ try { -+ currentTask.cancel(); -+ } catch (Throwable t) { -+ PufferfishLogger.LOGGER.log(Level.WARNING, "Error occurred stopping Flare", t); -+ } -+ -+ currentTask = null; -+ return true; -+ } -+ -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/collectors/GCEventCollector.java b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/GCEventCollector.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d426575c669020f369960107da1e2de2f11f082f ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/GCEventCollector.java -@@ -0,0 +1,66 @@ -+package gg.pufferfish.pufferfish.flare.collectors; -+ -+import co.technove.flare.Flare; -+import co.technove.flare.internal.FlareInternal; -+import co.technove.flare.live.CollectorData; -+import co.technove.flare.live.EventCollector; -+import co.technove.flare.live.LiveEvent; -+import co.technove.flare.live.category.GraphCategory; -+import co.technove.flare.live.formatter.DataFormatter; -+import com.google.common.collect.ImmutableMap; -+import com.sun.management.GarbageCollectionNotificationInfo; -+ -+import javax.management.ListenerNotFoundException; -+import javax.management.Notification; -+import javax.management.NotificationEmitter; -+import javax.management.NotificationListener; -+import javax.management.openmbean.CompositeData; -+import java.lang.management.GarbageCollectorMXBean; -+import java.lang.management.ManagementFactory; -+ -+public class GCEventCollector extends EventCollector implements NotificationListener { -+ -+ private static final CollectorData MINOR_GC = new CollectorData("builtin:gc:minor", "Minor GC", "A small pause in the program to allow Garbage Collection to run.", DataFormatter.MILLISECONDS, GraphCategory.SYSTEM); -+ private static final CollectorData MAJOR_GC = new CollectorData("builtin:gc:major", "Major GC", "A large pause in the program to allow Garbage Collection to run.", DataFormatter.MILLISECONDS, GraphCategory.SYSTEM); -+ private static final CollectorData UNKNOWN_GC = new CollectorData("builtin:gc:generic", "Major GC", "A run of the Garbage Collection.", DataFormatter.MILLISECONDS, GraphCategory.SYSTEM); -+ -+ public GCEventCollector() { -+ super(MINOR_GC, MAJOR_GC, UNKNOWN_GC); -+ } -+ -+ private static CollectorData fromString(String string) { -+ if (string.endsWith("minor GC")) { -+ return MINOR_GC; -+ } else if (string.endsWith("major GC")) { -+ return MAJOR_GC; -+ } -+ return UNKNOWN_GC; -+ } -+ -+ @Override -+ public void start(Flare flare) { -+ for (GarbageCollectorMXBean garbageCollectorBean : ManagementFactory.getGarbageCollectorMXBeans()) { -+ NotificationEmitter notificationEmitter = (NotificationEmitter) garbageCollectorBean; -+ notificationEmitter.addNotificationListener(this, null, null); -+ } -+ } -+ -+ @Override -+ public void stop(Flare flare) { -+ for (GarbageCollectorMXBean garbageCollectorBean : ManagementFactory.getGarbageCollectorMXBeans()) { -+ NotificationEmitter notificationEmitter = (NotificationEmitter) garbageCollectorBean; -+ try { -+ notificationEmitter.removeNotificationListener(this); -+ } catch (ListenerNotFoundException e) { -+ } -+ } -+ } -+ -+ @Override -+ public void handleNotification(Notification notification, Object o) { -+ if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { -+ GarbageCollectionNotificationInfo gcInfo = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); -+ reportEvent(new LiveEvent(fromString(gcInfo.getGcAction()), System.currentTimeMillis(), (int) gcInfo.getGcInfo().getDuration(), ImmutableMap.of())); -+ } -+ } -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/collectors/StatCollector.java b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/StatCollector.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a22c6dbae53667e4c72464fa27153aee30c7946e ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/StatCollector.java -@@ -0,0 +1,41 @@ -+package gg.pufferfish.pufferfish.flare.collectors; -+ -+import co.technove.flare.live.CollectorData; -+import co.technove.flare.live.LiveCollector; -+import co.technove.flare.live.category.GraphCategory; -+import co.technove.flare.live.formatter.DataFormatter; -+import com.sun.management.OperatingSystemMXBean; -+import oshi.SystemInfo; -+import oshi.hardware.CentralProcessor; -+ -+import java.lang.management.ManagementFactory; -+import java.time.Duration; -+ -+public class StatCollector extends LiveCollector { -+ -+ private static final CollectorData CPU = new CollectorData("builtin:stat:cpu", "CPU Load", "The total amount of CPU usage across all cores.", DataFormatter.PERCENT, GraphCategory.SYSTEM); -+ private static final CollectorData CPU_PROCESS = new CollectorData("builtin:stat:cpu_process", "Process CPU", "The amount of CPU being used by this process.", DataFormatter.PERCENT, GraphCategory.SYSTEM); -+ private static final CollectorData MEMORY = new CollectorData("builtin:stat:memory_used", "Memory", "The amount of memory being used currently.", DataFormatter.BYTES, GraphCategory.SYSTEM); -+ private static final CollectorData MEMORY_TOTAL = new CollectorData("builtin:stat:memory_total", "Memory Total", "The total amount of memory allocated.", DataFormatter.BYTES, GraphCategory.SYSTEM); -+ -+ private final OperatingSystemMXBean bean; -+ private final CentralProcessor processor; -+ -+ public StatCollector() { -+ super(CPU, CPU_PROCESS, MEMORY, MEMORY_TOTAL); -+ this.interval = Duration.ofSeconds(5); -+ -+ this.bean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); -+ this.processor = new SystemInfo().getHardware().getProcessor(); -+ } -+ -+ @Override -+ public void run() { -+ Runtime runtime = Runtime.getRuntime(); -+ -+ this.report(CPU, this.processor.getSystemLoadAverage(1)[0] / 100); // percentage -+ this.report(CPU_PROCESS, this.bean.getProcessCpuLoad()); -+ this.report(MEMORY, runtime.totalMemory() - runtime.freeMemory()); -+ this.report(MEMORY_TOTAL, runtime.totalMemory()); -+ } -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/collectors/TPSCollector.java b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/TPSCollector.java -new file mode 100644 -index 0000000000000000000000000000000000000000..40447d00aefb5ffedb8a2ee87155a04088f0649f ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/TPSCollector.java -@@ -0,0 +1,31 @@ -+package gg.pufferfish.pufferfish.flare.collectors; -+ -+import co.technove.flare.live.CollectorData; -+import co.technove.flare.live.LiveCollector; -+import co.technove.flare.live.formatter.SuffixFormatter; -+import gg.pufferfish.pufferfish.flare.CustomCategories; -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.Bukkit; -+ -+import java.time.Duration; -+import java.util.Arrays; -+ -+public class TPSCollector extends LiveCollector { -+ private static final CollectorData TPS = new CollectorData("airplane:tps", "TPS", "Ticks per second, or how fast the server updates. For a smooth server this should be a constant 20TPS.", SuffixFormatter.of("TPS"), CustomCategories.MC_PERF); -+ private static final CollectorData MSPT = new CollectorData("airplane:mspt", "MSPT", "Milliseconds per tick, which can show how well your server is performing. This value should always be under 50mspt.", SuffixFormatter.of("mspt"), CustomCategories.MC_PERF); -+ -+ public TPSCollector() { -+ super(TPS, MSPT); -+ -+ this.interval = Duration.ofSeconds(5); -+ } -+ -+ @Override -+ public void run() { -+ long[] times = MinecraftServer.getServer().tickTimes5s.getTimes(); -+ double mspt = ((double) Arrays.stream(times).sum() / (double) times.length) * 1.0E-6D; -+ -+ this.report(TPS, Math.min(20D, Math.round(Bukkit.getServer().getTPS()[0] * 100d) / 100d)); -+ this.report(MSPT, (double) Math.round(mspt * 100d) / 100d); -+ } -+} -diff --git a/src/main/java/gg/pufferfish/pufferfish/flare/collectors/WorldCountCollector.java b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/WorldCountCollector.java -new file mode 100644 -index 0000000000000000000000000000000000000000..029d840e28d67d26d3c0dd6785e25dbf15f9226c ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/flare/collectors/WorldCountCollector.java -@@ -0,0 +1,45 @@ -+package gg.pufferfish.pufferfish.flare.collectors; -+ -+import co.technove.flare.live.CollectorData; -+import co.technove.flare.live.LiveCollector; -+import co.technove.flare.live.formatter.SuffixFormatter; -+import gg.pufferfish.pufferfish.flare.CustomCategories; -+import org.bukkit.Bukkit; -+import org.bukkit.World; -+ -+import java.time.Duration; -+ -+public class WorldCountCollector extends LiveCollector { -+ -+ private static final CollectorData PLAYER_COUNT = new CollectorData("airplane:world:playercount", "Player Count", "The number of players currently on the server.", new SuffixFormatter(" Player", " Players"), CustomCategories.ENTITIES_AND_CHUNKS); -+ private static final CollectorData ENTITY_COUNT = new CollectorData("airplane:world:entitycount", "Entity Count", "The number of entities in all worlds", new SuffixFormatter(" Entity", " Entities"), CustomCategories.ENTITIES_AND_CHUNKS); -+ private static final CollectorData CHUNK_COUNT = new CollectorData("airplane:world:chunkcount", "Chunk Count", "The number of chunks currently loaded.", new SuffixFormatter(" Chunk", " Chunks"), CustomCategories.ENTITIES_AND_CHUNKS); -+ private static final CollectorData TILE_ENTITY_COUNT = new CollectorData("airplane:world:blockentitycount", "Block Entity Count", "The number of block entities currently loaded.", new SuffixFormatter(" Block Entity", " Block Entities"), CustomCategories.ENTITIES_AND_CHUNKS); -+ -+ public WorldCountCollector() { -+ super(PLAYER_COUNT, ENTITY_COUNT, CHUNK_COUNT, TILE_ENTITY_COUNT); -+ -+ this.interval = Duration.ofSeconds(5); -+ } -+ -+ @Override -+ public void run() { -+ if (true) return; // This doesn't work, and it's not worth fixing at the moment. -+ int entities = 0; -+ int chunkCount = 0; -+ int tileEntityCount = 0; -+ -+ if (!Bukkit.isStopping()) { -+ for (World world : Bukkit.getWorlds()) { -+ world.getEntityCount(); -+ chunkCount += world.getChunkCount(); -+ tileEntityCount += world.getTileEntityCount(); -+ } -+ } -+ -+ this.report(PLAYER_COUNT, Bukkit.getOnlinePlayers().size()); -+ this.report(ENTITY_COUNT, entities); -+ this.report(CHUNK_COUNT, chunkCount); -+ this.report(TILE_ENTITY_COUNT, tileEntityCount); -+ } ++ } ++ } ++ ++ // Based off code contributed by Techcable in Paper/GH-65 ++ private @NotNull Component fetchGithubVersion(final @NotNull String hash) { ++ final URI uri = URI.create(String.format(GITHUB_FORMAT, hash)); ++ final HttpRequest request = HttpRequest.newBuilder(uri).build(); ++ try { ++ final HttpResponse response = client.send(request, JSON_OBJECT_BODY_HANDLER); ++ if (response.statusCode() != 200) { ++ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); ++ } ++ ++ final JsonObject obj = response.body(); ++ final int versionDiff = obj.get("behind_by").getAsInt(); ++ ++ return this.getResponseMessage(versionDiff); ++ } catch (IOException | InterruptedException e) { ++ LOGGER.log(Level.WARNING, "Failed to look up version from GitHub", e); ++ return text("Failed to retrieve version from server.", RED); ++ } ++ } ++ ++ private @NotNull Component getResponseMessage(final int versionDiff) { ++ return switch (Math.max(-1, Math.min(1, versionDiff))) { ++ case -1 -> text("You are running an unsupported version of Pufferfish.", RED); ++ case 0 -> text("You are on the latest version!", GREEN); ++ default -> text("You are running " + versionDiff + " version" + (versionDiff == 1 ? "" : "s") + " beyond. " + ++ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", ++ RED); ++ }; ++ } ++ ++ private @Nullable Component getHistory() { ++ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData(); ++ if (data == null) { ++ return null; ++ } ++ ++ final String oldVersion = data.getOldVersion(); ++ if (oldVersion == null) { ++ return null; ++ } ++ ++ return Component.text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); ++ } +} +\ No newline at end of file diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java new file mode 100644 index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834733d0621 @@ -2047,51 +1463,8 @@ index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f549 + return backingMap.size(); + } +} -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 97a9ce438afc9094dca4a44cb25b37d5f88dcf43..c69892a5f31895b85e530beadd8864ac32470ba7 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -8,6 +8,7 @@ import net.kyori.adventure.text.Component; - import net.kyori.adventure.text.format.NamedTextColor; - import net.minecraft.network.protocol.Packet; - import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; -+import org.bukkit.Bukkit; // Pufferfish - import org.checkerframework.checker.nullness.qual.Nullable; - import org.spongepowered.configurate.objectmapping.ConfigSerializable; - import org.spongepowered.configurate.objectmapping.meta.Comment; -@@ -17,6 +18,7 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; - import java.util.List; - import java.util.Map; - import java.util.Objects; -+import java.util.logging.Level; // Pufferfish - - @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"}) - public class GlobalConfiguration extends ConfigurationPart { -@@ -91,6 +93,7 @@ public class GlobalConfiguration extends ConfigurationPart { - - public class Timings extends ConfigurationPart.Post { - public boolean enabled = true; -+ public boolean reallyEnabled = false; - public boolean verbose = true; - public String url = "https://timings.aikar.co/"; - public boolean serverNamePrivacy = false; -@@ -104,6 +107,14 @@ public class GlobalConfiguration extends ConfigurationPart { - - @Override - public void postProcess() { -+ // Pufferfish start -+ if (enabled && !reallyEnabled) { -+ Bukkit.getLogger().log(Level.WARNING, "[Pufferfish] To improve performance, timings have been disabled by default"); -+ Bukkit.getLogger().log(Level.WARNING, "[Pufferfish] You can still use timings by using /timings on, but they will not start on server startup unless you set timings.really-enabled to true in paper.yml"); -+ Bukkit.getLogger().log(Level.WARNING, "[Pufferfish] If you would like to disable this message, either set timings.really-enabled to true or timings.enabled to false."); -+ } -+ enabled = reallyEnabled; -+ // Pufferfish end - MinecraftTimings.processConfig(this); - } - } diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index d02546b18cb689724887b4e85e8d32a18828a4ad..91eaff58bb422ba188e6cfaa9c20b45bec211edd 100644 +index 8240bb085b619f257f8c0a25775e0b15068e440f..6d9668d993bb922ae9d2b76a4d766903cc3f98a4 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java @@ -213,7 +213,7 @@ public final class MCUtil { @@ -2103,31 +1476,20 @@ index d02546b18cb689724887b4e85e8d32a18828a4ad..91eaff58bb422ba188e6cfaa9c20b45b } public static long getCoordinateKey(final ChunkPos pair) { -diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index ec268189b19b6fa5c4521f96ce211a531db35ec5..27a238cc56702297c88fde0f379178222ccf6c5b 100644 ---- a/src/main/java/net/minecraft/server/Main.java -+++ b/src/main/java/net/minecraft/server/Main.java -@@ -166,6 +166,7 @@ public class Main { - - // Spigot Start - boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ); -+ eulaAgreed = eulaAgreed || Boolean.getBoolean("Paper.isRunDev"); - if ( eulaAgreed ) - { - System.err.println( "You have used the Spigot command line EULA agreement flag." ); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 97745f0bab8d82d397c6c2a5775aed92bca0a034..87cacb46fb2b07482d3d608019d65a74b3854800 100644 +index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -308,6 +308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1697,7 +1698,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop needsChangeBroadcasting = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); @@ -2179,7 +1540,7 @@ index 0c2617574e21037d94ac56ad08b490f9bca5c5af..7eaee0d0dcbb420abb5c49ba0a465d90 // Paper end - optimise chunk tick iteration public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { -@@ -1330,8 +1330,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1464,8 +1464,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return ChunkMap.this.level.getServer().getScaledTrackingDistance(initialDistance); } @@ -2208,7 +1569,7 @@ index 0c2617574e21037d94ac56ad08b490f9bca5c5af..7eaee0d0dcbb420abb5c49ba0a465d90 Iterator iterator = this.entity.getIndirectPassengers().iterator(); while (iterator.hasNext()) { -@@ -1343,6 +1363,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1477,6 +1497,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider i = j; } } @@ -2219,19 +1580,28 @@ index 0c2617574e21037d94ac56ad08b490f9bca5c5af..7eaee0d0dcbb420abb5c49ba0a465d90 return this.scaledRange(i); } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 17b6925b46f8386dcfc561483693de516465ec12..390e5a4e9cead6f217de7689a47b8c3b4b042990 100644 +index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..5d26364c0f4ed03bd9994077683c93b9883e5327 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -75,6 +75,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -75,6 +75,9 @@ public class ServerChunkCache extends ChunkSource { final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f); private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; ++ + public boolean firstRunSpawnCounts = true; // Pufferfish + public final java.util.concurrent.atomic.AtomicBoolean _pufferfish_spawnCountsReady = new java.util.concurrent.atomic.AtomicBoolean(false); // Pufferfish - optimize countmobs private static int getChunkCacheKey(int x, int z) { return x & 3 | ((z & 3) << 2); -@@ -530,28 +532,35 @@ public class ServerChunkCache extends ChunkSource { +@@ -521,6 +524,7 @@ public class ServerChunkCache extends ChunkSource { + ProfilerFiller gameprofilerfiller = this.level.getProfiler(); + + gameprofilerfiller.push("pollingChunks"); ++ this.level.resetIceAndSnowTick(); // Pufferfish - reset ice & snow tick random + int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); + boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit + +@@ -530,28 +534,35 @@ public class ServerChunkCache extends ChunkSource { // Paper start - per player mob spawning NaturalSpawner.SpawnState spawnercreature_d; // moved down if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled @@ -2268,7 +1638,7 @@ index 17b6925b46f8386dcfc561483693de516465ec12..390e5a4e9cead6f217de7689a47b8c3b + // Pufferfish end } else { - spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); -+ // Pufferfish start - this is only implemented for per-player mob spawning so this makes everything work if this setting is disabled. ++ // Pufferfish start + lastSpawnState = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); + _pufferfish_spawnCountsReady.set(true); + // Pufferfish end @@ -2281,7 +1651,7 @@ index 17b6925b46f8386dcfc561483693de516465ec12..390e5a4e9cead6f217de7689a47b8c3b gameprofilerfiller.popPush("filteringLoadedChunks"); // Paper - optimise chunk tick iteration // Paper - optimise chunk tick iteration -@@ -644,8 +653,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -644,8 +655,8 @@ public class ServerChunkCache extends ChunkSource { // Paper end - optimise chunk tick iteration if (tick && chunk1.chunkStatus.isOrAfter(net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING)) { // Paper - optimise chunk tick iteration chunk1.incrementInhabitedTime(j); @@ -2292,11 +1662,11 @@ index 17b6925b46f8386dcfc561483693de516465ec12..390e5a4e9cead6f217de7689a47b8c3b } if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration -@@ -691,6 +700,40 @@ public class ServerChunkCache extends ChunkSource { +@@ -691,6 +702,40 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.pop(); this.chunkMap.tick(); } -+ ++ + // Pufferfish start - optimize mob spawning + if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) { + for (ServerPlayer player : this.level.players) { @@ -2316,7 +1686,7 @@ index 17b6925b46f8386dcfc561483693de516465ec12..390e5a4e9cead6f217de7689a47b8c3b + firstRunSpawnCounts = false; + _pufferfish_spawnCountsReady.set(true); + } -+ if (chunkMap.playerMobSpawnMap != null && _pufferfish_spawnCountsReady.getAndSet(false)) { ++ if (_pufferfish_spawnCountsReady.getAndSet(false)) { + net.minecraft.server.MinecraftServer.getServer().mobSpawnExecutor.submit(() -> { + int mapped = distanceManager.getNaturalSpawnChunkCount(); + io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator objectiterator = @@ -2356,12 +1726,12 @@ index 35674f92a67f93382103c2766df4b678ba5c862f..d46e61640b241d32df05240dedd2c23f this.wasOnGround = this.entity.onGround(); this.teleportDelay = 0; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 868951dc21aff541765b1f58f08cdf3c47446d25..48402dc3008d1d1d513f0486c0a120719a9fd441 100644 +index c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b68f6d494f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -878,6 +878,7 @@ public class ServerLevel extends Level implements WorldGenLevel { org.spigotmc.ActivationRange.activateEntities(this); // Spigot - timings.entityTick.startTiming(); // Spigot + this.timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { + entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { @@ -2389,19 +1759,33 @@ index 868951dc21aff541765b1f58f08cdf3c47446d25..48402dc3008d1d1d513f0486c0a12071 gameprofilerfiller.pop(); } } -@@ -964,6 +978,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -962,9 +976,11 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); - private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); +- private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); ++ // private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(); // Pufferfish - moved to super // Paper end -+ public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish ++ private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Pufferfish ++ public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ChunkPos chunkcoordintpair = chunk.getPos(); + boolean flag = this.isRaining(); +@@ -975,7 +991,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + gameprofilerfiller.push("thunder"); + final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change + +- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder ++ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && /*this.random.nextInt(this.spigotConfig.thunderChance) == 0 &&*/ chunk.shouldDoLightning(this.random)) { // Spigot // Paper - disable thunder // Pufferfish - replace random with shouldDoLightning + blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper + + if (this.isRainingAt(blockposition)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8bd243a8d5a4be54f907af2b02e96ea833cee62f..501cb7450cd28ca487c1522ada4a571e74d3258c 100644 +index 65bb221993147a558995b36fb835f7b82e0eb4bd..6cc9271ba058f4af759eae34e2f6e9f892b4f6da 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1118,6 +1118,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1119,6 +1119,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleEditBook(ServerboundEditBookPacket packet) { @@ -2409,7 +1793,7 @@ index 8bd243a8d5a4be54f907af2b02e96ea833cee62f..501cb7450cd28ca487c1522ada4a571e // Paper start if (!this.cserver.isPrimaryThread()) { List pageList = packet.getPages(); -@@ -2273,6 +2274,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2274,6 +2275,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private boolean updateChatOrder(Instant timestamp) { @@ -2417,23 +1801,123 @@ index 8bd243a8d5a4be54f907af2b02e96ea833cee62f..501cb7450cd28ca487c1522ada4a571e Instant instant1; do { -diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index ff2dd53e9e943aa929188fd9d4c35498b78c497a..0c57a06b785dc024ee05ac1291a56f08624e1e56 100644 ---- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -126,6 +126,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +diff --git a/src/main/java/net/minecraft/world/CompoundContainer.java b/src/main/java/net/minecraft/world/CompoundContainer.java +index 241fec02e6869c638d3a160819b32173a081467b..6a8f9e8f5bf108674c47018def28906e2d0a729c 100644 +--- a/src/main/java/net/minecraft/world/CompoundContainer.java ++++ b/src/main/java/net/minecraft/world/CompoundContainer.java +@@ -1,5 +1,6 @@ + package net.minecraft.world; + ++import net.minecraft.core.Direction; // Pufferfish + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; + +@@ -64,6 +65,23 @@ public class CompoundContainer implements Container { + this.container2 = second; + } ++ // Pufferfish start ++ @Override ++ public boolean hasEmptySlot(Direction enumdirection) { ++ return this.container1.hasEmptySlot(null) || this.container2.hasEmptySlot(null); ++ } ++ ++ @Override ++ public boolean isCompletelyFull(Direction enumdirection) { ++ return this.container1.isCompletelyFull(null) && this.container2.isCompletelyFull(null); ++ } ++ ++ @Override ++ public boolean isCompletelyEmpty(Direction enumdirection) { ++ return this.container1.isCompletelyEmpty(null) && this.container2.isCompletelyEmpty(null); ++ } ++ // Pufferfish end ++ @Override - public void onDisconnect(Component reason) { -+ if (gg.pufferfish.pufferfish.PufferfishConfig.suppressNullIdDisconnections && this.authenticatedProfile != null && this.authenticatedProfile.getId() == null && "Disconnected".equals(reason.getString())) return; // Pufferfish - ServerLoginPacketListenerImpl.LOGGER.info("{} lost connection: {}", this.getUserName(), reason.getString()); - } + public int getContainerSize() { + return this.container1.getContainerSize() + this.container2.getContainerSize(); +diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java +index d6cbe98e67fdbf8db46338a88ab1356dd63b50a3..20dd3a63b2f955b05a75eb240e33ae4cf6aef28f 100644 +--- a/src/main/java/net/minecraft/world/Container.java ++++ b/src/main/java/net/minecraft/world/Container.java +@@ -3,6 +3,8 @@ package net.minecraft.world; + import java.util.Set; + import java.util.function.Predicate; + import net.minecraft.core.BlockPos; ++ ++import net.minecraft.core.Direction; // Pufferfish + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.Item; + import net.minecraft.world.item.ItemStack; +@@ -14,6 +16,63 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity; + // CraftBukkit end + + public interface Container extends Clearable { ++ // Pufferfish start - allow the inventory to override and optimize these frequent calls ++ default boolean hasEmptySlot(@org.jetbrains.annotations.Nullable Direction enumdirection) { // there is a slot with 0 items in it ++ if (this instanceof WorldlyContainer worldlyContainer) { ++ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { ++ if (this.getItem(i).isEmpty()) { ++ return true; ++ } ++ } ++ } else { ++ int size = this.getContainerSize(); ++ for (int i = 0; i < size; i++) { ++ if (this.getItem(i).isEmpty()) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ default boolean isCompletelyFull(@org.jetbrains.annotations.Nullable Direction enumdirection) { // every stack is maxed ++ if (this instanceof WorldlyContainer worldlyContainer) { ++ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { ++ ItemStack itemStack = this.getItem(i); ++ if (itemStack.getCount() < itemStack.getMaxStackSize()) { ++ return false; ++ } ++ } ++ } else { ++ int size = this.getContainerSize(); ++ for (int i = 0; i < size; i++) { ++ ItemStack itemStack = this.getItem(i); ++ if (itemStack.getCount() < itemStack.getMaxStackSize()) { ++ return false; ++ } ++ } ++ } ++ return true; ++ } ++ ++ default boolean isCompletelyEmpty(@org.jetbrains.annotations.Nullable Direction enumdirection) { ++ if (this instanceof WorldlyContainer worldlyContainer) { ++ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { ++ if (!this.getItem(i).isEmpty()) { ++ return false; ++ } ++ } ++ } else { ++ int size = this.getContainerSize(); ++ for (int i = 0; i < size; i++) { ++ if (!this.getItem(i).isEmpty()) { ++ return false; ++ } ++ } ++ } ++ return true; ++ } ++ // Pufferfish end + int LARGE_MAX_STACK_SIZE = 64; + int DEFAULT_DISTANCE_LIMIT = 8; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c761560d2dfad 100644 +index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0bf55da454 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -305,7 +305,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -306,7 +306,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public double yo; public double zo; private Vec3 position; @@ -2442,7 +1926,7 @@ index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c7615 private ChunkPos chunkPosition; private Vec3 deltaMovement; private float yRot; -@@ -433,6 +433,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -434,6 +434,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return this.originWorld; } // Paper end @@ -2451,10 +1935,11 @@ index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c7615 + public int activatedPriority = gg.pufferfish.pufferfish.PufferfishConfig.maximumActivationPrio; // golf score + public final BlockPos.MutableBlockPos cachedBlockPos = new BlockPos.MutableBlockPos(); // used where needed + // Pufferfish end ++ public float getBukkitYaw() { return this.yRot; } -@@ -765,6 +770,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -798,6 +804,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public void tick() { @@ -2467,7 +1952,7 @@ index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c7615 this.baseTick(); } -@@ -4324,16 +4335,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4362,16 +4374,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { @@ -2493,7 +1978,7 @@ index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c7615 double d1 = 0.0D; boolean flag = this.isPushedByFluid(); boolean flag1 = false; -@@ -4341,14 +4354,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4379,14 +4393,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { int k1 = 0; BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); @@ -2561,7 +2046,7 @@ index f20ae9153b7098980ce6c0e75fcbbb4da652661b..b2b1e34af626fad2586dcc12596c7615 if (d2 >= axisalignedbb.minY) { flag1 = true; -@@ -4370,9 +4430,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4408,9 +4469,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // CraftBukkit end } } @@ -2588,7 +2073,7 @@ index 73871f456a85bda1e51f54986d0e61fb629822e8..2561e74ffdf595a9b6ae13dcd738662c private String descriptionId; @Nullable diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 77a1c7dfbaccc2e74da5c78ce4dfcd1717a7ac65..4a8a0432366f16f4a7028293bb4d33770f215ec6 100644 +index 15e1d8c09fad181406a6acb8b3f177cd5e6c0f52..3b9ee3324a084271862ed790e8fc0d469e877ec1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -142,7 +142,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; @@ -2608,7 +2093,7 @@ index 77a1c7dfbaccc2e74da5c78ce4dfcd1717a7ac65..4a8a0432366f16f4a7028293bb4d3377 this.hurt(this.damageSources().inWall(), 1.0F); } else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) { double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); -@@ -1401,6 +1400,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1409,6 +1408,19 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.getHealth() <= 0.0F; } @@ -2628,7 +2113,7 @@ index 77a1c7dfbaccc2e74da5c78ce4dfcd1717a7ac65..4a8a0432366f16f4a7028293bb4d3377 @Override public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { -@@ -1999,6 +2011,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2004,6 +2016,20 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.lastClimbablePos; } @@ -2650,7 +2135,7 @@ index 77a1c7dfbaccc2e74da5c78ce4dfcd1717a7ac65..4a8a0432366f16f4a7028293bb4d3377 if (this.isSpectator()) { return false; diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index d28c477171c1b6888a45175075017d960464b5cd..4cb836dfa7cbd2e634d4a3a567da0305aac0da4d 100644 +index 956d05e2ae59978ea9623ca0e167c0afe0b87306..944c22ea172796492a683d2f2bddfb0938d7a8c9 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -220,14 +220,16 @@ public abstract class Mob extends LivingEntity implements Targeting { @@ -2672,7 +2157,7 @@ index d28c477171c1b6888a45175075017d960464b5cd..4cb836dfa7cbd2e634d4a3a567da0305 this.targetSelector.tick(); } } -@@ -913,16 +915,20 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -911,16 +913,20 @@ public abstract class Mob extends LivingEntity implements Targeting { if (i % 2 != 0 && this.tickCount > 1) { this.level().getProfiler().push("targetSelector"); @@ -2694,29 +2179,32 @@ index d28c477171c1b6888a45175075017d960464b5cd..4cb836dfa7cbd2e634d4a3a567da0305 this.level().getProfiler().pop(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index 7204b973c3ad9239e82355513f6d538107102e48..d8bb16f74fdd8d5a50bd384249e0eac9640cd498 100644 +index 7204b973c3ad9239e82355513f6d538107102e48..3087f8359b098682a345399c85395de8a15b6eed 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -23,9 +23,11 @@ public class AttributeMap { private final Map attributes = Maps.newHashMap(); private final Set dirtyAttributes = Sets.newHashSet(); private final AttributeSupplier supplier; -+ private final java.util.function.Function createdInstance; // Pufferfish ++ private final java.util.function.Function createInstance; // Pufferfish public AttributeMap(AttributeSupplier defaultAttributes) { this.supplier = defaultAttributes; -+ this.createdInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish ++ this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish } private void onAttributeModified(AttributeInstance instance) { -@@ -47,9 +49,7 @@ public class AttributeMap { +@@ -45,11 +47,10 @@ public class AttributeMap { + }).collect(Collectors.toList()); + } ++ @Nullable public AttributeInstance getInstance(Attribute attribute) { - return this.attributes.computeIfAbsent(attribute, (attributex) -> { - return this.supplier.createInstance(this::onAttributeModified, attributex); - }); -+ return this.attributes.computeIfAbsent(attribute, this.createdInstance); // Pufferfish - cache lambda, as for some reason java allocates it anyway ++ return this.attributes.computeIfAbsent(attribute, this.createInstance); // Pufferfish - cache lambda, as for some reason java allocates it anyways } @Nullable @@ -2838,7 +2326,7 @@ index 5ad5f22e5aa26445e5eb229958e7bf356bdd460e..d241ca4d0295f9fce39c11197bd435cf this.level().getProfiler().pop(); this.level().getProfiler().push("allayActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java -index aa850cfaa0534d57e83f37360724da2428a48a18..eb1e850f11ed1cd8d2f1f2eb1af55b7fe6352ed4 100644 +index d5b97d4316390028f54aa9bb9fa52b0b003e32a0..b4793b88688bd568a428aa520e880f0038de45a7 100644 --- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java +++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java @@ -280,9 +280,11 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { +@@ -142,6 +142,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return holder.is(PoiTypes.MEETING); }); -+ public long nextGolemPanic = -1; // Pufferfish ++ public long nextGolemPanic = -1; // Pufferfish ++ public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); -@@ -245,6 +246,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + } +@@ -245,6 +247,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } // Spigot End @@ -3013,7 +2502,7 @@ index f555e29c7f9ea4ddb243a018bdc93d2bf1950c3c..1bc082a1fad26e38a8606b633bf3789b @Override @Deprecated // Paper protected void customServerAiStep() { -@@ -254,7 +256,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -254,7 +257,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler protected void customServerAiStep(final boolean inactive) { // Paper end this.level().getProfiler().push("villagerBrain"); @@ -3099,6 +2588,53 @@ index a90317100d32974e481e14476843f66997a2cf3a..cd0629581bae5f805842157af36c2d83 public void setOwner(@Nullable Entity entity) { if (entity != null) { this.ownerUUID = entity.getUUID(); +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +index 00187fbbeddfc17e1b6887f8bf0f50da23938470..f64edfdb03f99624daf1e05b5dc86d845c3018b6 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +@@ -27,7 +27,10 @@ import org.bukkit.inventory.InventoryHolder; + + public abstract class AbstractMinecartContainer extends AbstractMinecart implements ContainerEntity { + ++ // Pufferfish start + private NonNullList itemStacks; ++ private gg.airplane.structs.ItemListWithBitset itemStacksOptimized; ++ // Pufferfish end + @Nullable + public ResourceLocation lootTable; + public long lootTableSeed; +@@ -89,12 +92,18 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme + + protected AbstractMinecartContainer(EntityType type, Level world) { + super(type, world); +- this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 ++ // Pufferfish start ++ this.itemStacksOptimized = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // CraftBukkit - SPIGOT-3513 ++ this.itemStacks = this.itemStacksOptimized.nonNullList; ++ // Pufferfish end + } + + protected AbstractMinecartContainer(EntityType type, double x, double y, double z, Level world) { + super(type, world, x, y, z); +- this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 ++ // Pufferfish start ++ this.itemStacksOptimized = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // CraftBukkit - SPIGOT-3513 ++ this.itemStacks = this.itemStacksOptimized.nonNullList; ++ // Pufferfish end + } + + @Override +@@ -156,6 +165,10 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme + protected void readAdditionalSaveData(CompoundTag nbt) { + super.readAdditionalSaveData(nbt); + this.lootableData.loadNbt(nbt); // Paper ++ // Pufferfish start ++ this.itemStacksOptimized = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); ++ this.itemStacks = this.itemStacksOptimized.nonNullList; ++ // Pufferfish end + this.readChestVehicleSaveData(nbt); + } + diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java index 5a19875cbc603acea95193d969d2e1dc1e0bfd78..3688e9f8c6c6d1239095e3a87060ccca90386d0c 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -3113,26 +2649,24 @@ index 5a19875cbc603acea95193d969d2e1dc1e0bfd78..3688e9f8c6c6d1239095e3a87060ccca } } diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -index 38f7d1ece27ec1a3deda21fb6a6f0e788c8ed718..cf8795e3e91a6ef0dc8c37f17b16480fb4845bff 100644 +index 38f7d1ece27ec1a3deda21fb6a6f0e788c8ed718..252fc22844682c0f67dc02a87478e01e49b6430d 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -@@ -26,8 +26,15 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo +@@ -26,8 +26,13 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo final CraftingBookCategory category; final ItemStack result; final NonNullList ingredients; + private final boolean isBukkit; // Pufferfish ++ // Pufferfish start public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList ingredients) { -+ // Pufferfish start + this(group, category, result, ingredients, false); + } -+ public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList ingredients, boolean isBukkit) { -+ this.isBukkit = isBukkit; -+ // Pufferfish end ++ public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList ingredients, boolean isBukkit) { this.isBukkit = isBukkit; // Pufferfish end this.group = group; this.category = category; this.result = result; -@@ -77,6 +84,28 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo +@@ -77,6 +82,28 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo } public boolean matches(CraftingContainer inventory, Level world) { @@ -3157,15 +2691,24 @@ index 38f7d1ece27ec1a3deda21fb6a6f0e788c8ed718..cf8795e3e91a6ef0dc8c37f17b16480f + return ingredients.isEmpty(); + } + // Pufferfish end -+ ++ StackedContents autorecipestackmanager = new StackedContents(); autorecipestackmanager.initialize(this); // Paper - better exact choice recipes int i = 0; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ea8a0961190e9aafda4fed6fecd85097c141040a..4b49df79d366e58e1cee245e1aaefbb95f4fdfc0 100644 +index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..99e1c645871be28d130319b65700a1b8db093de4 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1308,13 +1308,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -210,6 +210,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public abstract ResourceKey getTypeKey(); + ++ protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter ++ + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper +@@ -1308,13 +1310,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick @@ -3181,7 +2724,7 @@ index ea8a0961190e9aafda4fed6fecd85097c141040a..4b49df79d366e58e1cee245e1aaefbb9 // Paper end } } -@@ -1779,6 +1779,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1779,6 +1781,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { @@ -3190,7 +2733,7 @@ index ea8a0961190e9aafda4fed6fecd85097c141040a..4b49df79d366e58e1cee245e1aaefbb9 } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 3cdddda9c0618e95288b81b975d499c8dd30c05f..27b75fba1b8052a715979f48b28bba0e4be16274 100644 +index 3cdddda9c0618e95288b81b975d499c8dd30c05f..9c2d62feff1816f5729060c6192269a5b2d34153 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -429,12 +429,12 @@ public final class NaturalSpawner { @@ -3198,12 +2741,12 @@ index 3cdddda9c0618e95288b81b975d499c8dd30c05f..27b75fba1b8052a715979f48b28bba0e } - private static BlockPos getRandomPosWithin(Level world, LevelChunk chunk) { -+ private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Pufferfish - accept serverLevel ++ private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Pufferfish - accept serverlevel ChunkPos chunkcoordintpair = chunk.getPos(); - int i = chunkcoordintpair.getMinBlockX() + world.random.nextInt(16); - int j = chunkcoordintpair.getMinBlockZ() + world.random.nextInt(16); -+ int i = chunkcoordintpair.getMinBlockX() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish - use thread unsafe random -+ int j = chunkcoordintpair.getMinBlockZ() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish ++ int i = chunkcoordintpair.getMinBlockX() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish - use thread unsafe random ++ int j = chunkcoordintpair.getMinBlockZ() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish int k = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i, j) + 1; - int l = Mth.randomBetweenInclusive(world.random, world.getMinBuildHeight(), k); + int l = Mth.randomBetweenInclusive(world.getThreadUnsafeRandom(), world.getMinBuildHeight(), k); // Pufferfish @@ -3259,6 +2802,231 @@ index 65012a12e1430956ef55ced56773e6354ac26444..ed439b7e94646141c93a7dd3704d1cde return g; } } +diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f3040b26a 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +@@ -31,7 +31,10 @@ import org.bukkit.entity.HumanEntity; + public class ChestBlockEntity extends RandomizableContainerBlockEntity implements LidBlockEntity { + + private static final int EVENT_SET_OPEN_COUNT = 1; ++ // Pufferfish start + private NonNullList items; ++ private gg.airplane.structs.ItemListWithBitset optimizedItems; ++ // Pufferfish end + public final ContainerOpenersCounter openersCounter; + private final ChestLidController chestLidController; + +@@ -65,9 +68,13 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + } + // CraftBukkit end + ++ private final boolean isNative = getClass().equals(ChestBlockEntity.class); // Pufferfish + protected ChestBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); +- this.items = NonNullList.withSize(27, ItemStack.EMPTY); ++ // Pufferfish start ++ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(27); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + this.openersCounter = new ContainerOpenersCounter() { + @Override + protected void onOpen(Level world, BlockPos pos, BlockState state) { +@@ -98,6 +105,23 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + this.chestLidController = new ChestLidController(); + } + ++ // Pufferfish start ++ @Override ++ public boolean hasEmptySlot(Direction enumdirection) { ++ return isNative ? !this.optimizedItems.hasFullStacks() : super.hasEmptySlot(enumdirection); ++ } ++ ++ @Override ++ public boolean isCompletelyFull(Direction enumdirection) { ++ return isNative ? this.optimizedItems.hasFullStacks() && super.isCompletelyFull(enumdirection) : super.isCompletelyFull(enumdirection); ++ } ++ ++ @Override ++ public boolean isCompletelyEmpty(Direction enumdirection) { ++ return isNative && this.optimizedItems.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection); ++ } ++ // Pufferfish end ++ + public ChestBlockEntity(BlockPos pos, BlockState state) { + this(BlockEntityType.CHEST, pos, state); + } +@@ -115,7 +139,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + @Override + public void load(CompoundTag nbt) { + super.load(nbt); +- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); ++ // Pufferfish start ++ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + if (!this.tryLoadLootTable(nbt)) { + ContainerHelper.loadAllItems(nbt, this.items); + } +@@ -187,7 +214,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + + @Override + protected void setItems(NonNullList list) { +- this.items = list; ++ // Pufferfish start ++ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(list); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index d4dcf7fe26474ae07374e7761d823bc5c8b54f97..1d13fabb3f34023b4fbb1be9ad02ebc606645531 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -47,7 +47,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + + public static final int MOVE_ITEM_SPEED = 8; + public static final int HOPPER_CONTAINER_SIZE = 5; ++ // Pufferfish start + private NonNullList items; ++ private gg.airplane.structs.ItemListWithBitset optimizedItems; // Pufferfish ++ // Pufferfish end + private int cooldownTime; + private long tickedGameTime; + +@@ -83,14 +86,37 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + + public HopperBlockEntity(BlockPos pos, BlockState state) { + super(BlockEntityType.HOPPER, pos, state); +- this.items = NonNullList.withSize(5, ItemStack.EMPTY); ++ // Pufferfish start ++ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(5); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + this.cooldownTime = -1; + } + ++ // Pufferfish start ++ @Override ++ public boolean hasEmptySlot(Direction enumdirection) { ++ return !this.optimizedItems.hasFullStacks(); ++ } ++ ++ @Override ++ public boolean isCompletelyFull(Direction enumdirection) { ++ return this.optimizedItems.hasFullStacks() && super.isCompletelyFull(enumdirection); ++ } ++ ++ @Override ++ public boolean isCompletelyEmpty(Direction enumdirection) { ++ return this.optimizedItems.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection); ++ } ++ // Pufferfish end ++ + @Override + public void load(CompoundTag nbt) { + super.load(nbt); +- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); ++ // Pufferfish start ++ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + if (!this.tryLoadLootTable(nbt)) { + ContainerHelper.loadAllItems(nbt, this.items); + } +@@ -491,6 +517,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + } + + private static boolean isFullContainer(Container inventory, Direction direction) { ++ if (true) return inventory.isCompletelyFull(direction); // Pufferfish - use bitsets + // Paper start - optimize hoppers + if (inventory instanceof WorldlyContainer worldlyContainer) { + for (final int slot : worldlyContainer.getSlotsForFace(direction)) { +@@ -513,7 +540,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + } + + private static boolean isEmptyContainer(Container inv, Direction facing) { +- return allMatch(inv, facing, IS_EMPTY_TEST); ++ // Paper start ++ // Pufferfish start - use bitsets ++ //return allMatch(inv, facing, IS_EMPTY_TEST); ++ return inv.isCompletelyEmpty(facing); ++ // Pufferfish end + } + + public static boolean suckInItems(Level world, Hopper hopper) { +@@ -713,7 +744,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + + if (HopperBlockEntity.canPlaceItemInContainer(to, stack, slot, side)) { + boolean flag = false; +- boolean flag1 = to.isEmpty(); ++ boolean flag1 = to.isCompletelyEmpty(side); // Pufferfish + + if (itemstack1.isEmpty()) { + // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem +@@ -908,7 +939,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + + @Override + protected void setItems(NonNullList list) { +- this.items = list; ++ // Pufferfish start ++ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(list); ++ this.items = this.optimizedItems.nonNullList; ++ // Pufferfish end + } + + public static void entityInside(Level world, BlockPos pos, BlockState state, Entity entity, HopperBlockEntity blockEntity) { +diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +index 3e638f12956e57548f76c7e2403ba370f7baa249..02364a148b347e3669275553004391e31d77c0b5 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +@@ -96,12 +96,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc + public boolean isEmpty() { + this.unpackLootTable((Player)null); + // Paper start +- for (final ItemStack itemStack : this.getItems()) { +- if (!itemStack.isEmpty()) { +- return false; +- } +- } +- return true; ++ return this.isCompletelyEmpty(null); // Pufferfish - use super + // Paper end + } + +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 fa170cc1ce7011d201295b89718292d696c7fc24..7fd68d4aba72b15b2e21e5c88b44e677b794fe57 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -86,6 +86,18 @@ public class LevelChunk extends ChunkAccess { + private final LevelChunkTicks fluidTicks; + public volatile FullChunkStatus chunkStatus = FullChunkStatus.INACCESSIBLE; // Paper - rewrite chunk system + ++ // Pufferfish start - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively ++ private int lightningTick; ++ // shouldDoLightning compiles down to 29 bytes, which with the default of 35 byte inlining should guarantee an inline ++ public final boolean shouldDoLightning(net.minecraft.util.RandomSource random) { ++ if (this.lightningTick-- <= 0) { ++ this.lightningTick = random.nextInt(this.level.spigotConfig.thunderChance) << 1; ++ return true; ++ } ++ return false; ++ } ++ // Pufferfish end ++ + public LevelChunk(Level world, ChunkPos pos) { + this(world, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, (LevelChunkSection[]) null, (LevelChunk.PostLoadProcessor) null, (BlendingData) null); + } +@@ -109,6 +121,8 @@ public class LevelChunk extends ChunkAccess { + this.postLoad = entityLoader; + this.blockTicks = blockTickScheduler; + this.fluidTicks = fluidTickScheduler; ++ ++ this.lightningTick = this.level.getThreadUnsafeRandom().nextInt(100000) << 1; // Pufferfish - initialize lightning tick + } + + // CraftBukkit start 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 f0de72afad4bb571153436399386a6a8a70582a6..45b7527341fcb6d24f35318cedb522646b5ee1c2 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -3309,7 +3077,7 @@ index 4cdfc433df67afcd455422e9baf56f167dd712ae..57fcf3910f45ce371ac2e237b277b103 private void ensureActiveIsNotIterated() { // Paper - replace with better logic, do not delay removals 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 e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4e9ed54d7 100644 +index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af5f81d742 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java @@ -45,6 +45,8 @@ public abstract class FlowingFluid extends Fluid { @@ -3321,11 +3089,12 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4 private static final ThreadLocal> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> { Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { protected void rehash(int i) {} -@@ -53,6 +55,13 @@ public abstract class FlowingFluid extends Fluid { +@@ -53,6 +55,14 @@ public abstract class FlowingFluid extends Fluid { object2bytelinkedopenhashmap.defaultReturnValue((byte) 127); return object2bytelinkedopenhashmap; }); + */ ++ + private static final ThreadLocal> localFluidDirectionCache = ThreadLocal.withInitial(() -> { + // Pufferfish todo - mess with this number for performance + // with 2048 it seems very infrequent on a small world that it has to remove old entries @@ -3335,7 +3104,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4 private final Map shapes = Maps.newIdentityHashMap(); public FlowingFluid() {} -@@ -252,6 +261,8 @@ public abstract class FlowingFluid extends Fluid { +@@ -252,6 +262,8 @@ public abstract class FlowingFluid extends Fluid { return false; } // Paper end - optimise collisions @@ -3344,7 +3113,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4 Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -@@ -259,9 +270,16 @@ public abstract class FlowingFluid extends Fluid { +@@ -259,9 +271,16 @@ public abstract class FlowingFluid extends Fluid { } else { object2bytelinkedopenhashmap = null; } @@ -3361,7 +3130,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4 if (object2bytelinkedopenhashmap != null) { block_a = new Block.BlockStatePairKey(state, fromState, face); byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); -@@ -272,11 +290,22 @@ public abstract class FlowingFluid extends Fluid { +@@ -272,11 +291,22 @@ public abstract class FlowingFluid extends Fluid { } else { block_a = null; } @@ -3384,12 +3153,14 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..089f42d16b2e279fa0daefb8705867a4 if (object2bytelinkedopenhashmap != null) { if (object2bytelinkedopenhashmap.size() == 200) { object2bytelinkedopenhashmap.removeLastByte(); -@@ -284,6 +313,9 @@ public abstract class FlowingFluid extends Fluid { +@@ -284,6 +314,11 @@ public abstract class FlowingFluid extends Fluid { object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); } + */ -+ if (cache != null) cache.putValue(block_a, flag); ++ if (cache != null) { ++ cache.putValue(block_a, flag); ++ } + // Pufferfish end return flag; @@ -3498,10 +3269,10 @@ index ebe65474a4a05ff1637d7f37ebcfe690af59def5..42142c512b12e5b269c19f1e821c50e7 @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index fcd5096d64edfaf6bce3ecce8c9b9afb84462786..7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f 100644 +index 356107688a5d40d1c462b164f61af82f4dfd3926..2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -267,7 +267,7 @@ import javax.annotation.Nullable; // Paper +@@ -269,7 +269,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -3510,7 +3281,7 @@ index fcd5096d64edfaf6bce3ecce8c9b9afb84462786..7f2f4f3d804832e314983ba78fe9c6cc private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -1122,6 +1122,11 @@ public final class CraftServer implements Server { +@@ -1124,6 +1124,11 @@ public final class CraftServer implements Server { plugin.getPluginMeta().getDisplayName(), "This plugin is not properly shutting down its async tasks when it is being shut down. This task may throw errors during the final shutdown logs and might not complete before process dies." )); @@ -3523,59 +3294,22 @@ index fcd5096d64edfaf6bce3ecce8c9b9afb84462786..7f2f4f3d804832e314983ba78fe9c6cc } // Paper end diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java -index acfe2676b840d4edc70507aa139f7db212ed90b7..65971a2da4e947c7ed60c0730827136665bb7674 100644 +index 96d772eb02f79f8c478f5e6f065e387aa7665b18..c5ce412f321b8b4f31cc042893659e213b081f29 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java @@ -45,6 +45,6 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe - data.set(i, toNMS(ingred.get(i), true)); + data.set(i, this.toNMS(ingred.get(i), true)); } - MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data))); -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data, true))); ++ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data, true))); // Pufferfish } } -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java -index d96399e9bf1a58db5a4a22e58abb99e7660e0694..eb19f679ee498e51d02fe9a961cf02699cf75848 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java -@@ -22,7 +22,8 @@ public class MinecraftInternalPlugin extends PluginBase { - private boolean enabled = true; - - private final String pluginName; -- private PluginDescriptionFile pdf; -+ private org.bukkit.plugin.PluginLogger logger; -+ private PluginDescriptionFile pdf; // Pufferfish - - public MinecraftInternalPlugin() { - this.pluginName = "Minecraft"; -@@ -81,7 +82,12 @@ public class MinecraftInternalPlugin extends PluginBase { - - @Override - public PluginLogger getLogger() { -- throw new UnsupportedOperationException("Not supported."); -+ // Pufferfish start -+ if (this.logger == null) { -+ this.logger = new org.bukkit.plugin.PluginLogger(this); // Pufferfish -+ } -+ return this.logger; -+ // Pufferfish end - } - - @Override -@@ -91,7 +97,7 @@ public class MinecraftInternalPlugin extends PluginBase { - - @Override - public Server getServer() { -- throw new UnsupportedOperationException("Not supported."); -+ return org.bukkit.Bukkit.getServer(); // Pufferfish - impl - } - - @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 96f6e0554baf5915dd1f5b93f3bcfe7a13393c29..031e5acee0061d7f8050ea3a42f33b42112a3172 100644 +index 548c77592a3520e8053483644eba805079a14f1a..397c10f64db3a4d7296fe18585b56851bc3a1f01 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -452,7 +452,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -485,7 +485,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { @@ -3584,18 +3318,6 @@ index 96f6e0554baf5915dd1f5b93f3bcfe7a13393c29..031e5acee0061d7f8050ea3a42f33b42 } @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java -index e8e93538dfd71de86515d9405f728db1631e949a..3dff02fd97f001508e2f81192817bf1b0ef92446 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java -@@ -11,6 +11,7 @@ public class ServerShutdownThread extends Thread { - - @Override - public void run() { -+ try { gg.pufferfish.pufferfish.flare.ProfilingManager.stop(); } catch (Throwable t) {} // Pufferfish - shut down Flare if it's running - try { - // Paper start - try to shutdown on main - server.safeShutdown(false, false); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 774556a62eb240da42e84db4502e2ed43495be17..80553face9c70c2a3d897681e7761df85b22d464 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -3610,7 +3332,7 @@ index 774556a62eb240da42e84db4502e2ed43495be17..80553face9c70c2a3d897681e7761df8 if (stream != null) { diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 2f9e5a1adf9d67ffe18d95f2822ca3d2288fb27a..acde675a8f1b84b686d53084d66dece3ad5f940e 100644 +index 59103744ac6beeb12719fdefcda54eeff498229e..c0333ba8e57cd284bb8ab15181da6b39d55872f9 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -38,6 +38,10 @@ import co.aikar.timings.MinecraftTimings; @@ -3624,7 +3346,7 @@ index 2f9e5a1adf9d67ffe18d95f2822ca3d2288fb27a..acde675a8f1b84b686d53084d66dece3 public class ActivationRange { -@@ -222,6 +226,24 @@ public class ActivationRange +@@ -222,6 +226,25 @@ public class ActivationRange } // Paper end - configurable marker ticking ActivationRange.activateEntity(entity); @@ -3646,10 +3368,26 @@ index 2f9e5a1adf9d67ffe18d95f2822ca3d2288fb27a..acde675a8f1b84b686d53084d66dece3 + entity.activatedPriority = 1; + } + // Pufferfish end ++ } // Paper end } -@@ -297,7 +319,7 @@ public class ActivationRange +@@ -238,12 +261,12 @@ public class ActivationRange + if ( MinecraftServer.currentTick > entity.activatedTick ) + { + if ( entity.defaultActivationState ) +- { ++ { // Pufferfish - diff on change + entity.activatedTick = MinecraftServer.currentTick; + return; + } + if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) +- { ++ { // Pufferfish - diff on change + entity.activatedTick = MinecraftServer.currentTick; + } + } +@@ -297,7 +320,7 @@ public class ActivationRange if ( entity instanceof LivingEntity ) { LivingEntity living = (LivingEntity) entity; diff --git a/patches/server/0002-Purpur-Server-Changes.patch b/patches/server/0002-Purpur-Server-Changes.patch index 51e8968b6..475cf3dd5 100644 --- a/patches/server/0002-Purpur-Server-Changes.patch +++ b/patches/server/0002-Purpur-Server-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath -Date: Sat, 30 Sep 2023 09:53:53 +0000 +Date: Sat, 25 Nov 2023 11:56:59 +0000 Subject: [PATCH] Purpur Server Changes Original: PurpurMC @@ -25,10 +25,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/build.gradle.kts b/build.gradle.kts -index de0a05602389ebb005bb7fd3c8d78da045d55bbe..393dab1ece76e0ca1e0b58c0b2c72d5c1c41a84d 100644 +index 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888fbdc9bf3c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -13,13 +13,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { +@@ -13,12 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { val alsoShade: Configuration by configurations.creating dependencies { @@ -40,23 +40,23 @@ index de0a05602389ebb005bb7fd3c8d78da045d55bbe..393dab1ece76e0ca1e0b58c0b2c72d5c + implementation("io.papermc.paper:paper-mojangapi:${project.version}") { exclude("io.papermc.paper", "paper-api") } -+ // Purpur end - implementation("com.github.technove:Flare:34637f3f87") // flare - // Pufferfish end ++ // Purpur end // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -63,6 +63,9 @@ dependencies { - exclude(group="org.yaml", module="snakeyaml") +@@ -62,6 +62,10 @@ dependencies { } // Pufferfish end + + implementation("org.mozilla:rhino-runtime:1.7.14") // Purpur + implementation("org.mozilla:rhino-engine:1.7.14") // Purpur + implementation("dev.omega24:upnp4j:1.0") // Purpur - ++ testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") -@@ -84,7 +87,7 @@ tasks.jar { + testImplementation("org.hamcrest:hamcrest:2.2") +@@ -89,7 +93,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -65,7 +65,7 @@ index de0a05602389ebb005bb7fd3c8d78da045d55bbe..393dab1ece76e0ca1e0b58c0b2c72d5c "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -168,7 +171,7 @@ fun TaskContainer.registerRunTask( +@@ -173,7 +177,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -74,6 +74,15 @@ index de0a05602389ebb005bb7fd3c8d78da045d55bbe..393dab1ece76e0ca1e0b58c0b2c72d5c mainClass.set("org.bukkit.craftbukkit.Main") standardInput = System.`in` workingDir = rootProject.layout.projectDirectory +@@ -229,5 +233,7 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> + } + tasks.registerRunTask("runDev") { + description = "Spin up a non-relocated Mojang-mapped test server" +- classpath(sourceSets.main.map { it.runtimeClasspath }) ++ classpath(tasks.filterProjectDir.flatMap { it.outputJar }) ++ classpath(runtimeClasspathForRunDev) ++ jvmArgs("-DPaper.isRunDev=true") + } diff --git a/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java b/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8ace07630c @@ -166,7 +175,7 @@ index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8a + } +} diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index 692c962193cf9fcc6801fc93f3220bdc673d527b..b0b2cbd8d9db1772d43a285eca9060f3879acab0 100644 +index 692c962193cf9fcc6801fc93f3220bdc673d527b..8cde30544e14f8fc2dac32966ae3c21f8cf3a551 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java @@ -593,7 +593,7 @@ public class Metrics { @@ -178,16 +187,25 @@ index 692c962193cf9fcc6801fc93f3220bdc673d527b..b0b2cbd8d9db1772d43a285eca9060f3 metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { String minecraftVersion = Bukkit.getVersion(); -@@ -602,7 +602,8 @@ public class Metrics { +@@ -602,16 +602,8 @@ public class Metrics { })); metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size())); - metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : "offline")); +- final String paperVersion; +- final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion(); +- if (implVersion != null) { +- final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1); +- paperVersion = "git-Pufferfish-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Pufferfish +- } else { +- paperVersion = "unknown"; +- } +- metrics.addCustomChart(new Metrics.SimplePie("pufferfish_version", () -> paperVersion)); // Pufferfish + metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() ? "bungee" : "offline"))); // Purpur + metrics.addCustomChart(new Metrics.SimplePie("purpur_version", () -> (org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion() != null) ? org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion() : "unknown")); // Purpur - final String paperVersion; - final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion(); - if (implVersion != null) { + + metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { + Map> map = new HashMap<>(); diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java index 9d687da5bdf398bb3f6c84cdf1249a7213d09f2e..462a6eed350fd660ddaf25d567bb6e97b77d0b2b 100644 --- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java @@ -333,18 +351,18 @@ index fa56cd09102a89692b42f1d14257990508c5c720..f9251183df72ddc56662fd3f02acf216 setListData(vector); } diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -index 7b091c1258c3f33933ec30a15d963e9d5f069ba7..5f223856b06e901b100fcca8e6dd968e0b2e3a8e 100644 +index cc66657cb4f978aa2df3ca1be6c683759952cc7a..9ca1494497ae53e56b1f81fda51b0b8bd02a6d03 100644 --- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -@@ -36,6 +36,7 @@ public class PufferfishConfig { +@@ -28,6 +28,7 @@ public class PufferfishConfig { private static final YamlFile config = new YamlFile(); private static int updates = 0; -+ public static File pufferfishFile; // Purpur ++ public static File pufferfishFile; // Purpur private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) { ConfigurationSection newSection = new MemoryConfiguration(); -@@ -58,7 +59,7 @@ public class PufferfishConfig { +@@ -50,7 +51,7 @@ public class PufferfishConfig { } public static void load() throws IOException { @@ -353,7 +371,7 @@ index 7b091c1258c3f33933ec30a15d963e9d5f069ba7..5f223856b06e901b100fcca8e6dd968e if (configFile.exists()) { try { -@@ -232,7 +233,7 @@ public class PufferfishConfig { +@@ -224,7 +225,7 @@ public class PufferfishConfig { public static int activationDistanceMod; private static void dynamicActivationOfBrains() throws IOException { @@ -362,7 +380,7 @@ index 7b091c1258c3f33933ec30a15d963e9d5f069ba7..5f223856b06e901b100fcca8e6dd968e startDistance = getInt("dab.start-distance", "activation-range.start-distance", 12, "This value determines how far away an entity has to be", "from the player to start being effected by DEAR."); -@@ -276,7 +277,7 @@ public class PufferfishConfig { +@@ -268,7 +269,7 @@ public class PufferfishConfig { public static boolean throttleInactiveGoalSelectorTick; private static void inactiveGoalSelectorThrottle() { @@ -1028,7 +1046,7 @@ index 9ec6145fe04ec64bbee8ec6a837719caebdbc6f5..358d610ad020cada1bb83e393deeeaae public ClientboundSetTimePacket(long time, long timeOfDay, boolean doDaylightCycle) { this.gameTime = time; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 87cacb46fb2b07482d3d608019d65a74b3854800..8c3942d9ce4f8a102a47bec74af5911760fda4e3 100644 +index 58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90..b61c4d1ebb9c15a7ecd7bec5eb864851c053fb7e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -288,6 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -@@ -341,6 +345,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - }; -+ */ // Purpur +- this.metricsRecorder = InactiveMetricsRecorder.INSTANCE; +- this.profiler = this.metricsRecorder.getProfiler(); +- this.onMetricsRecordingStopped = (methodprofilerresults) -> { ++ //this.metricsRecorder = InactiveMetricsRecorder.INSTANCE; // Purpur ++ //this.profiler = this.metricsRecorder.getProfiler(); // Purpur ++ /*this.onMetricsRecordingStopped = (methodprofilerresults) -> { // Purpur + this.stopRecordingMetrics(); +- }; +- this.onMetricsRecordingFinished = (path) -> { +- }; ++ };*/ // Purpur ++ //this.onMetricsRecordingFinished = (path) -> { // Purpur ++ //}; // Purpur this.random = RandomSource.create(); this.port = -1; this.levels = Maps.newLinkedHashMap(); -@@ -909,7 +914,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return !this.canOversleep(); }); - isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); -+ //isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); // Purpur // Plazma TODO: unmark isOversleep ++ //isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); // Purpur // Paper end new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper -@@ -1388,7 +1419,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.tickCount % autosavePeriod == 0; try { this.isSaving = true; -@@ -1403,20 +1434,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -1264,7 +1285,7 @@ index 87cacb46fb2b07482d3d608019d65a74b3854800..8c3942d9ce4f8a102a47bec74af59117 // Paper start - Folia scheduler API ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); getAllLevels().forEach(level -> { -@@ -1485,22 +1516,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper + worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur -+ /* // Purpur - this.profiler.push(() -> { +- this.profiler.push(() -> { ++ /*this.profiler.push(() -> { // Purpur return worldserver + " " + worldserver.dimension().location(); - }); -+ */ // Purpur +- }); ++ });*/ // Purpur /* Drop global time updates if (this.tickCount % 20 == 0) { - this.profiler.push("timeSync"); -@@ -1542,17 +1577,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! -+ return org.purpurmc.purpur.PurpurConfig.serverModName; // Purpur - Purpur > // Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! ++ return org.purpurmc.purpur.PurpurConfig.serverModName; // Purpur - Purpur > Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! } public SystemReport fillSystemReport(SystemReport details) { -@@ -2273,7 +2308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.executeBlocking(() -> { -@@ -2526,37 +2562,40 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop resultConsumer, Consumer dumpConsumer) { -+ /* // Purpur - this.onMetricsRecordingStopped = (methodprofilerresults) -> { +- this.onMetricsRecordingStopped = (methodprofilerresults) -> { ++ /*this.onMetricsRecordingStopped = (methodprofilerresults) -> { // Purpur this.stopRecordingMetrics(); resultConsumer.accept(methodprofilerresults); }; this.onMetricsRecordingFinished = dumpConsumer; - this.willStartRecordingMetrics = true; -+ */ // Purpur +- this.willStartRecordingMetrics = true; ++ this.willStartRecordingMetrics = true;*/ // Purpur } public void stopRecordingMetrics() { @@ -1497,7 +1527,7 @@ index 87cacb46fb2b07482d3d608019d65a74b3854800..8c3942d9ce4f8a102a47bec74af59117 } public Path getWorldPath(LevelResource worldSavePath) { -@@ -2605,15 +2644,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { final io.papermc.paper.adventure.ChatDecorationProcessor processor = new io.papermc.paper.adventure.ChatDecorationProcessor(this, sender, commandSourceStack, message); -@@ -2781,7 +2829,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); - level.timings.tracker1.startTiming(); // Paper -+ //level.timings.tracker1.startTiming(); // Paper // Purpur ++ //this.level.timings.tracker1.startTiming(); // Paper // Purpur ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1115,17 +1115,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1213,17 +1213,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } - level.timings.tracker1.stopTiming(); // Paper -+ //level.timings.tracker1.stopTiming(); // Paper // Purpur ++ //this.level.timings.tracker1.stopTiming(); // Paper // Purpur if (!list.isEmpty()) { objectiterator = this.entityMap.values().iterator(); - level.timings.tracker2.startTiming(); // Paper -+ //level.timings.tracker2.startTiming(); // Paper // Purpur ++ //this.level.timings.tracker2.startTiming(); // Paper // Purpur while (objectiterator.hasNext()) { playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next(); playerchunkmap_entitytracker.updatePlayers(list); } - level.timings.tracker2.stopTiming(); // Paper -+ //level.timings.tracker2.stopTiming(); // Paper // Purpur ++ //this.level.timings.tracker2.stopTiming(); // Paper // Purpur } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575e300ddf6 100644 +index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93b1959ffc 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -278,16 +278,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -279,16 +279,16 @@ public class ServerChunkCache extends ChunkSource { return ifLoaded; } // Paper end @@ -2010,7 +2069,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 CompletableFuture> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; -@@ -297,10 +297,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -298,10 +298,10 @@ public class ServerChunkCache extends ChunkSource { io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system // Paper end com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info @@ -2023,7 +2082,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; -@@ -449,17 +449,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -450,17 +450,17 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -2045,7 +2104,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 } // Paper end -@@ -476,36 +476,36 @@ public class ServerChunkCache extends ChunkSource { +@@ -477,36 +477,36 @@ public class ServerChunkCache extends ChunkSource { // CraftBukkit start - modelled on below public void purgeUnload() { if (true) return; // Paper - tickets will be removed later, this behavior isn't really well accounted for by the chunk system @@ -2095,7 +2154,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 this.clearCache(); } -@@ -520,14 +520,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -521,15 +521,15 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.tick(); } else { LevelData worlddata = this.level.getLevelData(); @@ -2104,8 +2163,9 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 - gameprofilerfiller.push("pollingChunks"); + //gameprofilerfiller.push("pollingChunks"); // Purpur + this.level.resetIceAndSnowTick(); // Pufferfish - reset ice & snow tick random int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); - boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit + boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit - gameprofilerfiller.push("naturalSpawnCount"); - this.level.timings.countNaturalMobs.startTiming(); // Paper - timings @@ -2114,7 +2174,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 int l = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - per player mob spawning NaturalSpawner.SpawnState spawnercreature_d; // moved down -@@ -558,17 +558,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -560,17 +560,17 @@ public class ServerChunkCache extends ChunkSource { // Pufferfish end } // Paper end @@ -2123,7 +2183,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously - gameprofilerfiller.popPush("filteringLoadedChunks"); -+ //gameprofilerfiller.popPush("filteringLoadedChunks"); ++ //gameprofilerfiller.popPush("filteringLoadedChunks"); // Purpur // Paper - optimise chunk tick iteration // Paper - optimise chunk tick iteration - this.level.timings.chunkTicks.startTiming(); // Paper @@ -2136,7 +2196,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit // Paper start - optimise chunk tick iteration -@@ -670,17 +670,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -672,17 +672,17 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -2160,7 +2220,7 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 // Paper start - optimise chunk tick iteration if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -@@ -694,10 +694,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -696,10 +696,10 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -2173,8 +2233,8 @@ index 390e5a4e9cead6f217de7689a47b8c3b4b042990..6255960ae70e14eb11da5043eb003575 + //gameprofilerfiller.pop(); // Purpur this.chunkMap.tick(); } - -@@ -904,7 +904,7 @@ public class ServerChunkCache extends ChunkSource { + +@@ -906,7 +906,7 @@ public class ServerChunkCache extends ChunkSource { @Override protected void doRunTask(Runnable task) { @@ -2197,7 +2257,7 @@ index d46e61640b241d32df05240dedd2c23f138725e6..c6ef510d335b8baea58c4491853414a5 public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer> consumer, Set trackedPlayers) { this.trackedPlayers = trackedPlayers; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a3139481207 100644 +index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442b7a6df83 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -214,6 +214,8 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2278,9 +2338,9 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 this.updateSkyBrightness(); this.tickTime(); - gameprofilerfiller.popPush("tickPending"); -- timings.scheduledBlocks.startTiming(); // Paper +- this.timings.scheduledBlocks.startTiming(); // Paper + //gameprofilerfiller.popPush("tickPending"); // Purpur -+ //timings.scheduledBlocks.startTiming(); // Paper // Purpur // Purpur ++ //this.timings.scheduledBlocks.startTiming(); // Paper // Purpur if (!this.isDebug()) { j = this.getGameTime(); - gameprofilerfiller.push("blockTicks"); @@ -2292,8 +2352,8 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 - gameprofilerfiller.pop(); + //gameprofilerfiller.pop(); // Purpur } -- timings.scheduledBlocks.stopTiming(); // Paper -+ //timings.scheduledBlocks.stopTiming(); // Paper // Purpur // Purpur +- this.timings.scheduledBlocks.stopTiming(); // Paper ++ //this.timings.scheduledBlocks.stopTiming(); // Paper // Purpur - gameprofilerfiller.popPush("raid"); - this.timings.raids.startTiming(); // Paper - timings @@ -2309,13 +2369,13 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 this.getChunkSource().tick(shouldKeepTicking, true); - this.timings.chunkProviderTick.stopTiming(); // Paper - timings - gameprofilerfiller.popPush("blockEvents"); -- timings.doSounds.startTiming(); // Spigot +- this.timings.doSounds.startTiming(); // Spigot + //this.timings.chunkProviderTick.stopTiming(); // Paper - timings // Purpur + //gameprofilerfiller.popPush("blockEvents"); // Purpur -+ //timings.doSounds.startTiming(); // Spigot // Purpur ++ //this.timings.doSounds.startTiming(); // Spigot // Purpur this.runBlockEvents(); -- timings.doSounds.stopTiming(); // Spigot -+ //timings.doSounds.stopTiming(); // Spigot // Purpur +- this.timings.doSounds.stopTiming(); // Spigot ++ //this.timings.doSounds.stopTiming(); // Spigot // Purpur this.handlingTick = false; - gameprofilerfiller.pop(); + //gameprofilerfiller.pop(); // Purpur @@ -2327,9 +2387,9 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 if (flag || this.emptyTime++ < 300) { - gameprofilerfiller.push("entities"); -- timings.tickEntities.startTiming(); // Spigot +- this.timings.tickEntities.startTiming(); // Spigot + //gameprofilerfiller.push("entities"); // Purpur -+ //timings.tickEntities.startTiming(); // Spigot // Purpur ++ //this.timings.tickEntities.startTiming(); // Spigot // Purpur if (this.dragonFight != null) { - gameprofilerfiller.push("dragonFight"); + //gameprofilerfiller.push("dragonFight"); // Purpur @@ -2339,8 +2399,8 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } org.spigotmc.ActivationRange.activateEntities(this); // Spigot -- timings.entityTick.startTiming(); // Spigot -+ //timings.entityTick.startTiming(); // Spigot // Purpur +- this.timings.entityTick.startTiming(); // Spigot ++ //this.timings.entityTick.startTiming(); // Spigot // Purpur this.entityTickList.forEach((entity) -> { entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { @@ -2364,7 +2424,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 // Pufferfish start - copied from this.guardEntityTick try { this.tickNonPassenger(entity); // Pufferfish - changed -@@ -912,20 +933,20 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -912,20 +933,19 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper end } // Pufferfish end @@ -2374,11 +2434,11 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } } }); -- timings.entityTick.stopTiming(); // Spigot -- timings.tickEntities.stopTiming(); // Spigot +- this.timings.entityTick.stopTiming(); // Spigot +- this.timings.tickEntities.stopTiming(); // Spigot - gameprofilerfiller.pop(); -+ //timings.entityTick.stopTiming(); // Spigot // Purpur -+ //timings.tickEntities.stopTiming(); // Spigot // Purpur ++ //this.timings.entityTick.stopTiming(); // Spigot // Purpur ++ //this.timings.tickEntities.stopTiming(); // Spigot // Purpur + //gameprofilerfiller.pop(); // Purpur this.tickBlockEntities(); } @@ -2387,11 +2447,10 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 + //gameprofilerfiller.push("entityManagement"); // Purpur //this.entityManager.tick(); // Paper - rewrite chunk system - gameprofilerfiller.pop(); -+ //gameprofilerfiller.pop(); // Purpur } @Override -@@ -943,6 +964,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -943,6 +963,13 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setGameTime(i); this.serverLevelData.getScheduledEvents().tick(this.server, i); if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { @@ -2405,14 +2464,14 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -951,7 +979,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -951,7 +978,21 @@ public class ServerLevel extends Level implements WorldGenLevel { public void setDayTime(long timeOfDay) { this.serverLevelData.setDayTime(timeOfDay); + // Purpur start + this.preciseTime = timeOfDay; + this.forceTime = false; -+ } + } + public void setDayTime(double i) { + this.serverLevelData.setDayTime((long) i); + this.forceTime = true; @@ -2422,12 +2481,21 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 + // Purpur start + public boolean isForceTime() { + return this.forceTime; - } ++ } + // Purpur end public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { Iterator iterator = this.customSpawners.iterator(); -@@ -985,9 +1027,9 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -976,7 +1017,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + // Paper start - optimise random block ticking + private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); +- // private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(); // Pufferfish - moved to super ++ private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - moved to super // Purpur - dont break ABI + // Paper end + + private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Pufferfish +@@ -986,9 +1027,9 @@ public class ServerLevel extends Level implements WorldGenLevel { boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); int k = chunkcoordintpair.getMinBlockZ(); @@ -2438,8 +2506,8 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 + //gameprofilerfiller.push("thunder"); // Purpur final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change - if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder -@@ -998,10 +1040,18 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && /*this.random.nextInt(this.spigotConfig.thunderChance) == 0 &&*/ chunk.shouldDoLightning(this.random)) { // Spigot // Paper - disable thunder // Pufferfish - replace random with shouldDoLightning +@@ -999,10 +1040,18 @@ public class ServerLevel extends Level implements WorldGenLevel { boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper if (flag1) { @@ -2460,7 +2528,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 entityhorseskeleton.setAge(0); entityhorseskeleton.setPos((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); this.addFreshEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit -@@ -1018,7 +1068,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1019,7 +1068,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } } @@ -2469,7 +2537,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 if (!this.paperConfig().environment.disableIceAndSnow) { // Paper for (int l = 0; l < randomTickSpeed; ++l) { -@@ -1030,8 +1080,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1031,8 +1080,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper // Paper start - optimise random block ticking @@ -2480,7 +2548,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 if (randomTickSpeed > 0) { LevelChunkSection[] sections = chunk.getSections(); final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this); -@@ -1064,8 +1114,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1065,8 +1114,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper end - optimise random block ticking @@ -2491,7 +2559,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } private void tickIceAndSnow(boolean raining, BlockPos.MutableBlockPos blockposition1, final LevelChunk chunk) { // Paper - optimise chunk ticking -@@ -1118,7 +1168,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1120,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { return holder.is(PoiTypes.LIGHTNING_ROD); }, (blockposition1) -> { return blockposition1.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition1.getX(), blockposition1.getZ()) - 1; @@ -2500,7 +2568,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 return optional.map((blockposition1) -> { return blockposition1.above(1); -@@ -1167,11 +1217,27 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1169,11 +1218,27 @@ public class ServerLevel extends Level implements WorldGenLevel { if (this.canSleepThroughNights()) { if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) { int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); @@ -2529,7 +2597,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); } -@@ -1310,6 +1376,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1312,6 +1377,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private void resetWeatherCycle() { // CraftBukkit start @@ -2537,7 +2605,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - when passing the night // If we stop due to everyone sleeping we should reset the weather duration to some other random value. // Not that everyone ever manages to get the whole server to sleep at the same time.... -@@ -1317,6 +1384,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1319,6 +1385,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setRainTime(0); } // CraftBukkit end @@ -2545,16 +2613,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - when passing the night // CraftBukkit start // If we stop due to everyone sleeping we should reset the weather duration to some other random value. -@@ -1373,7 +1441,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - // Paper end - log detailed entity tick information - ++TimingHistory.entityTicks; // Paper - timings - // Spigot start -- co.aikar.timings.Timing timer; // Paper -+ //co.aikar.timings.Timing timer; // Paper // Purpur - /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below - entity.tickCount++; - timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings -@@ -1384,24 +1452,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1386,24 +1453,24 @@ public class ServerLevel extends Level implements WorldGenLevel { // Spigot end // Paper start- timings final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); @@ -2565,15 +2624,16 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 // Paper end - timings entity.setOldPosAndRot(); - ProfilerFiller gameprofilerfiller = this.getProfiler(); -+ //ProfilerFiller gameprofilerfiller = this.getProfiler(); ++ //ProfilerFiller gameprofilerfiller = this.getProfiler(); // Purpur ++entity.tickCount; - this.getProfiler().push(() -> { + /*this.getProfiler().push(() -> { // Purpur return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); - }); +- }); - gameprofilerfiller.incrementCounter("tickNonPassenger"); -+ gameprofilerfiller.incrementCounter("tickNonPassenger");*/ // Purpur ++ });*/ // Purpur ++ //gameprofilerfiller.incrementCounter("tickNonPassenger"); // Purpur if (isActive) { // Paper - EAR 2 TimingHistory.activatedEntityTicks++; entity.tick(); @@ -2586,7 +2646,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1424,17 +1492,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1426,17 +1493,17 @@ public class ServerLevel extends Level implements WorldGenLevel { if (passenger instanceof Player || this.entityTickList.contains(passenger)) { // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); @@ -2603,13 +2663,14 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 - gameprofilerfiller.push(() -> { + /*gameprofilerfiller.push(() -> { // Purpur return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString(); - }); +- }); - gameprofilerfiller.incrementCounter("tickPassenger"); -+ gameprofilerfiller.incrementCounter("tickPassenger");*/ // Purpur ++ });*/ // Purpur ++ //gameprofilerfiller.incrementCounter("tickPassenger"); // Purpur // Paper start - EAR 2 if (isActive) { passenger.rideTick(); -@@ -1446,7 +1514,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1448,7 +1515,7 @@ public class ServerLevel extends Level implements WorldGenLevel { vehicle.positionRider(passenger); } // Paper end - EAR 2 @@ -2618,7 +2679,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 Iterator iterator = passenger.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1455,7 +1523,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1457,7 +1524,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(passenger, entity2); } @@ -2627,7 +2688,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } } else { passenger.stopRiding(); -@@ -1475,14 +1543,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1477,14 +1544,14 @@ public class ServerLevel extends Level implements WorldGenLevel { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); } @@ -2645,7 +2706,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 // Copied from save() // CraftBukkit start - moved from MinecraftServer.saveChunks -@@ -1494,7 +1562,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1496,7 +1563,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); } // CraftBukkit end @@ -2654,16 +2715,16 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } // Paper end -@@ -1508,7 +1576,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1510,7 +1577,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (!savingDisabled) { - org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit + org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit - try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper -+ //try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper // Purpur ++ //try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper // Purpur // Purpur if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1518,11 +1586,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1520,11 +1587,11 @@ public class ServerLevel extends Level implements WorldGenLevel { progressListener.progressStage(Component.translatable("menu.savingChunks")); } @@ -2678,7 +2739,7 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 // Paper - rewrite chunk system - entity saving moved into ChunkHolder } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system -@@ -2808,7 +2876,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2810,7 +2877,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Spigot Start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message // Paper start @@ -2688,12 +2749,12 @@ index 48402dc3008d1d1d513f0486c0a120719a9fd441..670d7649d25f7704b071d27157173a31 } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d440dc0c3 100644 +index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc75ef9eeb7 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -273,6 +273,10 @@ public class ServerPlayer extends Player { - public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper +@@ -274,6 +274,10 @@ public class ServerPlayer extends Player { public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper + public @Nullable String clientBrandName = null; // Paper - Brand name public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event + public boolean purpurClient = false; // Purpur + private boolean tpsBar = false; // Purpur @@ -2702,7 +2763,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d // Paper start - replace player chunk loader private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -@@ -560,6 +564,9 @@ public class ServerPlayer extends Player { +@@ -561,6 +565,9 @@ public class ServerPlayer extends Player { } } @@ -2712,7 +2773,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d } @Override -@@ -626,6 +633,9 @@ public class ServerPlayer extends Player { +@@ -627,6 +634,9 @@ public class ServerPlayer extends Player { } this.getBukkitEntity().setExtraData(nbt); // CraftBukkit @@ -2722,7 +2783,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d } // CraftBukkit start - World fallback code, either respawn location or global spawn -@@ -754,6 +764,15 @@ public class ServerPlayer extends Player { +@@ -755,6 +765,15 @@ public class ServerPlayer extends Player { this.trackStartFallingPosition(); this.trackEnteredOrExitedLavaOnVehicle(); this.advancements.flushDirty(this); @@ -2738,7 +2799,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d } public void doTick() { -@@ -992,6 +1011,7 @@ public class ServerPlayer extends Player { +@@ -991,6 +1010,7 @@ public class ServerPlayer extends Player { })); Team scoreboardteambase = this.getTeam(); @@ -2746,7 +2807,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { if (scoreboardteambase.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent); -@@ -1098,6 +1118,16 @@ public class ServerPlayer extends Player { +@@ -1097,6 +1117,16 @@ public class ServerPlayer extends Player { if (this.isInvulnerableTo(source)) { return false; } else { @@ -2763,7 +2824,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL); if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { -@@ -1209,7 +1239,7 @@ public class ServerPlayer extends Player { +@@ -1208,7 +1238,7 @@ public class ServerPlayer extends Player { PortalInfo shapedetectorshape = this.findDimensionEntryPoint(worldserver); if (shapedetectorshape != null) { @@ -2772,7 +2833,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d worldserver = shapedetectorshape.world; // CraftBukkit if (worldserver == null) { } else // CraftBukkit - empty to fall through to null to event if (resourcekey == LevelStem.OVERWORLD && worldserver.getTypeKey() == LevelStem.NETHER) { // CraftBukkit -@@ -1232,8 +1262,8 @@ public class ServerPlayer extends Player { +@@ -1231,8 +1261,8 @@ public class ServerPlayer extends Player { worldserver = ((CraftWorld) exit.getWorld()).getHandle(); // CraftBukkit end @@ -2783,7 +2844,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d if (true) { // CraftBukkit this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds -@@ -1244,13 +1274,14 @@ public class ServerPlayer extends Player { +@@ -1243,13 +1273,14 @@ public class ServerPlayer extends Player { playerlist.sendPlayerPermissionLevel(this); worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); @@ -2799,7 +2860,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d this.triggerDimensionChangeTriggers(worldserver1); this.connection.send(new ClientboundPlayerAbilitiesPacket(this.getAbilities())); playerlist.sendLevelInfo(this, worldserver); -@@ -1400,7 +1431,7 @@ public class ServerPlayer extends Player { +@@ -1399,7 +1430,7 @@ public class ServerPlayer extends Player { return entitymonster.isPreventingPlayerRest(this); }); @@ -2808,7 +2869,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1440,7 +1471,19 @@ public class ServerPlayer extends Player { +@@ -1439,7 +1470,19 @@ public class ServerPlayer extends Player { }); if (!this.serverLevel().canSleepThroughNights()) { @@ -2829,7 +2890,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d } ((ServerLevel) this.level()).updateSleepingPlayerList(); -@@ -1537,6 +1580,7 @@ public class ServerPlayer extends Player { +@@ -1536,6 +1579,7 @@ public class ServerPlayer extends Player { @Override public void openTextEdit(SignBlockEntity sign, boolean front) { @@ -2837,7 +2898,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); } -@@ -1782,6 +1826,26 @@ public class ServerPlayer extends Player { +@@ -1781,6 +1825,26 @@ public class ServerPlayer extends Player { this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -2864,7 +2925,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2098,8 +2162,68 @@ public class ServerPlayer extends Player { +@@ -2102,8 +2166,68 @@ public class ServerPlayer extends Player { public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -2933,7 +2994,7 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d public ServerStatsCounter getStats() { return this.stats; } -@@ -2647,4 +2771,50 @@ public class ServerPlayer extends Player { +@@ -2654,4 +2778,50 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -2985,10 +3046,10 @@ index d4aec99cac3f83d764e21946cc904c00e084704e..99cf8ce63316e127a5ee84cdd96df80d + // Purpur end } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17160db723 100644 +index 3706e94108f68a16fea63e734f3e3b6871dcb0b8..6f8d990cbc15c3fa11acdf59fc1ec1fa583f60ec 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -398,6 +398,7 @@ public class ServerPlayerGameMode { +@@ -397,6 +397,7 @@ public class ServerPlayerGameMode { } else {capturedBlockEntity = true;} // Paper end return false; } @@ -2996,7 +3057,7 @@ index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17 } // CraftBukkit end -@@ -428,7 +429,7 @@ public class ServerPlayerGameMode { +@@ -427,7 +428,7 @@ public class ServerPlayerGameMode { ItemStack mainHandStack = null; // Paper boolean isCorrectTool = false; // Paper @@ -3005,7 +3066,7 @@ index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17 // return true; // CraftBukkit } else { ItemStack itemstack = this.player.getMainHandItem(); -@@ -517,6 +518,7 @@ public class ServerPlayerGameMode { +@@ -516,6 +517,7 @@ public class ServerPlayerGameMode { public InteractionHand interactHand; public ItemStack interactItemStack; public InteractionResult useItemOn(ServerPlayer player, Level world, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) { @@ -3013,7 +3074,7 @@ index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17 BlockPos blockposition = hitResult.getBlockPos(); BlockState iblockdata = world.getBlockState(blockposition); InteractionResult enuminteractionresult = InteractionResult.PASS; -@@ -578,7 +580,7 @@ public class ServerPlayerGameMode { +@@ -579,7 +581,7 @@ public class ServerPlayerGameMode { boolean flag1 = player.isSecondaryUseActive() && flag; ItemStack itemstack1 = stack.copy(); @@ -3022,7 +3083,7 @@ index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17 enuminteractionresult = iblockdata.use(world, player, hand, hitResult); if (enuminteractionresult.consumesAction()) { -@@ -619,4 +621,18 @@ public class ServerPlayerGameMode { +@@ -620,4 +622,18 @@ public class ServerPlayerGameMode { public void setLevel(ServerLevel world) { this.level = world; } @@ -3042,10 +3103,10 @@ index b2c2bd5ec0afd479973f7237a5c610f21231c505..3250c21eded7872336d349a7a93c2c17 + // Purpur end } diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 877498729c66de9aa6a27c9148f7494d7895615c..acd7468ee3c86d3456e96e4ec3d7e6a4c612e89d 100644 +index 50ed7cfe1ecef6d075ba484804827cec83ba2bf2..54f9cd80ac925aa95ff4fdb4d52cbcc2b04263a5 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -@@ -297,6 +297,7 @@ public class WorldGenRegion implements WorldGenLevel { +@@ -318,6 +318,7 @@ public class WorldGenRegion implements WorldGenLevel { return true; } else { // Paper start @@ -3054,10 +3115,10 @@ index 877498729c66de9aa6a27c9148f7494d7895615c..acd7468ee3c86d3456e96e4ec3d7e6a4 Util.logAndPauseIfInIde("Detected setBlock in a far chunk [" + i + ", " + j + "], pos: " + pos + ", status: " + this.generatingStatus + (this.currentlyGenerating == null ? "" : ", currently generating: " + (String) this.currentlyGenerating.get())); hasSetFarWarned = true; diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd74c4cb5a 100644 +index 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fef3456f09 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -51,11 +51,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -51,10 +51,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private long keepAliveTime = Util.getMillis(); // Paper private boolean keepAlivePending; private long keepAliveChallenge; @@ -3065,13 +3126,12 @@ index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd private int latency; private volatile boolean suspendFlushingOnServerThread = false; private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit - private @Nullable String clientBrandName = null; // Paper - Brand name protected static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support + protected static final ResourceLocation PURPUR_CLIENT = new ResourceLocation("purpur", "client"); // Purpur public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -91,6 +93,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -90,6 +92,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { @@ -3088,7 +3148,7 @@ index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { int i = (int) (Util.getMillis() - this.keepAliveTime); -@@ -138,6 +150,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -137,6 +149,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex); this.disconnect("Invalid payload REGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } @@ -3099,10 +3159,10 @@ index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd + } catch (Exception ignore) { + } + // Purpur end - } else if (identifier.equals(CUSTOM_UNREGISTER)) { + } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { try { String channels = payload.toString(com.google.common.base.Charsets.UTF_8); -@@ -198,12 +217,27 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -190,12 +209,27 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } protected void keepConnectionAlive() { @@ -3131,7 +3191,7 @@ index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd if (this.keepAlivePending) { if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info -@@ -219,7 +253,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -211,7 +245,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } // Paper end @@ -3141,7 +3201,7 @@ index 231150bac0ae61e9722c2cdfd70d6f7d254681e4..6f6228edfe77668552a40a814ab3cebd public void suspendFlushing() { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d6593d0fff0e 100644 +index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f019072006a3ef31f 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -323,6 +323,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -3195,11 +3255,14 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 return; } -@@ -1126,10 +1149,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1127,10 +1150,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl int maxBookPageSize = io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.pageMax; double multiplier = Math.max(0.3D, Math.min(1D, io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier)); long byteAllowed = maxBookPageSize; -+ ItemStack itemstack = this.player.getInventory().getItem(packet.getSlot()); // Purpur ++ // Purpur start ++ int slot = packet.getSlot(); ++ ItemStack itemstack = Inventory.isHotbarSlot(slot) || slot == Inventory.SLOT_OFFHAND ? this.player.getInventory().getItem(slot) : ItemStack.EMPTY; ++ // Purpur end for (String testString : pageList) { int byteLength = testString.getBytes(java.nio.charset.StandardCharsets.UTF_8).length; if (byteLength > 256 * 4) { @@ -3208,7 +3271,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1153,6 +1178,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1154,6 +1182,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size()); @@ -3216,7 +3279,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1206,13 +1232,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1207,13 +1236,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl itemstack1.setTag(nbttagcompound.copy()); } @@ -3236,7 +3299,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 this.updateBookPages(pages, (s) -> { return Component.Serializer.toJson(Component.literal(s)); -@@ -1224,10 +1253,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1225,10 +1257,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void updateBookPages(List list, UnaryOperator unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit ListTag nbttaglist = new ListTag(); @@ -3252,7 +3315,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 Objects.requireNonNull(nbttaglist); stream.forEach(nbttaglist::add); -@@ -1237,11 +1269,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1238,11 +1273,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl for (int j = list.size(); i < j; ++i) { FilteredText filteredtext = (FilteredText) list.get(i); @@ -3266,8 +3329,8 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 } } -@@ -1254,6 +1286,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(player, slot, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) +@@ -1255,6 +1290,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(this.player, slot, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) } + // Purpur start @@ -3283,7 +3346,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 @Override public void handleEntityTagQuery(ServerboundEntityTagQuery packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -@@ -1283,8 +1325,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1284,8 +1329,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -3301,7 +3364,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 } else { ServerLevel worldserver = this.player.serverLevel(); -@@ -1467,7 +1517,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1468,7 +1521,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!event.isAllowed()) { flag2 = true; // Paper - diff on change, this should be moved wrongly if (event.getLogWarning()) @@ -3310,7 +3373,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 } // Paper end } -@@ -1529,6 +1579,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1530,6 +1583,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -3319,7 +3382,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 // Skip the first time we do this if (from.getX() != Double.MAX_VALUE) { Location oldTo = to.clone(); -@@ -1567,6 +1619,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1568,6 +1623,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetFallDistance(); } @@ -3333,7 +3396,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 this.player.checkMovementStatistics(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5); this.lastGoodX = this.player.getX(); this.lastGoodY = this.player.getY(); -@@ -1618,6 +1677,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1619,6 +1681,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return false; } // Paper end - optimise out extra getCubes @@ -3347,7 +3410,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 private boolean isPlayerCollidingWithAnythingNew(LevelReader world, AABB box, double newX, double newY, double newZ) { AABB axisalignedbb1 = this.player.getBoundingBox().move(newX - this.player.getX(), newY - this.player.getY(), newZ - this.player.getZ()); Iterable iterable = world.getCollisions(this.player, axisalignedbb1.deflate(9.999999747378752E-6D)); -@@ -1963,6 +2029,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1964,6 +2033,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean cancelled; if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) { @@ -3355,7 +3418,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2280,7 +2347,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2281,7 +2351,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl do { instant1 = (Instant) this.lastChatTimeStamp.get(); if (timestamp.isBefore(instant1)) { @@ -3364,7 +3427,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 } } while (!this.lastChatTimeStamp.compareAndSet(instant1, timestamp)); -@@ -2390,7 +2457,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2391,7 +2461,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleCommand(String s) { // Paper - private -> public org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher @@ -3373,7 +3436,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2400,7 +2467,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2401,7 +2471,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -3382,7 +3445,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 return; } -@@ -2413,7 +2480,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2414,7 +2484,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { @@ -3391,7 +3454,7 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 } } // CraftBukkit end -@@ -2700,6 +2767,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2701,6 +2771,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = entity.getBoundingBox(); if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < ServerGamePacketListenerImpl.MAX_INTERACTION_DISTANCE) { @@ -3399,16 +3462,16 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); -@@ -2713,6 +2781,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2714,6 +2785,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - cserver.getPluginManager().callEvent(event); + ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); + player.processClick(enumhand); // Purpur + // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { entity.getEntityData().resendPossiblyDesyncedEntity(player); // Paper - The entire mob gets deleted, so resend it. -@@ -3293,6 +3363,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3299,6 +3372,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } } @@ -3422,10 +3485,10 @@ index 501cb7450cd28ca487c1522ada4a571e74d3258c..e001787e40cc0a843e65b36582e9d659 boolean flag1 = packet.getSlotNum() >= 1 && packet.getSlotNum() <= 45; boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty(); diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 0c57a06b785dc024ee05ac1291a56f08624e1e56..b875f4af9dcb45bcad0ee59a958442ba673268fe 100644 +index 1c4f272219e68373eaae93fc5ea9af7d8f3fd6f9..3dcccca8ede9b203c24ba29b2020a583297b895c 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -142,6 +142,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -141,6 +141,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, return false; } @@ -3434,7 +3497,7 @@ index 0c57a06b785dc024ee05ac1291a56f08624e1e56..b875f4af9dcb45bcad0ee59a958442ba for (int i = 0, len = in.length(); i < len; ++i) { char c = in.charAt(i); -@@ -297,7 +299,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -296,7 +298,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!"); ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot } else { @@ -3444,7 +3507,7 @@ index 0c57a06b785dc024ee05ac1291a56f08624e1e56..b875f4af9dcb45bcad0ee59a958442ba } } catch (AuthenticationUnavailableException authenticationunavailableexception) { diff --git a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java -index 2c13147bc063a09bb7907d6f90c3a1e811a09eb1..3edb0c392cec7fdabebad81da1a8b06a700fbfca 100644 +index e5006e7672ba79ed4bcf2c4173c5a9ed4c68395b..6338c52e0082d36d3b80038fdb44abf2772adb30 100644 --- a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java @@ -153,6 +153,7 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene @@ -3476,10 +3539,10 @@ index 9ddbfcf80d9a381dace78a62880f85a4d767e0eb..7383c7d3820dce06108eaafd236a7c6c } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3285d219e 100644 +index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a4584de7a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -467,6 +467,7 @@ public abstract class PlayerList { +@@ -488,6 +488,7 @@ public abstract class PlayerList { scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end @@ -3487,7 +3550,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 // CraftBukkit - Moved from above, added world PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } -@@ -580,6 +581,7 @@ public abstract class PlayerList { +@@ -601,6 +602,7 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) { // Paper end @@ -3495,7 +3558,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -734,7 +736,7 @@ public abstract class PlayerList { +@@ -755,7 +757,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; @@ -3504,7 +3567,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -1039,6 +1041,20 @@ public abstract class PlayerList { +@@ -1060,6 +1062,20 @@ public abstract class PlayerList { } // CraftBukkit end @@ -3525,7 +3588,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -1142,6 +1158,7 @@ public abstract class PlayerList { +@@ -1163,6 +1179,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + permissionLevel); } @@ -3533,7 +3596,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 player.connection.send(new ClientboundEntityEventPacket(player, b0)); } -@@ -1150,6 +1167,27 @@ public abstract class PlayerList { +@@ -1171,6 +1188,27 @@ public abstract class PlayerList { player.getBukkitEntity().recalculatePermissions(); // CraftBukkit this.server.getCommands().sendCommands(player); } // Paper @@ -3561,7 +3624,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 } public boolean isWhiteListed(GameProfile profile) { -@@ -1211,7 +1249,7 @@ public abstract class PlayerList { +@@ -1232,7 +1270,7 @@ public abstract class PlayerList { public void saveAll(int interval) { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main @@ -3570,7 +3633,7 @@ index 48d1444fbad1c57738807d0128b94160a5a17a4d..5c38df8170033dbfee267520991a3cc3 int numSaved = 0; long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1222,7 +1260,7 @@ public abstract class PlayerList { +@@ -1243,7 +1281,7 @@ public abstract class PlayerList { } // Paper end } @@ -3797,34 +3860,6 @@ index 2e6e8eac987c4ef6b2dcd3de592d8a51d2b29792..863343a87fe34d72f04af89d75268b47 } }; } -diff --git a/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java b/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java -index 48e7211e01691a677c52cf1f5982b0c179eaf83b..729ebd1b2433327de243d0168289e180a841f47c 100644 ---- a/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java -+++ b/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java -@@ -2,16 +2,23 @@ package net.minecraft.util.profiling.metrics.profiling; - - import net.minecraft.util.profiling.ProfilerFiller; - -+@Deprecated(forRemoval = true) - public interface MetricsRecorder { -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - void end(); - -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - void cancel(); - -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - void startTick(); - -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - boolean isRecording(); - -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - ProfilerFiller getProfiler(); - -+ @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur - void endTick(); - } diff --git a/src/main/java/net/minecraft/world/damagesource/CombatRules.java b/src/main/java/net/minecraft/world/damagesource/CombatRules.java index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2a3a08b88 100644 --- a/src/main/java/net/minecraft/world/damagesource/CombatRules.java @@ -4152,10 +4187,10 @@ index 1f9e0c139988c4c44a26552881647d36965aa4fa..b8d612d22aca74a08b53393c0723a2ae @Override diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d23cb47ec 100644 +index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48082750ef 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -155,7 +155,7 @@ import org.bukkit.plugin.PluginManager; +@@ -156,7 +156,7 @@ import org.bukkit.plugin.PluginManager; // CraftBukkit end public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -4164,16 +4199,16 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d // CraftBukkit start private static final int CURRENT_LEVEL = 2; public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation -@@ -333,7 +333,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -334,7 +334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public double xOld; public double yOld; public double zOld; - private float maxUpStep; + public float maxUpStep; // Purpur - private -> public public boolean noPhysics; - protected final RandomSource random; + public final RandomSource random; public int tickCount; -@@ -375,7 +375,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -376,7 +376,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { private final Set tags; private final double[] pistonDeltas; private long pistonDeltasGameTime; @@ -4182,7 +4217,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; -@@ -417,6 +417,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -418,6 +418,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean collidingWithWorldBorder; // Paper public boolean fixedPose = false; // Paper @@ -4190,7 +4225,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -491,6 +492,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -493,6 +494,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return false; } @@ -4216,7 +4251,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d public final boolean hardCollides() { return this.hardCollides; } -@@ -541,7 +561,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -575,7 +595,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -4225,7 +4260,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -789,7 +809,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -823,7 +843,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // CraftBukkit end public void baseTick() { @@ -4234,7 +4269,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Update last hurt when ticking this.feetBlockState = null; if (this.isPassenger() && this.getVehicle().isRemoved()) { -@@ -850,7 +870,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -884,7 +904,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.firstTick = false; @@ -4243,7 +4278,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } public void setSharedFlagOnFire(boolean onFire) { -@@ -859,10 +879,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -893,10 +913,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public void checkBelowWorld() { // Paper start - Configurable nether ceiling damage @@ -4256,7 +4291,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d this.onBelowWorld(); } -@@ -1069,7 +1090,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1103,7 +1124,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } @@ -4265,7 +4300,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { movement = movement.multiply(this.stuckSpeedMultiplier); this.stuckSpeedMultiplier = Vec3.ZERO; -@@ -1078,7 +1099,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1112,7 +1133,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // Paper start - ignore movement changes while inactive. if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof net.minecraft.world.entity.vehicle.AbstractMinecart) && movement == getDeltaMovement() && movementType == MoverType.SELF) { setDeltaMovement(Vec3.ZERO); @@ -4274,7 +4309,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d return; } // Paper end -@@ -1099,8 +1120,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1133,8 +1154,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.setPos(this.getX() + vec3d1.x, this.getY() + vec3d1.y, this.getZ() + vec3d1.z); } @@ -4285,18 +4320,16 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d boolean flag = !Mth.equal(movement.x, vec3d1.x); boolean flag1 = !Mth.equal(movement.z, vec3d1.z); -@@ -1118,8 +1139,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - BlockState iblockdata = this.level().getBlockState(blockposition); +@@ -1153,7 +1174,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.checkFallDamage(vec3d1.y, this.onGround(), iblockdata, blockposition); -- if (this.isRemoved()) { + if (this.isRemoved()) { - this.level().getProfiler().pop(); -+ if (false && this.isRemoved()) { // Purpur + //this.level().getProfiler().pop(); // Purpur } else { if (this.horizontalCollision) { Vec3 vec3d2 = this.getDeltaMovement(); -@@ -1257,7 +1278,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1291,7 +1312,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.setRemainingFireTicks(-this.getFireImmuneTicks()); } @@ -4305,7 +4338,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } } // Paper start - detailed watchdog information -@@ -1759,7 +1780,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1793,7 +1814,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean fireImmune() { @@ -4314,7 +4347,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { -@@ -1832,7 +1853,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1866,7 +1887,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return this.isInWater() || flag; } @@ -4323,7 +4356,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d Entity entity = this.getVehicle(); if (entity instanceof Boat) { -@@ -2433,6 +2454,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2467,6 +2488,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { nbt.putBoolean("Paper.FreezeLock", true); } // Paper end @@ -4335,19 +4368,20 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d return nbt; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2601,6 +2627,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2614,7 +2640,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { freezeLocked = nbt.getBoolean("Paper.FreezeLock"); } // Paper end +- + // Purpur start + if (nbt.contains("Purpur.FireImmune")) { + immuneToFire = nbt.getBoolean("Purpur.FireImmune"); + } + // Purpur end - } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -2945,6 +2976,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); +@@ -2984,6 +3014,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.passengers = ImmutableList.copyOf(list); } @@ -4361,7 +4395,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -2985,6 +3023,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3024,6 +3061,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return false; } // Spigot end @@ -4374,7 +4408,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -3064,12 +3108,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3103,12 +3146,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return Vec3.directionFromRotation(this.getRotationVector()); } @@ -4391,7 +4425,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } this.isInsidePortal = true; -@@ -3087,7 +3134,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3126,7 +3172,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { ServerLevel worldserver1 = minecraftserver.getLevel(resourcekey); if (true && !this.isPassenger() && this.portalTime++ >= i) { // CraftBukkit @@ -4400,7 +4434,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d this.portalTime = i; // Paper start io.papermc.paper.event.entity.EntityPortalReadyEvent event = new io.papermc.paper.event.entity.EntityPortalReadyEvent(this.getBukkitEntity(), worldserver1 == null ? null : worldserver1.getWorld(), org.bukkit.PortalType.NETHER); -@@ -3105,7 +3152,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3144,7 +3190,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } // Paper // CraftBukkit end @@ -4409,16 +4443,15 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } this.isInsidePortal = false; -@@ -3120,7 +3167,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3159,6 +3205,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.processPortalCooldown(); -- this.tickEndPortal(); // Paper - make end portalling safe -+ if (this.level().purpurConfig.endPortalSafeTeleporting) this.tickEndPortal(); // Paper - make end portalling safe // Purpur ++ if (this.level().purpurConfig.endPortalSafeTeleporting) // Purpur + this.tickEndPortal(); // Paper - make end portalling safe } } - -@@ -3310,7 +3357,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3349,7 +3396,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public int getMaxAirSupply() { @@ -4427,7 +4460,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } public int getAirSupply() { -@@ -3580,14 +3627,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3619,14 +3666,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } // Paper end if (this.level() instanceof ServerLevel && !this.isRemoved()) { @@ -4444,7 +4477,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d PortalInfo shapedetectorshape = (location == null) ? this.findDimensionEntryPoint(worldserver) : new PortalInfo(new Vec3(location.x(), location.y(), location.z()), Vec3.ZERO, this.yRot, this.xRot, worldserver, null); // CraftBukkit if (shapedetectorshape == null) { -@@ -3626,7 +3673,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3665,7 +3712,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.unRide(); // CraftBukkit end @@ -4453,7 +4486,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d // Paper start - Change lead drop timing to prevent dupe if (this instanceof Mob) { ((Mob) this).dropLeash(true, true); // Paper drop lead -@@ -3649,10 +3696,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3688,10 +3735,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.removeAfterChangingDimensions(); @@ -4466,7 +4499,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d return entity; } } else { -@@ -3772,7 +3819,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3811,7 +3858,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean canChangeDimensions() { @@ -4475,7 +4508,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d } public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { -@@ -4065,6 +4112,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4104,6 +4151,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return SlotAccess.NULL; } @@ -4496,7 +4529,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d @Override public void sendSystemMessage(Component message) {} -@@ -4334,6 +4395,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4373,6 +4434,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.yRotO = this.getYRot(); } @@ -4509,7 +4542,7 @@ index b2b1e34af626fad2586dcc12596c761560d2dfad..1ca91631b03c9690b4f661ecfb4d500d public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { if (false && this.touchingUnloadedChunk()) { // Pufferfish - cost of a lookup here is the same cost as below, so skip return false; -@@ -4899,4 +4966,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4938,4 +5005,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end @@ -4628,7 +4661,7 @@ index 2561e74ffdf595a9b6ae13dcd738662c772db442..5930e45bae5aa86b3cedb811c4c9bb92 } diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index eca634792d2a7cc649675e3394e84dbaf1453905..724bf857bf1b89cb0947b8a82e0ce09a0bec0335 100644 +index 6dac7cd4c9abfbde299f5d279acc2739195fc312..2bcbfe5516e30a150aa133cf8c1561b784443778 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java @@ -313,7 +313,7 @@ public class ExperienceOrb extends Entity { @@ -4712,7 +4745,7 @@ index 1bb8b6e91c44cd13411d96d749fa64835c75a267..b18cbe85330e26de6f6cbfcc3d51a741 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a0644671e 100644 +index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b26bfd5947 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -218,9 +218,9 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -4734,7 +4767,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a public int expToDrop; + public float safeFallDistance = 3.0F; // Purpur public boolean forceDrops; - public ArrayList drops = new ArrayList(); + public ArrayList drops = new ArrayList<>(); // Paper public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; @@ -262,6 +263,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @@ -4853,7 +4886,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } // CraftBukkit start -@@ -1027,9 +1040,31 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1027,9 +1040,29 @@ public abstract class LivingEntity extends Entity implements Attackable { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); EntityType entitytypes = entity.getType(); @@ -4872,9 +4905,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a + else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) { + d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent; + } -+ // Purpur end + -+ // Purpur start + if (entity instanceof LivingEntity entityliving) { + if (entityliving.hasEffect(MobEffects.BLINDNESS)) { + int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier(); @@ -4887,7 +4918,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } return d0; -@@ -1089,6 +1124,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1089,6 +1122,7 @@ public abstract class LivingEntity extends Entity implements Attackable { for (flag = false; iterator.hasNext(); flag = true) { // CraftBukkit start MobEffectInstance effect = (MobEffectInstance) iterator.next(); @@ -4895,7 +4926,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); if (event.isCancelled()) { continue; -@@ -1503,13 +1539,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1511,13 +1545,13 @@ public abstract class LivingEntity extends Entity implements Attackable { if (entity1 instanceof net.minecraft.world.entity.player.Player) { net.minecraft.world.entity.player.Player entityhuman = (net.minecraft.world.entity.player.Player) entity1; @@ -4911,7 +4942,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a LivingEntity entityliving2 = entitywolf.getOwner(); if (entityliving2 instanceof net.minecraft.world.entity.player.Player) { -@@ -1620,6 +1656,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1625,6 +1659,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -4930,7 +4961,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot); event.setCancelled(itemstack == null); -@@ -1787,7 +1835,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1792,7 +1838,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = false; if (this.dead && adversary instanceof WitherBoss) { // Paper @@ -4939,7 +4970,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1833,6 +1881,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1838,6 +1884,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropEquipment(); // CraftBukkit - from below if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { @@ -4947,7 +4978,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a this.dropFromLootTable(source, flag); // Paper start final boolean prev = this.clearEquipmentSlots; -@@ -1841,6 +1890,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1846,6 +1893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper end this.dropCustomDeathLoot(source, i, flag); this.clearEquipmentSlots = prev; // Paper @@ -4955,7 +4986,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops, () -> { -@@ -2088,7 +2138,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2093,7 +2141,7 @@ public abstract class LivingEntity extends Entity implements Attackable { MobEffectInstance mobeffect = this.getEffect(MobEffects.JUMP); float f2 = mobeffect == null ? 0.0F : (float) (mobeffect.getAmplifier() + 1); @@ -4964,28 +4995,28 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } } -@@ -2311,6 +2361,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2316,6 +2364,20 @@ public abstract class LivingEntity extends Entity implements Attackable { } } -+ // Purpur start -+ if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damagesource.getEntity().level().purpurConfig.creativeOnePunch) { -+ if (player.isCreative()) { -+ double attackDamage = 0; -+ for (AttributeModifier modifier : player.getMainHandItem().getAttributeModifiers(EquipmentSlot.MAINHAND).get(Attributes.ATTACK_DAMAGE)) { -+ attackDamage += modifier.getAmount(); -+ } -+ if (attackDamage == 0) { -+ this.setHealth(0); -+ } -+ } -+ } -+ // Purpur end ++ // Purpur start ++ if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damagesource.getEntity().level().purpurConfig.creativeOnePunch) { ++ if (player.isCreative()) { ++ double attackDamage = 0; ++ for (AttributeModifier modifier : player.getMainHandItem().getAttributeModifiers(EquipmentSlot.MAINHAND).get(Attributes.ATTACK_DAMAGE)) { ++ attackDamage += modifier.getAmount(); ++ } ++ if (attackDamage == 0) { ++ this.setHealth(0); ++ } ++ } ++ } ++ // Purpur end + if (f > 0 || !human) { if (human) { // PAIL: Be sure to drag all this code from the EntityHuman subclass each update. -@@ -2531,7 +2595,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2536,7 +2598,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override protected void onBelowWorld() { @@ -4994,7 +5025,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } protected void updateSwingTime() { -@@ -2725,7 +2789,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2730,7 +2792,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected long lastJumpTime = 0L; // Paper @@ -5003,7 +5034,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a Vec3 vec3d = this.getDeltaMovement(); // Paper start long time = System.nanoTime(); -@@ -2877,6 +2941,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2882,6 +2944,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (f3 > 0.0F) { this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F); @@ -5011,7 +5042,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a this.hurt(this.damageSources().flyIntoWall(), f3); } } -@@ -3098,10 +3163,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3103,10 +3166,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.run += (f3 - this.run) * 0.3F; @@ -5025,7 +5056,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a // Paper start - stop large pitch and yaw changes from crashing the server this.yRotO += Math.round((this.getYRot() - this.yRotO) / 360.0F) * 360.0F; -@@ -3113,7 +3178,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3118,7 +3181,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.yHeadRotO += Math.round((this.yHeadRot - this.yHeadRotO) / 360.0F) * 360.0F; // Paper end @@ -5034,7 +5065,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a this.animStep += f2; if (this.isFallFlying()) { ++this.fallFlyTicks; -@@ -3396,19 +3461,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3408,19 +3471,19 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.setDeltaMovement(d0, d1, d2); @@ -5059,7 +5090,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a if (this.jumping && this.isAffectedByFluids()) { double d3; -@@ -3435,8 +3500,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3447,8 +3510,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.noJumpDelay = 0; } @@ -5070,7 +5101,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a this.xxa *= 0.98F; this.zza *= 0.98F; this.updateFallFlying(); -@@ -3463,8 +3528,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3475,8 +3538,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.travel(vec3d1); } @@ -5081,7 +5112,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a if (!this.level().isClientSide && !this.isDeadOrDying() && !freezeLocked) { // Paper - Freeze Tick Lock API int i = this.getTicksFrozen(); -@@ -3481,18 +3546,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3493,18 +3556,20 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurt(this.damageSources().freeze(), 1.0F); } @@ -5107,7 +5138,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO); Location to = new Location (this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); io.papermc.paper.event.entity.EntityMoveEvent event = new io.papermc.paper.event.entity.EntityMoveEvent(this.getBukkitLivingEntity(), from, to.clone()); -@@ -3502,12 +3569,48 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3514,12 +3579,48 @@ public abstract class LivingEntity extends Entity implements Attackable { this.absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch()); } } @@ -5156,7 +5187,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a } public boolean isSensitiveToWater() { -@@ -3528,7 +3631,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3540,7 +3641,16 @@ public abstract class LivingEntity extends Entity implements Attackable { int j = i / 10; if (j % 2 == 0) { @@ -5175,7 +5206,7 @@ index 4a8a0432366f16f4a7028293bb4d33770f215ec6..df869a765ab48b4352c6355d7648754a }); } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b1182d7dce4 100644 +index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c57a05fd4 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -65,6 +65,7 @@ import net.minecraft.world.item.ProjectileWeaponItem; @@ -5291,7 +5322,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 } protected Vec3i getPickupReach() { -@@ -908,46 +937,46 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -906,46 +935,46 @@ public abstract class Mob extends LivingEntity implements Targeting { return; } // Paper end @@ -5317,7 +5348,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 + //this.level().getProfiler().pop(); // Purpur } else { - this.level().getProfiler().push("targetSelector"); -+ //this.level().getProfiler().push("targetSelector"); // Purpur ++ //this.level().getProfiler().push("targetSelector"); if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); - this.level().getProfiler().pop(); @@ -5358,7 +5389,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 this.sendDebugPackets(); } -@@ -1176,6 +1205,12 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1174,6 +1203,12 @@ public abstract class Mob extends LivingEntity implements Targeting { } @@ -5371,7 +5402,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 @Nullable public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) { switch (equipmentSlot) { -@@ -1270,7 +1305,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1268,7 +1303,7 @@ public abstract class Mob extends LivingEntity implements Targeting { RandomSource randomsource = world.getRandom(); this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.MULTIPLY_BASE)); @@ -5380,7 +5411,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 this.setLeftHanded(true); } else { this.setLeftHanded(false); -@@ -1318,6 +1353,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1316,6 +1351,7 @@ public abstract class Mob extends LivingEntity implements Targeting { if (!this.isAlive()) { return InteractionResult.PASS; } else if (this.getLeashHolder() == player) { @@ -5388,7 +5419,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 // CraftBukkit start - fire PlayerUnleashEntityEvent // Paper start - drop leash variable org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild); -@@ -1391,7 +1427,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1389,7 +1425,7 @@ public abstract class Mob extends LivingEntity implements Targeting { protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} protected InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -5397,7 +5428,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 } public boolean isWithinRestriction() { -@@ -1702,6 +1738,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1700,6 +1736,7 @@ public abstract class Mob extends LivingEntity implements Targeting { this.setLastHurtMob(target); } @@ -5405,7 +5436,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 return flag; } -@@ -1718,17 +1755,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1716,17 +1753,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } public boolean isSunBurnTick() { @@ -5424,7 +5455,7 @@ index 4cb836dfa7cbd2e634d4a3a567da0305aac0da4d..d35afa8f8648bbcbfc044323bcda1b11 } @Override -@@ -1775,4 +1802,56 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1773,4 +1800,56 @@ public abstract class Mob extends LivingEntity implements Targeting { return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg); } @@ -5501,13 +5532,13 @@ index 5e8cc5cfac8888628c6d513148f41be09ca65a2c..a089fc61ec09be6b7490375489178dc6 boolean readyForShearing(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index d8bb16f74fdd8d5a50bd384249e0eac9640cd498..a2ec4ad05547a7c3fe9349d6e724d234fb1b7a82 100644 +index 3087f8359b098682a345399c85395de8a15b6eed..6b0855cffb901dbc7dcc5fd44506275206bc9a2d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -24,14 +24,21 @@ public class AttributeMap { private final Set dirtyAttributes = Sets.newHashSet(); private final AttributeSupplier supplier; - private final java.util.function.Function createdInstance; // Pufferfish + private final java.util.function.Function createInstance; // Pufferfish + private final net.minecraft.world.entity.LivingEntity entity; // Purpur public AttributeMap(AttributeSupplier defaultAttributes) { @@ -5518,7 +5549,7 @@ index d8bb16f74fdd8d5a50bd384249e0eac9640cd498..a2ec4ad05547a7c3fe9349d6e724d234 + this.entity = entity; + // Purpur end this.supplier = defaultAttributes; - this.createdInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish + this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish } private void onAttributeModified(AttributeInstance instance) { @@ -6358,7 +6389,7 @@ index 2249fc6dd98afb8d52623b5864955fdd3b3fc042..2ccfaab0a02cf5ff9779e250fb79a75a double d = this.wantedX - this.fish.getX(); double e = this.wantedY - this.fish.getY(); diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java -index be105a4460e9bf2ef4b72a307fa31291c37d5e0e..2e268aa614522b40fbffabce4017b228db5bcba8 100644 +index a836bfd2ea8af8098a20fb37ca25a5a613226f67..a434d91b8dfff30cff81df964ea8149caa8cb604 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Animal.java +++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java @@ -42,6 +42,7 @@ public abstract class Animal extends AgeableMob { @@ -6375,10 +6406,10 @@ index be105a4460e9bf2ef4b72a307fa31291c37d5e0e..2e268aa614522b40fbffabce4017b228 - if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { + if (!this.level().isClientSide && i == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur + final ItemStack breedCopy = itemstack.copy(); // Paper this.usePlayerItem(player, hand, itemstack); - this.setInLove(player); - return InteractionResult.SUCCESS; -@@ -231,12 +232,20 @@ public abstract class Animal extends AgeableMob { + this.setInLove(player, breedCopy); // Paper +@@ -240,12 +241,20 @@ public abstract class Animal extends AgeableMob { AgeableMob entityageable = this.getBreedOffspring(world, other); if (entityageable != null) { @@ -6402,7 +6433,7 @@ index be105a4460e9bf2ef4b72a307fa31291c37d5e0e..2e268aa614522b40fbffabce4017b228 int experience = this.getRandom().nextInt(7) + 1; EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, other, breeder, this.breedItem, experience); if (entityBreedEvent.isCancelled()) { -@@ -264,8 +273,10 @@ public abstract class Animal extends AgeableMob { +@@ -273,8 +282,10 @@ public abstract class Animal extends AgeableMob { entityplayer.awardStat(Stats.ANIMALS_BRED); CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable); } // Paper @@ -6416,7 +6447,7 @@ index be105a4460e9bf2ef4b72a307fa31291c37d5e0e..2e268aa614522b40fbffabce4017b228 entityanimal.resetLove(); worldserver.broadcastEntityEvent(this, (byte) 18); diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 55026e1731e41b4e3e4c6a8fef5d96a32051a556..6c04c8e7776b2830ac368229da834532e8ce163e 100644 +index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64bc7fffd0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java @@ -43,6 +43,7 @@ import net.minecraft.world.entity.EntityType; @@ -7027,7 +7058,7 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..6d00b3cd4a9cb0fc8a9e9c27f37429a2 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index 8448c5d778998390cf2b683f36e4e18ca7ffdc34..4c9c07d470357c35bd5ba3c21437a2c44c52811e 100644 +index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd4df32a47 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java @@ -82,19 +82,104 @@ public class Dolphin extends WaterAnimal { @@ -7189,7 +7220,7 @@ index 8448c5d778998390cf2b683f36e4e18ca7ffdc34..4c9c07d470357c35bd5ba3c21437a2c4 } diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index 31d4683f5e158f076ce9a416b7003478af293688..39c982f83a8b5b0787fc8dd48a0c11e5ad452bb0 100644 +index 9e2af80c6a87f5849710266149cbca8cabfad4f8..075554f28dab5809d0f2d346bad40efc16b38371 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java @@ -36,6 +36,7 @@ import net.minecraft.util.RandomSource; @@ -7506,7 +7537,7 @@ index f383928fc5b331ddf128bdcb6a23010d8fe088d3..64aba511e615983988cdb6a0fd45b7d9 } } diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java -index 52cc265f1663d648b6bfd03f2ac3e191b1c16d44..59ef1070c6c1ac876e097cd23835e4ed8b6e732f 100644 +index e42b0b19019ef74733fd19b08f882cccff920142..6ce116dc3173d17b19c4c03fe9cf494dd022f0d5 100644 --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java @@ -63,6 +63,43 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder 0) { -@@ -279,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -279,7 +428,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } // CraftBukkit end @@ -10869,7 +10900,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e // CraftBukkit start - Use relative location for far away sounds // this.level().globalLevelEvent(1023, new BlockPosition(this), 0); int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16; -@@ -303,7 +454,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -303,7 +452,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob this.setInvulnerableTicks(i); if (this.tickCount % 10 == 0) { @@ -10878,7 +10909,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e } } else { -@@ -363,7 +514,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -363,7 +512,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.destroyBlocksTick > 0) { --this.destroyBlocksTick; @@ -10887,7 +10918,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e i = Mth.floor(this.getY()); j = Mth.floor(this.getX()); int i1 = Mth.floor(this.getZ()); -@@ -396,8 +547,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -396,8 +545,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } } @@ -10900,7 +10931,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -583,11 +736,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -583,11 +734,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } public int getAlternativeTarget(int headIndex) { @@ -10914,7 +10945,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e } @Override -@@ -602,6 +755,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -602,6 +753,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected boolean canRide(Entity entity) { @@ -10923,7 +10954,7 @@ index c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65..c94a1b75593ad01e7f79fdc84818ea8e } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 1c7702a5c888846f93f8f80d3b854a26c11499be..2f64267d780fdbba1248398094bed39ed619740c 100644 +index 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb15c630988 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java @@ -99,10 +99,12 @@ public class ArmorStand extends LivingEntity { @@ -11031,7 +11062,7 @@ index d9016807bc21c38a5c38170e1335c79b39355bcb..62cdc36a21c0203ed98d2946a1efdf54 } diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index 9105418b29c89f092378da11b14e3d324332a2ba..cf99a4c45bd9cdd886bd7b220d8f95dd64d79227 100644 +index e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..958e7684440fcc209fe33e882bf259d92a6814b1 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -133,7 +133,7 @@ public class FallingBlockEntity extends Entity { @@ -11748,7 +11779,7 @@ index efc1d49c5bfea7d1674b8a9de2c8b617657eda0f..df8d1b34078031001c50325b8cf5bfa9 return Guardian.createAttributes().add(Attributes.MOVEMENT_SPEED, 0.30000001192092896D).add(Attributes.ATTACK_DAMAGE, 8.0D).add(Attributes.MAX_HEALTH, 80.0D); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 9fc3db543a0c9df502df5fb85012c6aa590e887d..0be47e96b2bb6bb66e7905e255e5f6009d6e0a97 100644 +index 0d51f435f18f3f9d59a3241a0b7fa1c4af841b72..4c9ffa8e1ab97d8156ead0ed189c769ffd9b4aae 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java @@ -95,12 +95,40 @@ public class EnderMan extends Monster implements NeutralMob { @@ -12595,7 +12626,7 @@ index 2858ea5562d06c11e5c7337a2b123f9be7a3f62e..1ad97267394d3717b1871336193cdc91 @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/Monster.java b/src/main/java/net/minecraft/world/entity/monster/Monster.java -index 55c245d0dfa369dc6de2197ae37335fba4fae4ae..c9b40515f4c2ff1eedfc9510930c3baebc078ebd 100644 +index e4218acaaf7d3aef0fb31f5597fb1af32aa2c8b5..01977550309451cda795583ba4122143b140b9b7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Monster.java +++ b/src/main/java/net/minecraft/world/entity/monster/Monster.java @@ -89,6 +89,14 @@ public abstract class Monster extends PathfinderMob implements Enemy { @@ -13681,7 +13712,7 @@ index b14979ab7bed34a37fceff5589ecb789bab31318..e2eb27a60fde8a937ad1101bbda54c89 } diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index 71b5a9c97a13f703073c0122742ff9e8a0e49df2..42252e86ca02955ba8cae913081795b57e04c934 100644 +index 6f12e342adf1a008709fd9a4fbbbe1da8ec31b83..43ce5ffc6fc1853875f446b543d5b57502a21dc7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -53,14 +53,48 @@ public class Spider extends Monster { @@ -14229,7 +14260,7 @@ index b79c86272f12c4b1173ea494cbe09e1ecdc23533..1d36459ee10da702d65b4a6d139a05fd } 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 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac6f031390 100644 +index 5fdad1600cc7a7c22d1d9a58b6b2dda605521b97..1be1bfb831198b68d8e20bf5ff922edff8832114 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -96,22 +96,69 @@ public class Zombie extends Monster { @@ -14382,7 +14413,7 @@ index 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac } // Paper end -@@ -528,19 +565,20 @@ public class Zombie extends Monster { +@@ -520,19 +557,20 @@ public class Zombie extends Monster { if (object instanceof Zombie.ZombieGroupData) { Zombie.ZombieGroupData entityzombie_groupdatazombie = (Zombie.ZombieGroupData) object; @@ -14409,7 +14440,7 @@ index 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level()); if (entitychicken1 != null) { -@@ -550,6 +588,7 @@ public class Zombie extends Monster { +@@ -542,6 +580,7 @@ public class Zombie extends Monster { this.startRiding(entitychicken1); world.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit } @@ -14417,7 +14448,7 @@ index 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac } } } -@@ -560,11 +599,7 @@ public class Zombie extends Monster { +@@ -552,11 +591,7 @@ public class Zombie extends Monster { } if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) { @@ -14430,7 +14461,7 @@ index 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(randomsource.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN)); this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F; } -@@ -596,7 +631,7 @@ public class Zombie extends Monster { +@@ -588,7 +623,7 @@ public class Zombie extends Monster { } protected void randomizeReinforcementsChance() { @@ -14440,7 +14471,7 @@ index 1ddbba72a5fd3d225b651815a38d178941fba289..97ed65885f43c712953d6d8b3c231bac @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -index 807cff3fb51269b97d9aecbcc4706f0a139dfeaa..858bf64d951ae48421ceb2f9b62de9397ffb4dc3 100644 +index 94396ad1a3c280787d36c6c18256d10340ace488..4d744e00bbaf25d1bad3782a6415e9bf5958e536 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java @@ -82,6 +82,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { @@ -14666,7 +14697,7 @@ index e703320717ff620a19ff76d1c10066117c9895d5..9d6c4f13c4a444c6c815c6c4f2114142 if (this.isConverting()) { ++this.timeInOverworld; diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index cfdc1650783d6855e0d4f33ec68aab48dbee09f0..b2094e07084f06600f1e68b3ac5f865bf6667449 100644 +index cfdc1650783d6855e0d4f33ec68aab48dbee09f0..8e829d522a6012f409161ad5a9a06721a942d7e4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java @@ -96,6 +96,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @@ -14715,7 +14746,7 @@ index cfdc1650783d6855e0d4f33ec68aab48dbee09f0..b2094e07084f06600f1e68b3ac5f865b - this.level().getProfiler().push("piglinBrain"); - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish + //this.level().getProfiler().push("piglinBrain"); // Purpur -+ //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider this.getBrain().tick((ServerLevel) this.level(), this); - this.level().getProfiler().pop(); + //this.level().getProfiler().pop(); // Purpur @@ -14732,10 +14763,10 @@ index cfdc1650783d6855e0d4f33ec68aab48dbee09f0..b2094e07084f06600f1e68b3ac5f865b protected boolean canReplaceCurrentItem(ItemStack stack) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index 5c13e376dd079134da465044f1057bcce66973a3..8f10ced20d7cdb7020f032c9e37d9bbb38f360d6 100644 +index 372d084609216d5437b92ee60810a9efbb0b6f31..a5a7ea0ddad31e3633647f823df86ddbb5fbbcc5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -597,20 +597,33 @@ public class PiglinAi { +@@ -598,20 +598,33 @@ public class PiglinAi { Iterator iterator = iterable.iterator(); Item item; @@ -14910,7 +14941,7 @@ index 5e43912708f9074dee1bb351efa737a7e6796fc3..5e66c2bd3807619cadee5b7081d93d21 public static void applyDarknessAround(ServerLevel world, Vec3 pos, @Nullable Entity entity, int range) { diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 5119d070dbb04f5a4f9c2def526e33e15ca8573f..d5408629801716ccb227b6a7068d17495ed3d0fb 100644 +index 5a591c439c5cef6b7e7e6f836ab813cb4f29b08c..44bb73e6846fc5f536b6efd5db7c5f1560ffecae 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -42,6 +42,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; @@ -14968,19 +14999,19 @@ index 5f407535298a31a34cfe114dd863fd6a9b977707..29c7e33fe961020e5a0007287fe9b663 } diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323c95002e4 100644 +index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b4634b2abf08 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -142,6 +142,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -141,6 +141,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + }, MemoryModuleType.MEETING_POINT, (entityvillager, holder) -> { return holder.is(PoiTypes.MEETING); }); - public long nextGolemPanic = -1; // Pufferfish + private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur -+ private int notLobotomizedCount = 0; ++ private int notLobotomizedCount = 0; // Purpur + + public long nextGolemPanic = -1; // Pufferfish - public Villager(EntityType entityType, Level world) { - this(entityType, world, VillagerType.PLAINS); -@@ -154,6 +156,90 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -155,6 +157,90 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.getNavigation().setCanFloat(true); this.setCanPickUpLoot(true); this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); @@ -15060,8 +15091,8 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 + } + net.minecraft.world.level.block.Block bottom = state.getBlock(); + if (bottom instanceof net.minecraft.world.level.block.FenceBlock || -+ bottom instanceof net.minecraft.world.level.block.FenceGateBlock || -+ bottom instanceof net.minecraft.world.level.block.WallBlock) { ++ bottom instanceof net.minecraft.world.level.block.FenceGateBlock || ++ bottom instanceof net.minecraft.world.level.block.WallBlock) { + // bottom block is too tall to get over + return false; + } @@ -15071,7 +15102,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 } @Override -@@ -190,7 +276,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -191,7 +277,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F)); } else { brain.setSchedule(Schedule.VILLAGER_DEFAULT); @@ -15080,7 +15111,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 } brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); -@@ -253,15 +339,25 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -254,15 +340,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler // Paper start this.customServerAiStep(false); } @@ -15088,6 +15119,9 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 + protected void customServerAiStep(boolean inactive) { // Purpur - not final // Paper end - this.level().getProfiler().push("villagerBrain"); +- // Pufferfish start +- if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { +- this.getBrain().tick((ServerLevel) this.level(), this); // Paper + //this.level().getProfiler().push("villagerBrain"); // Purpur + // Purpur start + if (this.level().purpurConfig.villagerLobotomizeEnabled) { @@ -15096,21 +15130,18 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 + } else { + // clean up state for API + this.isLobotomized = false; -+ } - // Pufferfish start -- if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { -+ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) { // Purpur - only use brain if no rider - this.getBrain().tick((ServerLevel) this.level(), this); // Paper } -+ else if (this.isLobotomized && shouldRestock()) restock(); - // Pufferfish end +- // Pufferfish end - this.level().getProfiler().pop(); ++ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Purpur - only use brain if no rider ++ this.getBrain().tick((ServerLevel) this.level(), this); // Paper ++ else if (this.isLobotomized && shouldRestock()) restock(); + // Purpur end + //this.level().getProfiler().pop(); // Purpur if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } -@@ -317,7 +413,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -318,7 +411,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler if (!itemstack.is(Items.VILLAGER_SPAWN_EGG) && this.isAlive() && !this.isTrading() && !this.isSleeping()) { if (this.isBaby()) { this.setUnhappy(); @@ -15119,7 +15150,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 } else { boolean flag = this.getOffers().isEmpty(); -@@ -330,9 +426,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -331,9 +424,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (flag) { @@ -15132,7 +15163,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 this.startTrading(player); } -@@ -501,7 +598,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -502,7 +596,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); @@ -15141,7 +15172,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 } } -@@ -751,7 +848,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -752,7 +846,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public boolean canBreed() { @@ -15150,7 +15181,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 } private boolean hungry() { -@@ -944,6 +1041,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -945,6 +1039,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public boolean hasFarmSeeds() { return this.getInventory().hasAnyMatching((itemstack) -> { @@ -15162,7 +15193,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS); }); } -@@ -1001,6 +1103,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1002,6 +1101,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) { @@ -15170,7 +15201,7 @@ index 1bc082a1fad26e38a8606b633bf3789b5e4d6046..b0b06ba1ea4cfdb2c0d27aee12312323 if (this.wantsToSpawnGolem(time)) { AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D); List list = world.getEntitiesOfClass(Villager.class, axisalignedbb); -@@ -1074,6 +1177,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1066,6 +1166,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void startSleeping(BlockPos pos) { @@ -15197,7 +15228,7 @@ index ac70c2c03241e73943bd517a8c69dd05e0873634..0318663a824d2a9515f867a075d148c3 public static final VillagerProfession FISHERMAN = register("fisherman", PoiTypes.FISHERMAN, SoundEvents.VILLAGER_WORK_FISHERMAN); public static final VillagerProfession FLETCHER = register("fletcher", PoiTypes.FLETCHER, SoundEvents.VILLAGER_WORK_FLETCHER); diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 3c2941d799c9acb3dd9e2b67b7092f4bba5ede17..d8a4b1aaa180fc0c837bc0d8efab781a578898a5 100644 +index 833563e237462ccfc1b730b8f5fb35340d0db854..237247cb91248eb2d05e967e95cb8ad0a8a63080 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java @@ -70,6 +70,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill @@ -15298,7 +15329,7 @@ index 8385eb1d60f377da94e3178ab506feefb43563fd..a5443f92786427c42092aec8350e7ab3 if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, world, blockposition2, EntityType.WANDERING_TRADER)) { blockposition1 = blockposition2; diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index d58b4c0dbe651b5068212e5f14dce3164ee520f5..20c3d3c9d2150574e9b4761dc1bda11cee04862f 100644 +index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7ba4e69ceb 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -188,17 +188,40 @@ public abstract class Player extends LivingEntity { @@ -15443,88 +15474,8 @@ index d58b4c0dbe651b5068212e5f14dce3164ee520f5..20c3d3c9d2150574e9b4761dc1bda11c if (this instanceof ServerPlayer) { CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack); } -diff --git a/src/main/java/net/minecraft/world/entity/player/StackedContents.java b/src/main/java/net/minecraft/world/entity/player/StackedContents.java -index 26b236a764177ac16d53f5cbaf83d3e21d015ebc..6bc60ea5249cca9f4c1d029a2b7460fe3476e05a 100644 ---- a/src/main/java/net/minecraft/world/entity/player/StackedContents.java -+++ b/src/main/java/net/minecraft/world/entity/player/StackedContents.java -@@ -41,8 +41,62 @@ public class StackedContents { - int j = Math.min(maxCount, stack.getCount()); - if (this.extrasMap != null && stack.hasTag() && this.extrasMap.accountStack(stack, j)) return; // Paper - if an exact ingredient, don't include it - this.put(i, j); -+ // PaperPR start -+ if (stack.hasTag()) { -+ this.put(getExactStackingIndex(stack), j); -+ } -+ } -+ -+ } -+ private static final net.minecraft.core.IdMap EXACT_MATCHES_ID_MAP = new net.minecraft.core.IdMap<>() { -+ private final java.util.concurrent.atomic.AtomicInteger idCounter = new java.util.concurrent.atomic.AtomicInteger(BuiltInRegistries.ITEM.size()); -+ private final it.unimi.dsi.fastutil.objects.Object2IntMap itemstackToId = new it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap<>(new it.unimi.dsi.fastutil.Hash.Strategy<>() { -+ @Override -+ public int hashCode(ItemStack o) { -+ return java.util.Objects.hash(o.getItem(), o.getTag()); -+ } -+ -+ @Override -+ public boolean equals(@Nullable ItemStack a, @Nullable ItemStack b) { -+ if (a == null || b == null) { -+ return false; -+ } -+ return ItemStack.matches(a, b); -+ } -+ }); -+ private final it.unimi.dsi.fastutil.ints.Int2ObjectMap idToItemstack = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); -+ -+ @Override -+ public int getId(ItemStack value) { -+ if (!this.itemstackToId.containsKey(value)) { -+ final int id = this.idCounter.incrementAndGet(); -+ final ItemStack copy = value.copy(); -+ this.itemstackToId.put(copy, id); -+ this.idToItemstack.put(id, copy); -+ return id; -+ } -+ return this.itemstackToId.getInt(value); -+ } -+ -+ @Override -+ public @Nullable ItemStack byId(int index) { -+ return this.idToItemstack.get(index); -+ } -+ -+ @Override -+ public int size() { -+ return this.itemstackToId.size(); -+ } -+ -+ @Override -+ public java.util.Iterator iterator() { -+ return this.idToItemstack.values().iterator(); - } -+ }; - -+ public static int getExactStackingIndex(ItemStack stack) { -+ return EXACT_MATCHES_ID_MAP.getId(stack); -+ // PaperPR end - } - - public static int getStackingIndex(ItemStack stack) { -@@ -84,6 +138,12 @@ public class StackedContents { - } - - public static ItemStack fromStackingIndex(int itemId) { -+ // PaperPR start -+ if (itemId > BuiltInRegistries.ITEM.size()) { -+ final ItemStack stack = EXACT_MATCHES_ID_MAP.byId(itemId); -+ return stack == null ? ItemStack.EMPTY : stack.copy(); -+ } -+ // PaperPR end - return itemId == 0 ? ItemStack.EMPTY : new ItemStack(Item.byId(itemId)); - } - diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 8affdd74769aed9aa92a76ba539cd9d27208827c..4063aed1a3f0bfd7351c1ec2e9684e4991cb5285 100644 +index 6c176933967f6ee98da3026f16a10efe4c3842fe..aa5e17e497bbc1d45b361de73cc7a181773dbd8b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java @@ -72,6 +72,7 @@ public abstract class AbstractArrow extends Projectile { @@ -15558,22 +15509,22 @@ index 8affdd74769aed9aa92a76ba539cd9d27208827c..4063aed1a3f0bfd7351c1ec2e9684e49 return this.knockback; } diff --git a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java -index 251e6bc87eb02ec4372062ef22b21249ac5164ff..6b60597a0e837054b0d1891c1e6e5e7cd3af9539 100644 +index 6b67eec90cd0dc1b20762514eac97f75fdbdf182..2dec28091d1816e9d4c749a5155e83031751cf50 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java @@ -16,20 +16,20 @@ public class LargeFireball extends Fireball { public LargeFireball(EntityType type, Level world) { super(type, world); -- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit -+ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur +- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit ++ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur } public LargeFireball(Level world, LivingEntity owner, double velocityX, double velocityY, double velocityZ, int explosionPower) { super(EntityType.FIREBALL, owner, velocityX, velocityY, velocityZ, world); this.explosionPower = explosionPower; -- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit -+ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur +- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit ++ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur } @Override @@ -15628,15 +15579,15 @@ index cc0a3d9794d05b6bc6ab05f4f2ab8d83134b181d..e1f918d0bd2a70db1aba8bda8717149f HitResult hitResult = world.clip(new ClipContext(pos, vec3, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)); if (hitResult.getType() != HitResult.Type.MISS) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java -index 04c2ea1ff44af72ae48e2d6b7b912b1c14285038..7839d856b3f924f0c87b298d9a1e3b15ab0693d6 100644 +index 9d43c8520953d6fe0d0948f9dbe14e0650ee01c2..deee9fffe6981d7e728621cc799a812d78000592 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -24,7 +24,7 @@ public class SmallFireball extends Fireball { super(EntityType.SMALL_FIREBALL, owner, velocityX, velocityY, velocityZ, world); // CraftBukkit start if (this.getOwner() != null && this.getOwner() instanceof Mob) { -- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur +- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur } // CraftBukkit end } @@ -15687,7 +15638,7 @@ index 718e120c9768cf716b32d3d652f53f1dda925168..440d3d72d8b2dac14f83a83caa5ae9db protected void onHit(HitResult hitResult) { super.onHit(hitResult); diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index e02d5dcbf69bd68b2f567c1a16a44ab59955f871..fb0f29b714344f0ac3e7f6bd809ac57a21061156 100644 +index f5db60cbecbe69941873e064315931089fe0e48a..2728eaaf0a9b761d932bd22639ef4e1ccc428482 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java @@ -67,10 +67,11 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { @@ -15945,7 +15896,7 @@ index 5c07da62c82bc70138f6cb5007629d6974be69ac..c314febb75a85ef12051bde392c5b57e } else { return Boat.Status.IN_AIR; diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java -index 2038df72f8d7d33d4105de8129628daf21de6f0f..e54af9ff2a786e919b8261aa27509be942e70261 100644 +index c3448707fd8a632b457cc97b35d08a9c6933d5ee..e8079d126e6c0cf0b15c01afb6498922ee05964c 100644 --- a/src/main/java/net/minecraft/world/food/FoodData.java +++ b/src/main/java/net/minecraft/world/food/FoodData.java @@ -33,8 +33,10 @@ public class FoodData { @@ -16015,7 +15966,7 @@ index b16d9e2eaa589f19c563ee70b1a56d67dbcdecb0..71beab673f04cd051c46ea37f8c84731 public static final FoodProperties BAKED_POTATO = (new FoodProperties.Builder()).nutrition(5).saturationMod(0.6F).build(); public static final FoodProperties BEEF = (new FoodProperties.Builder()).nutrition(3).saturationMod(0.3F).meat().build(); diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index ffd349c1b80df0f1e8c02bda23700184825170fd..29f301bde378bd320d5c44f2c1b6bf9dc185e286 100644 +index 82f18790b9dc55b039ae03600a80a46d56a87521..6a754ecd4e9d6c3ebc7bd91b1de797fdbf3c4290 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -76,6 +76,7 @@ public abstract class AbstractContainerMenu { @@ -16046,7 +15997,7 @@ index 1af7e1548f0648890a1ef2fc0ff4e4c3a56c947c..decea1697c075e7549ccc7501c8e5935 } else if (this.isFuel(itemstack1)) { if (!this.moveItemStackTo(itemstack1, 1, 2, false)) { diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..531b911c1bcdd3735529ee18f2bb0ccdf4ad6089 100644 +index f00638e9d7baf8b803dd610f2bf6250da34efab3..27d76e0c4809d333c548379bf78ec2db083b027e 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java @@ -23,6 +23,13 @@ import org.slf4j.Logger; @@ -16207,7 +16158,7 @@ index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..531b911c1bcdd3735529ee18f2bb0ccd } @@ -315,11 +393,17 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit - sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client + this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); + // Purpur start + if ((canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants) && itemstack1 != ItemStack.EMPTY) { @@ -16326,7 +16277,7 @@ index c5c509fbb915c60dfa95aac8510684d0b9f8b0ff..d604b7ec46f08993647979ed220a8484 }); } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index a21eadcdfbdc4be803c5793bc97996db3e706071..3b721092a7a73472756064e0eb91d3220fdc4bc8 100644 +index 076c2b2938c9b88b7e71dbc2aa9d8c7e90d4fe75..b1eacb9691b320a10de3420fae3632bb9d5b7ae3 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java @@ -95,9 +95,11 @@ public class GrindstoneMenu extends AbstractContainerMenu { @@ -16401,7 +16352,7 @@ index a21eadcdfbdc4be803c5793bc97996db3e706071..3b721092a7a73472756064e0eb91d322 return itemstack; diff --git a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java -index b399903e8f11ec6c12fe7e724b7d9c8292acd573..a4afa946cd47238eb0fed297a27b24013d5ba77c 100644 +index 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..45eec732ff0e4e78b4d3f2112b6a79d7ae668d2f 100644 --- a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java +++ b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java @@ -4,6 +4,7 @@ import com.mojang.datafixers.util.Pair; @@ -16565,10 +16516,10 @@ index 18898e16ec42f6b694b06e09d9174b60d62450d7..20f33b77b4a9494be227456bc742a029 return InteractionResult.PASS; } diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index e483186a5292b3b53bfb1af4d56f55fcc1a6106c..41728bcbd5ca3585da64f7c3289b26977f90c229 100644 +index efdf56044396b4ce486948d2c993971f99174a5e..42bfde8e36b6395f50973300313d6959e2735327 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -153,7 +153,24 @@ public class BlockItem extends Item { +@@ -152,7 +152,24 @@ public class BlockItem extends Item { } protected boolean updateCustomBlockEntityTag(BlockPos pos, Level world, @Nullable Player player, ItemStack stack, BlockState state) { @@ -16594,7 +16545,7 @@ index e483186a5292b3b53bfb1af4d56f55fcc1a6106c..41728bcbd5ca3585da64f7c3289b2697 } @Nullable -@@ -288,7 +305,7 @@ public class BlockItem extends Item { +@@ -287,7 +304,7 @@ public class BlockItem extends Item { @Override public void onDestroyed(ItemEntity entity) { @@ -16663,7 +16614,7 @@ index 08d597db1a5345a343777a01427655e6bf2c926b..d45a2f49c82d00801578c34e5f5277fc } else { user.startUsingItem(hand); diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java -index 277555a26e8281dd1a626e572794b08cf51d00c5..48e4fecf5ae5538004e3f53093b8be7c4be1cbee 100644 +index aa0f09a18ea781e027ea70928b30d3e93061120f..5cb8f1e13f4889792395d6b498c0ade22a33b446 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java @@ -195,7 +195,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { @@ -16890,18 +16841,10 @@ index 180aec596110309aade13d2080f8824d152b07cb..552c31c0f3746dd35388395036e70a92 return InteractionResult.PASS; } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca8e1d20da 100644 +index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53ef149e43 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -114,6 +114,7 @@ import org.bukkit.event.world.StructureGrowEvent; - - public final class ItemStack { - -+ public boolean isExactRecipeIngredient = false; // PaperPR - public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { - return instance.group(BuiltInRegistries.ITEM.byNameCodec().fieldOf("id").forGetter(ItemStack::getItem), Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount), CompoundTag.CODEC.optionalFieldOf("tag").forGetter((itemstack) -> { - return Optional.ofNullable(itemstack.getTag()); -@@ -432,6 +433,7 @@ public final class ItemStack { +@@ -432,6 +432,7 @@ public final class ItemStack { world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 for (BlockState blockstate : blocks) { blockstate.update(true, false); @@ -16909,7 +16852,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca } world.preventPoiUpdated = false; -@@ -461,6 +463,7 @@ public final class ItemStack { +@@ -463,6 +464,7 @@ public final class ItemStack { if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically block.getBlock().onPlace(block, world, newblockposition, oldBlock, true, context); // Paper - pass context } @@ -16917,7 +16860,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point } -@@ -589,6 +592,16 @@ public final class ItemStack { +@@ -591,6 +593,16 @@ public final class ItemStack { return this.isDamageableItem() && this.getDamageValue() > 0; } @@ -16934,7 +16877,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca public int getDamageValue() { return this.tag == null ? 0 : this.tag.getInt("Damage"); } -@@ -608,7 +621,7 @@ public final class ItemStack { +@@ -610,7 +622,7 @@ public final class ItemStack { int j; if (amount > 0) { @@ -16943,7 +16886,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca int k = 0; for (int l = 0; j > 0 && l < amount; ++l) { -@@ -663,6 +676,12 @@ public final class ItemStack { +@@ -665,6 +677,12 @@ public final class ItemStack { if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - pass LivingEntity for EntityItemDamageEvent breakCallback.accept(entity); Item item = this.getItem(); @@ -16956,7 +16899,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca // CraftBukkit start - Check for item breaking if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) { org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this); -@@ -1189,7 +1208,7 @@ public final class ItemStack { +@@ -1191,7 +1209,7 @@ public final class ItemStack { ListTag nbttaglist = this.tag.getList("Enchantments", 10); @@ -16965,7 +16908,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..4d99e7db4e9e56caead5ea177b79aaca processEnchantOrder(this.tag); // Paper } -@@ -1197,6 +1216,12 @@ public final class ItemStack { +@@ -1199,6 +1217,12 @@ public final class ItemStack { return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; } @@ -17201,7 +17144,7 @@ index 8078f127ff4b6e0aafb5804b9c02e237f79445b5..c32cbe6065ecb6810f352b8a3598c21e entityhuman.startAutoSpinAttack(20); if (entityhuman.onGround()) { diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..ae98a5b49b5eb7b9b2846d1e41b5665c725198a2 100644 +index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..3532db21cee82c18f95c540d24b2071585d71c4e 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java @@ -39,6 +39,7 @@ public final class Ingredient implements Predicate { @@ -17212,20 +17155,7 @@ index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..ae98a5b49b5eb7b9b2846d1e41b5665c public static final Codec CODEC = Ingredient.codec(true); public static final Codec CODEC_NONEMPTY = Ingredient.codec(false); -@@ -56,7 +57,11 @@ public final class Ingredient implements Predicate { - if (this.itemStacks == null) { - this.itemStacks = (ItemStack[]) Arrays.stream(this.values).flatMap((recipeitemstack_provider) -> { - return recipeitemstack_provider.getItems().stream(); -- }).distinct().toArray((i) -> { -+ // PaperPR start -+ }).distinct().peek(stack -> { -+ stack.isExactRecipeIngredient = this.exact; -+ }).toArray((i) -> { -+ // PaperPR end - return new ItemStack[i]; - }); - } -@@ -70,6 +75,12 @@ public final class Ingredient implements Predicate { +@@ -70,6 +71,12 @@ public final class Ingredient implements Predicate { } else if (this.isEmpty()) { return itemstack.isEmpty(); } else { @@ -17238,20 +17168,6 @@ index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..ae98a5b49b5eb7b9b2846d1e41b5665c ItemStack[] aitemstack = this.getItems(); int i = aitemstack.length; -@@ -105,7 +116,13 @@ public final class Ingredient implements Predicate { - for (int j = 0; j < i; ++j) { - ItemStack itemstack = aitemstack1[j]; - -+ // PaperPR start -+ if (itemstack.isExactRecipeIngredient) { -+ this.stackingIds.add(StackedContents.getExactStackingIndex(itemstack)); -+ } else { -+ // PaperPR end - this.stackingIds.add(StackedContents.getStackingIndex(itemstack)); -+ } // PaperPR - } - - this.stackingIds.sort(IntComparators.NATURAL_COMPARATOR); diff --git a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java index 518d85a13c37a2f7d32ca0718323181048559986..27512787b37381a5236b1b473e9ce3f06df8e2d0 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java @@ -17385,10 +17301,10 @@ index 4f7457578ab3118d10e0d5dfc23d79c9b20c2f44..e03ce53b93d1b9366f2a7f14f341750a public ItemStack assemble() { diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 633500aefd515df5dadda3802b94079f75a03fa0..64d911bee1607880514061c75116d8672df8bb8f 100644 +index 6eca4a9b3cf462a4d18f32619bbcdfda0fa2ebc5..914564a528c360f352927e7681ab2e31ed365b21 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java -@@ -55,6 +55,7 @@ public abstract class BaseSpawner { +@@ -71,6 +71,7 @@ public abstract class BaseSpawner { } public boolean isNearPlayer(Level world, BlockPos pos) { @@ -17470,7 +17386,7 @@ index 45243249a561440512ef2a620c60b02e159c80e2..ef9b1687dd2dfda5398523140aecc678 } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f6dae3ccc 100644 +index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9be7dab401 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -176,6 +176,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -17531,7 +17447,13 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f public CraftWorld getWorld() { return this.world; } -@@ -213,6 +257,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -210,11 +254,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public abstract ResourceKey getTypeKey(); + +- protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter ++ //protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter // Purpur - dont break ABI + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper @@ -17540,7 +17462,7 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); -@@ -1253,18 +1299,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1255,18 +1301,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } protected void tickBlockEntities() { @@ -17548,36 +17470,36 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f + //ProfilerFiller gameprofilerfiller = this.getProfiler(); // Purpur - gameprofilerfiller.push("blockEntities"); -- timings.tileEntityPending.startTiming(); // Spigot +- this.timings.tileEntityPending.startTiming(); // Spigot + //gameprofilerfiller.push("blockEntities"); // Purpur -+ //timings.tileEntityPending.startTiming(); // Spigot // Purpur ++ //this.timings.tileEntityPending.startTiming(); // Spigot // Purpur this.tickingBlockEntities = true; if (!this.pendingBlockEntityTickers.isEmpty()) { this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); this.pendingBlockEntityTickers.clear(); } -- timings.tileEntityPending.stopTiming(); // Spigot -+ //timings.tileEntityPending.stopTiming(); // Spigot // Purpur +- this.timings.tileEntityPending.stopTiming(); // Spigot ++ //this.timings.tileEntityPending.stopTiming(); // Spigot // Purpur -- timings.tileEntityTick.startTiming(); // Spigot -+ //timings.tileEntityTick.startTiming(); // Spigot // Purpur +- this.timings.tileEntityTick.startTiming(); // Spigot ++ //this.timings.tileEntityTick.startTiming(); // Spigot // Purpur // Spigot start // Iterator iterator = this.blockEntityTickers.iterator(); int tilesThisCycle = 0; -@@ -1297,10 +1343,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1299,10 +1345,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } this.blockEntityTickers.removeAll(toRemove); -- timings.tileEntityTick.stopTiming(); // Spigot -+ //timings.tileEntityTick.stopTiming(); // Spigot // Purpur +- this.timings.tileEntityTick.stopTiming(); // Spigot ++ //this.timings.tileEntityTick.stopTiming(); // Spigot // Purpur this.tickingBlockEntities = false; co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper - gameprofilerfiller.pop(); + //gameprofilerfiller.pop(); // Purpur - spigotConfig.currentPrimedTnt = 0; // Spigot + this.spigotConfig.currentPrimedTnt = 0; // Spigot } -@@ -1503,7 +1549,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1505,7 +1551,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { @@ -17586,7 +17508,7 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f List list = Lists.newArrayList(); ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call return list; -@@ -1522,7 +1568,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1524,7 +1570,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { @@ -17595,7 +17517,7 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f // Paper start - optimise this call //TODO use limit if (filter instanceof net.minecraft.world.entity.EntityType entityTypeTest) { -@@ -1779,7 +1825,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1781,7 +1827,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { @@ -17604,7 +17526,7 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f return (ProfilerFiller) this.profiler.get(); } -@@ -1879,4 +1925,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1881,4 +1927,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } } // Paper end - notify observers even if grow failed @@ -17620,7 +17542,7 @@ index 4b49df79d366e58e1cee245e1aaefbb95f4fdfc0..75622ee77096d7eb311df0fd16b70c0f + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 27b75fba1b8052a715979f48b28bba0e4be16274..f64d17e701aa38f7223b8c9a09f351ed84dbcf5d 100644 +index 9c2d62feff1816f5729060c6192269a5b2d34153..a2a59dd2e515bf4dca84a442703c122fd36f05e0 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -132,8 +132,8 @@ public final class NaturalSpawner { @@ -18115,8 +18037,21 @@ index ead7b37122c76d43af2cdd17af7f0da8014efb26..1acc2dcda68ec8e462d51927f2ea985e + } + // Purpur end } +diff --git a/src/main/java/net/minecraft/world/level/block/ChangeOverTimeBlock.java b/src/main/java/net/minecraft/world/level/block/ChangeOverTimeBlock.java +index 8512b977b44a0a4d3a2521e27a60d65f7ac967be..dd270f67388c8663e0418875c88cb1e2a55d0635 100644 +--- a/src/main/java/net/minecraft/world/level/block/ChangeOverTimeBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/ChangeOverTimeBlock.java +@@ -65,7 +65,7 @@ public interface ChangeOverTimeBlock> { + } + + float f = (float) (k + 1) / (float) (k + j + 1); +- float f1 = f * f * this.getChanceModifier(); ++ float f1 = world.purpurConfig.disableOxidationProximityPenalty ? this.getChanceModifier() : f * f * this.getChanceModifier(); // Purpur + + if (random.nextFloat() < f1) { + this.getNext(state).ifPresent((iblockdata2) -> { diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -index 5e22d175b1048a58802cdf64ac70a8b56329e915..d81946b400f208c39941128ce823ff7709741c10 100644 +index af6e245b02d5fb78764d2db0ac200056277b212a..4ee31c5a6053237b15ddb8e3208cdb9a35a0d08d 100644 --- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java @@ -355,6 +355,7 @@ public class ChestBlock extends AbstractChestBlock implements @@ -18399,10 +18334,10 @@ index 7385e91f32f070e86a4e0fd3d214f55d832c7979..7b73de87236a60ce7343c29ec147e186 }, CONTAINER_TITLE)); player.awardStat(Stats.OPEN_ENDERCHEST); diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -index 5946f06f63b5694034bd027984a4925b0831d439..d566f67f8f6f1748023430de4f191881b79e44a1 100644 +index 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..856099241737c43b8213ccc203ef6bb7b7667b1f 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -101,7 +101,7 @@ public class FarmBlock extends Block { +@@ -103,7 +103,7 @@ public class FarmBlock extends Block { @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. @@ -18411,7 +18346,7 @@ index 5946f06f63b5694034bd027984a4925b0831d439..d566f67f8f6f1748023430de4f191881 // CraftBukkit start - Interact soil org.bukkit.event.Cancellable cancellable; if (entity instanceof Player) { -@@ -115,6 +115,22 @@ public class FarmBlock extends Block { +@@ -117,6 +117,22 @@ public class FarmBlock extends Block { return; } @@ -18434,7 +18369,7 @@ index 5946f06f63b5694034bd027984a4925b0831d439..d566f67f8f6f1748023430de4f191881 if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { return; } -@@ -162,7 +178,7 @@ public class FarmBlock extends Block { +@@ -164,7 +180,7 @@ public class FarmBlock extends Block { } } @@ -19277,7 +19212,7 @@ index f13943db6f2fb923c52dcf9e8bf7000041d0a362..99ef8d7e3ee0ee9777d12ad825e728c3 BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_AMBIENT); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index 41c9f074203915c31c1ae7a160ce509c13383f84..82bdd430f1640e44d25af54354bba27b190fa1ba 100644 +index cf09525efd2d53bf884cd6ec3b0b9229715895eb..1098cf5a7675ec742caf687cc8828e09cfd3125e 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java @@ -43,7 +43,7 @@ public class BeehiveBlockEntity extends BlockEntity { @@ -19289,32 +19224,15 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..82bdd430f1640e44d25af54354bba27b public BeehiveBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BEEHIVE, pos, state); -@@ -117,10 +117,15 @@ public class BeehiveBlockEntity extends BlockEntity { - } - - public List releaseBees(BlockState iblockdata, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { -+ // Purpur start -+ return this.releaseBees(iblockdata, this.level, tileentitybeehive_releasestatus, force); -+ } -+ public List releaseBees(BlockState iblockdata, Level level, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { -+ // Purpur end - List list = Lists.newArrayList(); - - this.stored.removeIf((tileentitybeehive_hivebee) -> { -- return BeehiveBlockEntity.releaseBee(this.level, this.worldPosition, iblockdata, tileentitybeehive_hivebee, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); -+ return BeehiveBlockEntity.releaseBee(level, this.worldPosition, iblockdata, tileentitybeehive_hivebee, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); // Purpur - // CraftBukkit end - }); - if (!list.isEmpty()) { -@@ -130,6 +135,22 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -130,6 +130,22 @@ public class BeehiveBlockEntity extends BlockEntity { return list; } + // Purpur start -+ public List releaseBee(BlockState iblockdata, Level level, BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { ++ public List releaseBee(BlockState iblockdata, BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { + List list = Lists.newArrayList(); + -+ BeehiveBlockEntity.releaseBee(level, this.worldPosition, iblockdata, data, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); ++ BeehiveBlockEntity.releaseBee(this.level, this.worldPosition, iblockdata, data, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); + + if (!list.isEmpty()) { + stored.remove(data); @@ -19329,7 +19247,7 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..82bdd430f1640e44d25af54354bba27b public void addOccupant(Entity entity, boolean hasNectar) { this.addOccupantWithPresetTicks(entity, hasNectar, 0); } -@@ -139,6 +160,12 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -139,6 +155,12 @@ public class BeehiveBlockEntity extends BlockEntity { return this.stored.size(); } @@ -19342,7 +19260,7 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..82bdd430f1640e44d25af54354bba27b // Paper start - Add EntityBlockStorage clearEntities public void clearBees() { this.stored.clear(); -@@ -203,7 +230,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -203,7 +225,7 @@ public class BeehiveBlockEntity extends BlockEntity { } private static boolean releaseBee(Level world, BlockPos blockposition, BlockState iblockdata, BeehiveBlockEntity.BeeData tileentitybeehive_hivebee, @Nullable List list, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPos blockposition1, boolean force) { @@ -19351,7 +19269,7 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..82bdd430f1640e44d25af54354bba27b // CraftBukkit end return false; } else { -@@ -425,9 +452,9 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -425,9 +447,9 @@ public class BeehiveBlockEntity extends BlockEntity { private BeeReleaseStatus() {} } @@ -19711,16 +19629,25 @@ index e6a4a5898ffdcb2aa2bc01371a6d7dbc06d610ce..e46a097dc134672720bc753ec0da0a91 protected ResourceLocation drops; 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 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b90286aad1a2 100644 +index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef0172f9ff 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -447,11 +447,11 @@ public class LevelChunk extends ChunkAccess { +@@ -122,7 +122,7 @@ public class LevelChunk extends ChunkAccess { + this.blockTicks = blockTickScheduler; + this.fluidTicks = fluidTickScheduler; + +- this.lightningTick = this.level.getThreadUnsafeRandom().nextInt(100000) << 1; // Pufferfish - initialize lightning tick ++ this.lightningTick = java.util.concurrent.ThreadLocalRandom.current().nextInt(100000) << 1; // Pufferfish - initialize lightning tick // Purpur - any random will do + } + + // CraftBukkit start +@@ -457,11 +457,11 @@ public class LevelChunk extends ChunkAccess { if (LightEngine.hasDifferentLightProperties(this, blockposition, iblockdata1, iblockdata)) { ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - gameprofilerfiller.push("updateSkyLightSources"); + //gameprofilerfiller.push("updateSkyLightSources"); // Purpur - this.skyLightSources.update(this, j, i, l); + // Paper - starlight - remove skyLightSources - gameprofilerfiller.popPush("queueCheckLight"); + //gameprofilerfiller.popPush("queueCheckLight"); // Purpur this.level.getChunkSource().getLightEngine().checkBlock(blockposition); @@ -19729,7 +19656,7 @@ index 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b902 } boolean flag3 = iblockdata1.hasBlockEntity(); -@@ -790,7 +790,7 @@ public class LevelChunk extends ChunkAccess { +@@ -800,7 +800,7 @@ public class LevelChunk extends ChunkAccess { this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system if (this.needsDecoration) { @@ -19738,7 +19665,7 @@ index 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b902 this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -810,7 +810,7 @@ public class LevelChunk extends ChunkAccess { +@@ -820,7 +820,7 @@ public class LevelChunk extends ChunkAccess { } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -19747,7 +19674,7 @@ index 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b902 } } } -@@ -1165,10 +1165,10 @@ public class LevelChunk extends ChunkAccess { +@@ -1175,10 +1175,10 @@ public class LevelChunk extends ChunkAccess { if (LevelChunk.this.isTicking(blockposition)) { try { @@ -19761,7 +19688,7 @@ index 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b902 BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1179,7 +1179,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1189,7 +1189,7 @@ public class LevelChunk extends ChunkAccess { LevelChunk.LOGGER.warn("Block entity {} @ {} state {} invalid for ticking:", new Object[]{LogUtils.defer(this::getType), LogUtils.defer(this::getPos), iblockdata}); } @@ -19770,7 +19697,7 @@ index 4abec88caab4116cfa318f7b66c6b1a8346a7401..8d385708df97d47881929d4352f1b902 } catch (Throwable throwable) { if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes -@@ -1190,7 +1190,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1200,7 +1200,7 @@ public class LevelChunk extends ChunkAccess { // Paper end // Spigot start } finally { @@ -19827,10 +19754,10 @@ index dfeb3e336e06ef01f5401a362755030db942bb07..f74c5eda91a3d521763ec7bc33f23e0c for (int l = 0; l < k; ++l) { // Paper start 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 089f42d16b2e279fa0daefb8705867a4e9ed54d7..f48d32bf4d7f179e7ad21cf4f395de9180c6c8f0 100644 +index c55f51e6db55f9fa66f53eef0e7a56af5f81d742..74688f4672936cd2ac629b9f2f404163df6730e9 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -227,7 +227,7 @@ public abstract class FlowingFluid extends Fluid { +@@ -228,7 +228,7 @@ public abstract class FlowingFluid extends Fluid { } } @@ -19839,7 +19766,7 @@ index 089f42d16b2e279fa0daefb8705867a4e9ed54d7..f48d32bf4d7f179e7ad21cf4f395de91 BlockState iblockdata2 = world.getBlockState(pos.below()); FluidState fluid1 = iblockdata2.getFluidState(); -@@ -334,6 +334,12 @@ public abstract class FlowingFluid extends Fluid { +@@ -337,6 +337,12 @@ public abstract class FlowingFluid extends Fluid { protected abstract boolean canConvertToSource(Level world); @@ -20035,7 +19962,7 @@ index 1d7c663fa0e550bd0cfb9a4b83ccd7e2968666f0..0043c0087896a6df6910b0500da37d84 this.rescheduleLeftoverContainers(); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index 03fc90a470c0f63d44161843cac88bea09166858..88640ac32d70ced6e8b1984663e1c492dd673cb5 100644 +index 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..d0e3b531392738679894a989293ae49eb319676c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -567,4 +567,213 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa @@ -20253,10 +20180,10 @@ index 03fc90a470c0f63d44161843cac88bea09166858..88640ac32d70ced6e8b1984663e1c492 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a0218f6dc28 100644 +index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755c84a4b03 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -267,7 +267,7 @@ import javax.annotation.Nullable; // Paper +@@ -269,7 +269,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -20265,7 +20192,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -399,6 +399,20 @@ public final class CraftServer implements Server { +@@ -401,6 +401,20 @@ public final class CraftServer implements Server { this.dataPackManager = new CraftDataPackManager(this.getServer().getPackRepository()); Bukkit.setServer(this); @@ -20286,15 +20213,15 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 CraftRegistry.setMinecraftRegistry(console.registryAccess()); -@@ -1039,6 +1053,7 @@ public final class CraftServer implements Server { +@@ -1041,6 +1055,7 @@ public final class CraftServer implements Server { - org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot + org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); + org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) -@@ -1054,6 +1069,7 @@ public final class CraftServer implements Server { +@@ -1056,6 +1071,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot @@ -20302,7 +20229,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1069,6 +1085,7 @@ public final class CraftServer implements Server { +@@ -1071,6 +1087,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper @@ -20310,7 +20237,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -1534,6 +1551,55 @@ public final class CraftServer implements Server { +@@ -1537,6 +1554,55 @@ public final class CraftServer implements Server { return true; } @@ -20366,7 +20293,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 @Override public List getRecipesFor(ItemStack result) { Preconditions.checkArgument(result != null, "ItemStack cannot be null"); -@@ -2873,6 +2939,7 @@ public final class CraftServer implements Server { +@@ -2937,6 +3003,7 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { return new double[] { @@ -20374,7 +20301,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps15.getAverage() -@@ -2919,6 +2986,18 @@ public final class CraftServer implements Server { +@@ -2983,6 +3050,18 @@ public final class CraftServer implements Server { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } @@ -20393,7 +20320,7 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 @Override public void restart() { org.spigotmc.RestartCommand.restart(); -@@ -3132,4 +3211,16 @@ public final class CraftServer implements Server { +@@ -3201,4 +3280,16 @@ public final class CraftServer implements Server { } // Paper end @@ -20411,10 +20338,10 @@ index 7f2f4f3d804832e314983ba78fe9c6cc3cfcdb1f..a7081f2ce7e001c9a75b620c55703a02 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 0e670de77a7f9926e295e1dd63d909bed1a959ca..52b48e40c3ee5f483c6cb04409459cf25abc3f0d 100644 +index 90c76ddcb8af13409490b8976263d27a71954668..bc9a049df648fa5a169219bb009c92a213df9ffd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2289,6 +2289,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2354,6 +2354,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } @@ -20464,10 +20391,10 @@ index 0e670de77a7f9926e295e1dd63d909bed1a959ca..52b48e40c3ee5f483c6cb04409459cf2 public PersistentDataContainer getPersistentDataContainer() { return this.persistentDataContainer; diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index e4cacb17f56c618bef19e1165c07aac86af61150..01f581e6c3dfacb0ec6aff05c08539bbd2e580c7 100644 +index c737c5d62407337d3db2899cfc01713a058a6467..d41f9c4a3c992b5dadacb4fcb1107235fff79fa8 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -173,6 +173,20 @@ public class Main { +@@ -174,6 +174,20 @@ public class Main { .describedAs("Jar file"); // Paper end @@ -20479,16 +20406,16 @@ index e4cacb17f56c618bef19e1165c07aac86af61150..01f581e6c3dfacb0ec6aff05c08539bb + .describedAs("Yml file"); + + acceptsAll(asList("pufferfish", "pufferfish-settings"), "File for pufferfish settings") -+ .withRequiredArg() -+ .ofType(File.class) -+ .defaultsTo(new File("pufferfish.yml")) -+ .describedAs("Yml file"); ++ .withRequiredArg() ++ .ofType(File.class) ++ .defaultsTo(new File("pufferfish.yml")) ++ .describedAs("Yml file"); + // Purpur end + // Paper start acceptsAll(asList("server-name"), "Name of the server") .withRequiredArg() -@@ -292,7 +306,7 @@ public class Main { +@@ -293,7 +307,7 @@ public class Main { System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper } @@ -20498,7 +20425,7 @@ index e4cacb17f56c618bef19e1165c07aac86af61150..01f581e6c3dfacb0ec6aff05c08539bb Calendar deadline = Calendar.getInstance(); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java -index 2b906fccdb0a5ecddaf487ee931d05b511f84351..2bf30db1c4af5291edc19451108437a39d9a6ec8 100644 +index 2e51fab98d95c93d2095f7be6dbb5d5474158bfb..32285c8e0f42897793759fba85a1e8658750c843 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java @@ -16,8 +16,15 @@ import org.bukkit.entity.Bee; @@ -20510,23 +20437,14 @@ index 2b906fccdb0a5ecddaf487ee931d05b511f84351..2bf30db1c4af5291edc19451108437a3 public CraftBeehive(World world, BeehiveBlockEntity tileEntity) { super(world, tileEntity); + // Purpur start - load bees to be able to modify them individually -+ for(BeehiveBlockEntity.BeeData data : getSnapshot().getStored()) { ++ for(BeehiveBlockEntity.BeeData data : tileEntity.getStored()) { + storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(data, this)); + } + // Purpur end } protected CraftBeehive(CraftBeehive state) { -@@ -70,20 +77,61 @@ public class CraftBeehive extends CraftBlockEntityState impl - List bees = new ArrayList<>(); - - if (isPlaced()) { -- BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getTileEntityFromWorld()); -- for (Entity bee : beehive.releaseBees(this.getHandle(), BeeReleaseStatus.BEE_RELEASED, true)) { -+ // Purpur start - change which releaseBees method is called, and use beehive snapshot -+ BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getSnapshot()); -+ for (Entity bee : beehive.releaseBees(this.getHandle(), world.getHandle(), BeeReleaseStatus.BEE_RELEASED, true)) { -+ // Purpur end +@@ -75,15 +82,54 @@ public class CraftBeehive extends CraftBlockEntityState impl bees.add((Bee) bee.getBukkitEntity()); } } @@ -20545,10 +20463,10 @@ index 2b906fccdb0a5ecddaf487ee931d05b511f84351..2bf30db1c4af5291edc19451108437a3 + } + + if(isPlaced()) { -+ BeehiveBlockEntity beehive = this.getSnapshot(); ++ BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getTileEntityFromWorld()); + BeehiveBlockEntity.BeeData data = ((org.purpurmc.purpur.entity.PurpurStoredBee) entity).getHandle(); + -+ List list = beehive.releaseBee(getHandle(), getWorldHandle().getMinecraftWorld(), data, BeeReleaseStatus.BEE_RELEASED, true); ++ List list = beehive.releaseBee(getHandle(), data, BeeReleaseStatus.BEE_RELEASED, true); + + if (list.size() == 1) { + storage.remove(entity); @@ -20570,11 +20488,12 @@ index 2b906fccdb0a5ecddaf487ee931d05b511f84351..2bf30db1c4af5291edc19451108437a3 public void addEntity(Bee entity) { Preconditions.checkArgument(entity != null, "Entity must not be null"); -+ int length = getSnapshot().getStored().size(); // Purpur - getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); +- this.getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); ++ int length = this.getSnapshot().getStored().size(); // Purpur ++ getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); + + // Purpur start - check if new bee was added, and if yes, add to stored bees -+ List s = getSnapshot().getStored(); ++ List s = this.getSnapshot().getStored(); + if(length < s.size()) { + storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(s.get(s.size() - 1), this)); + } @@ -20582,7 +20501,7 @@ index 2b906fccdb0a5ecddaf487ee931d05b511f84351..2bf30db1c4af5291edc19451108437a3 } @Override -@@ -95,6 +143,7 @@ public class CraftBeehive extends CraftBlockEntityState impl +@@ -95,6 +141,7 @@ public class CraftBeehive extends CraftBlockEntityState impl @Override public void clearEntities() { getSnapshot().clearBees(); @@ -20618,7 +20537,7 @@ index 4e56018b64d11f76c8da43fd8f85c6de72204e36..9607675e6c5bff2183c4420d11fc63ee @Override diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -index 3d0ce0803e1da8a2681a3cb41096ac942ece54a1..bcd075a771c7f43c6d1549aeec2ccb20ee168b57 100644 +index 21e83238a0bad86ffacf60d5c5612771a49ef33d..a38149b8883195736ec6093aeb54971a89ec056c 100644 --- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java +++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -59,6 +59,7 @@ public class CraftEnchantment extends Enchantment { @@ -20649,7 +20568,7 @@ index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..985e9ec21c60a1f47973bd5fc53b96a6 // Paper start @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index e932cfac619c30b8c7444a9fa41e0403a6eadf6a..236d753266943d8c64e1329336d28c50109d0886 100644 +index 9f843b89dc20b91bf7243facee8486d525e4a1b3..aa8efff39ca3b2c2ed69a19f1872a295b7103c6b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -223,6 +223,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @@ -20685,7 +20604,7 @@ index e932cfac619c30b8c7444a9fa41e0403a6eadf6a..236d753266943d8c64e1329336d28c50 return false; } -@@ -1506,4 +1525,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1538,4 +1557,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getScoreboardName(); } // Paper end - entity scoreboard name @@ -20714,7 +20633,7 @@ index e932cfac619c30b8c7444a9fa41e0403a6eadf6a..236d753266943d8c64e1329336d28c50 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 017e97c1618b8ee4640b36a0ec1b07026047bfc3..cf124ad445fd5e8adb1114aca5113e274d950a4a 100644 +index aefb9879b2edadfb4b21d80135d713b9d34c9941..2a534391e49c0653fd98fe5c22e474ae7e82feef 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -266,6 +266,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -20726,7 +20645,7 @@ index 017e97c1618b8ee4640b36a0ec1b07026047bfc3..cf124ad445fd5e8adb1114aca5113e27 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java -index 75d10b5322eb0a62bce2855c04a5151eb857d7de..208018981a2a5666c455eb34614b03f617354165 100644 +index 63cae1a2e95d8da17c45c4404a8dd0ca6a413c39..966587c2788b5c93be83259ddc962a89cde7cbaa 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java @@ -27,4 +27,17 @@ public class CraftIronGolem extends CraftGolem implements IronGolem { @@ -20748,10 +20667,10 @@ index 75d10b5322eb0a62bce2855c04a5151eb857d7de..208018981a2a5666c455eb34614b03f6 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -index 5e83fabb20bc2b0668cbf48530053ca1bb9092f3..4ffb4046b63cbc140c76721f51c9a7a09e81844d 100644 +index f444e843535ec68ede0f05e7e7ef182ce872342b..f03a6fad31b240722a2b944d91282412cf79d884 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -@@ -154,4 +154,51 @@ public class CraftItem extends CraftEntity implements Item { +@@ -151,4 +151,51 @@ public class CraftItem extends CraftEntity implements Item { public String toString() { return "CraftItem"; } @@ -20759,27 +20678,27 @@ index 5e83fabb20bc2b0668cbf48530053ca1bb9092f3..4ffb4046b63cbc140c76721f51c9a7a0 + // Purpur start + @Override + public void setImmuneToCactus(boolean immuneToCactus) { -+ item.immuneToCactus = immuneToCactus; ++ this.getHandle().immuneToCactus = immuneToCactus; + } + + @Override + public boolean isImmuneToCactus() { -+ return item.immuneToCactus; ++ return this.getHandle().immuneToCactus; + } + + @Override + public void setImmuneToExplosion(boolean immuneToExplosion) { -+ item.immuneToExplosion = immuneToExplosion; ++ this.getHandle().immuneToExplosion = immuneToExplosion; + } + + @Override + public boolean isImmuneToExplosion() { -+ return item.immuneToExplosion; ++ return this.getHandle().immuneToExplosion; + } + + @Override + public void setImmuneToFire(@org.jetbrains.annotations.Nullable Boolean immuneToFire) { -+ item.immuneToFire = (immuneToFire != null && immuneToFire); ++ this.getHandle().immuneToFire = (immuneToFire != null && immuneToFire); + } + + @Override @@ -20789,22 +20708,22 @@ index 5e83fabb20bc2b0668cbf48530053ca1bb9092f3..4ffb4046b63cbc140c76721f51c9a7a0 + + @Override + public boolean isImmuneToFire() { -+ return item.immuneToFire; ++ return this.getHandle().immuneToFire; + } + + @Override + public void setImmuneToLightning(boolean immuneToLightning) { -+ item.immuneToLightning = immuneToLightning; ++ this.getHandle().immuneToLightning = immuneToLightning; + } + + @Override + public boolean isImmuneToLightning() { -+ return item.immuneToLightning; ++ return this.getHandle().immuneToLightning; + } + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index fe2124694eb080cab685a1ce1f6a66e2fcdf6a17..465e63a5849e224d86e82ef6c31c99846245e63b 100644 +index 6be370a2be88aac6e229210ef625380171504693..9c94fd78cbd0d3ef0c4dd3678262126b6ed2847b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -453,7 +453,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @@ -20820,29 +20739,11 @@ index fe2124694eb080cab685a1ce1f6a66e2fcdf6a17..465e63a5849e224d86e82ef6c31c9984 @Override public boolean addPotionEffect(PotionEffect effect, boolean force) { org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper -- this.getHandle().addEffect(new MobEffectInstance(CraftPotionEffectType.bukkitToMinecraft(effect.getType()), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.hasIcon()), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon +- this.getHandle().addEffect(CraftPotionUtil.fromBukkit(effect), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon + this.getHandle().addEffect(new MobEffectInstance(CraftPotionEffectType.bukkitToMinecraft(effect.getType()), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.hasIcon(), effect.getKey()), EntityPotionEffectEvent.Cause.PLUGIN); // Purpur - add key // Paper - Don't ignore icon return true; } -@@ -486,7 +486,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - @Override - public PotionEffect getPotionEffect(PotionEffectType type) { - MobEffectInstance handle = this.getHandle().getEffect(CraftPotionEffectType.bukkitToMinecraft(type)); -- return (handle == null) ? null : new PotionEffect(CraftPotionEffectType.minecraftToBukkit(handle.getEffect()), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isVisible()); -+ return (handle == null) ? null : new PotionEffect(CraftPotionEffectType.minecraftToBukkit(handle.getEffect()), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isVisible(), handle.getKey()); // Purpur - add key - } - - @Override -@@ -498,7 +498,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - public Collection getActivePotionEffects() { - List effects = new ArrayList(); - for (MobEffectInstance handle : this.getHandle().activeEffects.values()) { -- effects.add(new PotionEffect(CraftPotionEffectType.minecraftToBukkit(handle.getEffect()), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isVisible())); -+ effects.add(new PotionEffect(CraftPotionEffectType.minecraftToBukkit(handle.getEffect()), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isVisible(), handle.getKey())); // Purpur - add key - } - return effects; - } @@ -912,7 +912,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return EntityCategory.WATER; } @@ -20852,7 +20753,7 @@ index fe2124694eb080cab685a1ce1f6a66e2fcdf6a17..465e63a5849e224d86e82ef6c31c9984 } @Override -@@ -1099,4 +1099,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1115,4 +1115,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { getHandle().knockback(strength, directionX, directionZ); }; // Paper end @@ -20907,7 +20808,7 @@ index 0ad16ee7b33582d214dab41eeee378d52c8e38ed..16bd1294c219f15ada653ef810bc2d74 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e188bb3ba5d2ec28421947c0b66b25eecb569bfe..28910943e5efcdf24865b961fba161b7d1e4a8f5 100644 +index 3a792ddc31e76038b84e8f87088c4cd94c349138..3b3bbeda831f82b6d9b284d85a31a1fff578a64f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -519,10 +519,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -20920,14 +20821,14 @@ index e188bb3ba5d2ec28421947c0b66b25eecb569bfe..28910943e5efcdf24865b961fba161b7 + public void setPlayerListName(String name, boolean useMM) { + // Purpur end if (name == null) { - name = getName(); + name = this.getName(); } -- this.getHandle().listName = name.equals(getName()) ? null : CraftChatMessage.fromStringOrNull(name); -+ this.getHandle().listName = name.equals(getName()) ? null : useMM ? io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name)) : CraftChatMessage.fromStringOrNull(name); // Purpur - for (ServerPlayer player : (List) server.getHandle().players) { +- this.getHandle().listName = name.equals(this.getName()) ? null : CraftChatMessage.fromStringOrNull(name); ++ this.getHandle().listName = name.equals(this.getName()) ? null : useMM ? io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name)) : CraftChatMessage.fromStringOrNull(name); // Purpur + for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { player.connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, this.getHandle())); -@@ -1352,6 +1357,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1358,6 +1363,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API @@ -20938,7 +20839,7 @@ index e188bb3ba5d2ec28421947c0b66b25eecb569bfe..28910943e5efcdf24865b961fba161b7 return false; } -@@ -2512,6 +2521,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2518,6 +2527,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -20967,7 +20868,7 @@ index e188bb3ba5d2ec28421947c0b66b25eecb569bfe..28910943e5efcdf24865b961fba161b7 private void validateSpeed(float value) { Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); } -@@ -3283,4 +3314,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3303,4 +3334,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.spigot; } // Spigot end @@ -21039,7 +20940,7 @@ index e188bb3ba5d2ec28421947c0b66b25eecb569bfe..28910943e5efcdf24865b961fba161b7 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java -index e4a14cdfeb91a3d32e622d27d612605b1bca08e2..898d934aafd6066df45f02fe3406fa83f79b745c 100644 +index 4ce2373ff71c3c1b8951646e057587a3ab09e145..4f7f6cf6ca24406570d2d29dc63dc89401119961 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java @@ -28,4 +28,17 @@ public class CraftSnowman extends CraftGolem implements Snowman, com.destroystok @@ -21061,7 +20962,7 @@ index e4a14cdfeb91a3d32e622d27d612605b1bca08e2..898d934aafd6066df45f02fe3406fa83 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index a67b5d20b956e0bf801c9eeb9330567c21927010..15c7dd5ae4ea040b91b665e5ce05c0d35ab1604e 100644 +index 6c15d40979fd3e3d246a447c432b321fbf29ada3..6ace76a829c88e2e747dbbcce0a6582c615fc56d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -252,4 +252,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { @@ -21077,7 +20978,7 @@ index a67b5d20b956e0bf801c9eeb9330567c21927010..15c7dd5ae4ea040b91b665e5ce05c0d3 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java -index 5a97c92f9b044d8ab7bd3346ceb464455a09046e..e30d8b80734f04b1fa89e8a3cef666116fd7366c 100644 +index 7a8ce6956db56061af93ba9761f5d1057a90bc49..6d286b23806666f7b00ac88c5922144649f8a041 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java @@ -99,4 +99,17 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok @@ -21099,7 +21000,7 @@ index 5a97c92f9b044d8ab7bd3346ceb464455a09046e..e30d8b80734f04b1fa89e8a3cef66611 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -index e16459c9cfcac790edd6d912750d32c68387cbbc..890938ad866e2c588f3f819230ba121b0b436401 100644 +index 38b6d2c377800134de592a780b737b45c8096a11..449acd9dc983be1cd51208bc8f8d843d2ddaa923 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -57,4 +57,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { @@ -21120,10 +21021,10 @@ index e16459c9cfcac790edd6d912750d32c68387cbbc..890938ad866e2c588f3f819230ba121b + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 50fed722bbba5c663e4be33a179ea75dfa2dd9e9..c3eaef001e6d7be7f16977c3f539d5d4a478c734 100644 +index 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773b8ce45df 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -592,6 +592,15 @@ public class CraftEventFactory { +@@ -594,6 +594,15 @@ public class CraftEventFactory { // Paper end craftServer.getPluginManager().callEvent(event); @@ -21139,7 +21040,7 @@ index 50fed722bbba5c663e4be33a179ea75dfa2dd9e9..c3eaef001e6d7be7f16977c3f539d5d4 return event; } -@@ -1033,6 +1042,7 @@ public class CraftEventFactory { +@@ -1071,6 +1080,7 @@ public class CraftEventFactory { damageCause = DamageCause.ENTITY_EXPLOSION; } event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions, source.isCritical()); // Paper - add critical damage API @@ -21147,7 +21048,7 @@ index 50fed722bbba5c663e4be33a179ea75dfa2dd9e9..c3eaef001e6d7be7f16977c3f539d5d4 } event.setCancelled(cancelled); -@@ -1147,6 +1157,7 @@ public class CraftEventFactory { +@@ -1185,6 +1195,7 @@ public class CraftEventFactory { } else { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } @@ -21155,7 +21056,7 @@ index 50fed722bbba5c663e4be33a179ea75dfa2dd9e9..c3eaef001e6d7be7f16977c3f539d5d4 return event; } -@@ -1210,6 +1221,7 @@ public class CraftEventFactory { +@@ -1248,6 +1259,7 @@ public class CraftEventFactory { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions, critical); // Paper - add critical damage API @@ -21164,7 +21065,7 @@ index 50fed722bbba5c663e4be33a179ea75dfa2dd9e9..c3eaef001e6d7be7f16977c3f539d5d4 event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -index 633e6f4922ccaf59979a22885162f42c65bf628a..15001e7c8eae3a89f9d8669be532d56b70d538ef 100644 +index b4bd318d61834d70d666577073f18e4c49ded113..a35f60b01b371673023bd23f47a8ddafd38787f2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -181,8 +181,19 @@ public class CraftContainer extends AbstractContainerMenu { @@ -21202,7 +21103,7 @@ index 471ae4458e7ea7c29d7551b32cec98180fbccd4e..23db63c78e9fcf86cd498b3ed36ca502 for (int i = 0; i < this.getSize(); i++) { if (i >= items.length) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java -index 88d3ca586ff6905f18a8ab9f0e229f440ed44088..27dd4eb4781a3c75772860c11db886e1038cecd2 100644 +index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe1ff08a28 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -9,7 +9,7 @@ import org.bukkit.inventory.AnvilInventory; @@ -21216,7 +21117,7 @@ index 88d3ca586ff6905f18a8ab9f0e229f440ed44088..27dd4eb4781a3c75772860c11db886e1 super(inventory, resultInventory); @@ -57,4 +57,26 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn Preconditions.checkArgument(levels >= 0, "Maximum repair cost must be positive (or 0)"); - container.maximumRepairCost = levels; + this.container.maximumRepairCost = levels; } + + // Purpur start @@ -21239,13 +21140,35 @@ index 88d3ca586ff6905f18a8ab9f0e229f440ed44088..27dd4eb4781a3c75772860c11db886e1 + public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { + container.canDoUnsafeEnchants = canDoUnsafeEnchants; + } ++ // Purpur end + } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +index 9469b0d5d8a46ac17c3998a4b537a4feb1deb3b0..cf7b65ec3fac111b607f11d08aee8f11873a04fd 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +@@ -599,4 +599,17 @@ public final class CraftItemFactory implements ItemFactory { + return CraftItemStack.asCraftMirror(enchanted); + } + // Paper end - enchantWithLevels API ++ ++ // Purpur start ++ @Override ++ public @org.jetbrains.annotations.NotNull java.util.List getHoverLines(@org.jetbrains.annotations.NotNull ItemStack itemStack, boolean advanced) { ++ return io.papermc.paper.adventure.PaperAdventure.asAdventure( ++ CraftItemStack.asNMSCopy(itemStack).getTooltipLines( ++ null, ++ advanced ? net.minecraft.world.item.TooltipFlag.ADVANCED ++ : net.minecraft.world.item.TooltipFlag.NORMAL ++ ) ++ ); ++ } + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -index 5a71efd27180004ee91495d9255867dbdfa1783e..1dcc3405393d11836a21aa16e435be64c04f6e7d 100644 +index bac3a5c378054481e1a5abaec1f83afde5d64ac1..f1050bf2b9efc54a894426b08989d44566acd875 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -@@ -43,6 +43,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -45,6 +45,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { static final ItemMetaKey POTION_COLOR = new ItemMetaKey("CustomPotionColor", "custom-color"); static final ItemMetaKey ID = new ItemMetaKey("id", "potion-id"); static final ItemMetaKey DEFAULT_POTION = new ItemMetaKey("Potion", "potion-type"); @@ -21253,34 +21176,34 @@ index 5a71efd27180004ee91495d9255867dbdfa1783e..1dcc3405393d11836a21aa16e435be64 // Having an initial "state" in ItemMeta seems bit dirty but the UNCRAFTABLE potion type // is treated as the empty form of the meta because it represents an empty potion with no effect -@@ -92,7 +93,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - boolean ambient = effect.getBoolean(AMBIENT.NBT); - boolean particles = effect.contains(SHOW_PARTICLES.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(SHOW_PARTICLES.NBT) : true; - boolean icon = effect.contains(SHOW_ICON.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(SHOW_ICON.NBT) : particles; +@@ -97,7 +98,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { + boolean ambient = effect.getBoolean(CraftMetaPotion.AMBIENT.NBT); + boolean particles = effect.contains(CraftMetaPotion.SHOW_PARTICLES.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(CraftMetaPotion.SHOW_PARTICLES.NBT) : true; + boolean icon = effect.contains(CraftMetaPotion.SHOW_ICON.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(CraftMetaPotion.SHOW_ICON.NBT) : particles; - this.customEffects.add(new PotionEffect(type, duration, amp, ambient, particles, icon)); + // Purpur start + NamespacedKey key = null; -+ if (tag.contains(KEY.NBT)) { -+ key = NamespacedKey.fromString(effect.getString(KEY.NBT)); ++ if (tag.contains(CraftMetaPotion.KEY.NBT)) { ++ key = NamespacedKey.fromString(effect.getString(CraftMetaPotion.KEY.NBT)); + } + this.customEffects.add(new PotionEffect(type, duration, amp, ambient, particles, icon, key)); + // Purpur end } } } -@@ -139,6 +146,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - effectData.putBoolean(AMBIENT.NBT, effect.isAmbient()); - effectData.putBoolean(SHOW_PARTICLES.NBT, effect.hasParticles()); - effectData.putBoolean(SHOW_ICON.NBT, effect.hasIcon()); +@@ -150,6 +157,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { + effectData.putBoolean(CraftMetaPotion.AMBIENT.NBT, effect.isAmbient()); + effectData.putBoolean(CraftMetaPotion.SHOW_PARTICLES.NBT, effect.hasParticles()); + effectData.putBoolean(CraftMetaPotion.SHOW_ICON.NBT, effect.hasIcon()); + // Purpur start + if (effect.hasKey()) { -+ effectData.putString(KEY.NBT, effect.getKey().toString()); ++ effectData.putString(CraftMetaPotion.KEY.NBT, effect.getKey().toString()); + } + // Purpur end effectList.add(effectData); } } -@@ -200,7 +212,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -225,7 +237,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { if (index != -1) { if (overwrite) { PotionEffect old = this.customEffects.get(index); @@ -21314,7 +21237,7 @@ index 2677e21d8239bf0361a3bc5c9a50c328e54d70f6..544a79d5da661aff19e2019f7b83a3a4 if (MinecraftServer.getServer() != null && MinecraftServer.getServer().isDebugging()) { new Exception().printStackTrace(); diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java -index 2d2bf5c37709b8e747fbfa2db5ce86f258e86224..f6413ab181208d729afb532dca5e96e4c938e83c 100644 +index 15e9dd8844f893de5e8372b847c9e8295d6f69ca..b4b105c0190502328d5aeb680dd8e67c2875618f 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java @@ -46,4 +46,10 @@ public class CraftMapRenderer extends MapRenderer { @@ -21329,29 +21252,29 @@ index 2d2bf5c37709b8e747fbfa2db5ce86f258e86224..f6413ab181208d729afb532dca5e96e4 + // Purpur - end } diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java -index 354393cbf0f113f14e936b40da56125a3130cbd9..a1ef7ecdf272546bdd76bb4b2ecd86a69c51c777 100644 +index 844fb8c662a409670f631228f687d85c5436d3dd..2bfa5908f1848702ceb42da7576a609d0928eddd 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java -@@ -101,7 +101,7 @@ public class CraftPotionUtil { +@@ -73,7 +73,7 @@ public class CraftPotionUtil { public static MobEffectInstance fromBukkit(PotionEffect effect) { MobEffect type = CraftPotionEffectType.bukkitToMinecraft(effect.getType()); -- return new MobEffectInstance(type, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles()); -+ return new MobEffectInstance(type, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.getKey()); // Purpur - add key +- return new MobEffectInstance(type, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.hasIcon()); // Paper ++ return new MobEffectInstance(type, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.hasIcon(), effect.getKey()); // Paper // Purpur - add key } public static PotionEffect toBukkit(MobEffectInstance effect) { -@@ -110,7 +110,7 @@ public class CraftPotionUtil { +@@ -82,7 +82,7 @@ public class CraftPotionUtil { int duration = effect.getDuration(); boolean ambient = effect.isAmbient(); boolean particles = effect.isVisible(); -- return new PotionEffect(type, duration, amp, ambient, particles); -+ return new PotionEffect(type, duration, amp, ambient, particles, effect.getKey()); // Purpur - add key +- return new PotionEffect(type, duration, amp, ambient, particles, effect.showIcon()); // Paper ++ return new PotionEffect(type, duration, amp, ambient, particles, effect.showIcon(), effect.getKey()); // Paper // Purpur - add key } public static boolean equals(MobEffect mobEffect, PotionEffectType type) { diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index d7ce4971d9271dbeff4adb9d852e4e7bdf60bf03..a4567188e2fe3f922bb6aeb71a2845d1a1be536f 100644 +index 700932b65e4fda560d684b0aa079bcee3923f73e..7902c649a54fccbb13531c01e052df87ec4a424a 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -501,7 +501,7 @@ public class CraftScheduler implements BukkitScheduler { @@ -21395,7 +21318,7 @@ index d7ce4971d9271dbeff4adb9d852e4e7bdf60bf03..a4567188e2fe3f922bb6aeb71a2845d1 private boolean isReady(final int currentTick) { diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -index 3f45bab0e9f7b3697e6d9d1092a1e6e579f7066f..4f1cf281c4bf68c37982d390da8779dea78dab18 100644 +index ea26d9464644b5217879b8c21b4da28e57708dcb..5835dc236b3f5291a804f7fb14a12eb466d4e0ba 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java @@ -96,13 +96,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot @@ -21415,7 +21338,7 @@ index 3f45bab0e9f7b3697e6d9d1092a1e6e579f7066f..4f1cf281c4bf68c37982d390da8779de long getCreatedAt() { diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index 7a2f46579352870cfbb32c343d7c68919758ffe3..60b8331a4327cc276b88420254495455babbe3b0 100644 +index 891f850ea99dac1433f3e395e26be14c8abf2bfb..280ed3a3b61b3eadbb6f253cd4e058641e2c3d2e 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -115,7 +115,7 @@ public final class CraftScoreboardManager implements ScoreboardManager { @@ -21437,10 +21360,10 @@ index 7a2f46579352870cfbb32c343d7c68919758ffe3..60b8331a4327cc276b88420254495455 // Paper end - add timings for scoreboard search } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 031e5acee0061d7f8050ea3a42f33b42112a3172..6eac7fcbc1c372675322c49f5557bf6be4dd1c31 100644 +index 397c10f64db3a4d7296fe18585b56851bc3a1f01..1e81801e5701b08feedd840c1e1663ae26507c16 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -452,7 +452,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -485,7 +485,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { @@ -21463,7 +21386,7 @@ index 80553face9c70c2a3d897681e7761df85b22d464..99597258e8e88cd9e2c901c4ac3ff7fa if (stream != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java -index 74ffea16027ba8eaa26716c3b6b78a8e83c9ed79..30567935db66eaa23614ad143cd8a45c596cae26 100644 +index ea732f8fe7b5dd56aab5d3a061a1cad19c49ae0b..8d2b0dc792120eda396947f5935052346f770567 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java +++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java @@ -23,7 +23,15 @@ public final class CommandPermissions { @@ -22146,10 +22069,10 @@ index 0000000000000000000000000000000000000000..3633574e112f217b412217dd243a631d +} diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c470de5ba2 +index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8cefe0226 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3235 @@ +@@ -0,0 +1,3241 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -22297,6 +22220,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + public boolean rainStopsAfterSleep = true; + public boolean thunderStopsAfterSleep = true; + public int mobLastHurtByPlayerTime = 100; ++ public boolean disableOxidationProximityPenalty = false; + private void miscGameplayMechanicsSettings() { + useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); + mendingMultiplier = getDouble("gameplay-mechanics.mending-multiplier", mendingMultiplier); @@ -22325,6 +22249,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + rainStopsAfterSleep = getBoolean("gameplay-mechanics.rain-stops-after-sleep", rainStopsAfterSleep); + thunderStopsAfterSleep = getBoolean("gameplay-mechanics.thunder-stops-after-sleep", thunderStopsAfterSleep); + mobLastHurtByPlayerTime = getInt("gameplay-mechanics.mob-last-hurt-by-player-time", mobLastHurtByPlayerTime); ++ disableOxidationProximityPenalty = getBoolean("gameplay-mechanics.disable-oxidation-proximity-penalty", disableOxidationProximityPenalty); + } + + public int daytimeTicks = 12000; @@ -24669,6 +24594,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + } + } + ++ public boolean skeletonHorseRidable = false; + public boolean skeletonHorseRidableInWater = true; + public boolean skeletonHorseCanSwim = false; + public double skeletonHorseMaxHealthMin = 15.0D; @@ -24680,6 +24606,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + public boolean skeletonHorseTakeDamageFromWater = false; + public boolean skeletonHorseAlwaysDropExp = false; + private void skeletonHorseSettings() { ++ skeletonHorseRidable = getBoolean("mobs.skeleton_horse.ridable", skeletonHorseRidable); + skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); + skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); + if (PurpurConfig.version < 10) { @@ -25244,6 +25171,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + zombieHeadVisibilityPercent = getDouble("mobs.zombie.head-visibility-percent", zombieHeadVisibilityPercent); + } + ++ public boolean zombieHorseRidable = false; + public boolean zombieHorseRidableInWater = false; + public boolean zombieHorseCanSwim = false; + public double zombieHorseMaxHealthMin = 15.0D; @@ -25256,6 +25184,7 @@ index 0000000000000000000000000000000000000000..d4d9f748d259df8b6f4566efa21c15c4 + public boolean zombieHorseTakeDamageFromWater = false; + public boolean zombieHorseAlwaysDropExp = false; + private void zombieHorseSettings() { ++ zombieHorseRidable = getBoolean("mobs.zombie_horse.ridable", zombieHorseRidable); + zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); + zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); + if (PurpurConfig.version < 10) { @@ -27650,7 +27579,7 @@ index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index acde675a8f1b84b686d53084d66dece3ad5f940e..062a793a134f774ebf918aab10443527c06c4fd1 100644 +index c0333ba8e57cd284bb8ab15181da6b39d55872f9..0b03dae85e6008283e68b07fa438daccf0e4f5fa 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -15,6 +15,7 @@ import net.minecraft.world.entity.ambient.AmbientCreature; @@ -27678,7 +27607,7 @@ index acde675a8f1b84b686d53084d66dece3ad5f940e..062a793a134f774ebf918aab10443527 // Paper start int worldHeight = world.getHeight(); ActivationRange.maxBB = player.getBoundingBox().inflate( maxRange, worldHeight, maxRange ); -@@ -247,7 +249,7 @@ public class ActivationRange +@@ -248,7 +250,7 @@ public class ActivationRange } // Paper end } @@ -27687,7 +27616,7 @@ index acde675a8f1b84b686d53084d66dece3ad5f940e..062a793a134f774ebf918aab10443527 } /** -@@ -400,6 +402,7 @@ public class ActivationRange +@@ -401,6 +403,7 @@ public class ActivationRange */ public static boolean checkIfActive(Entity entity) { @@ -27696,7 +27625,7 @@ index acde675a8f1b84b686d53084d66dece3ad5f940e..062a793a134f774ebf918aab10443527 if ( entity instanceof FireworkRocketEntity ) { return true; diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java -index bf970bf3356a914459c2d6db93537ce2d32c7e18..08221c7256f41ca511a4a61ffb2b979325aebee9 100644 +index 9eb2823cc8f83bad2626fc77578b0162d9ed5782..5da1ef6d90c6a5bd047e971bcc56d786239c6fd8 100644 --- a/src/main/java/org/spigotmc/TicksPerSecondCommand.java +++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java @@ -39,7 +39,7 @@ public class TicksPerSecondCommand extends Command @@ -27709,7 +27638,7 @@ index bf970bf3356a914459c2d6db93537ce2d32c7e18..08221c7256f41ca511a4a61ffb2b9793 sender.sendMessage(builder.asComponent()); if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) { diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 50c72e5db369a180f425eaaa0411cb8871bc3463..dbd502761ff6e6efb252bb41376a7ff028c73895 100644 +index 40dcdf6885e99b26283a9ea2bd4d4bf6ec358e71..5fc8cc40ab627eba0b2110c73d31af213a935733 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -96,7 +96,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa @@ -28345,7 +28274,7 @@ index afeb4271fffb7546209f1e651214065187c88302..81bc3af856b8af019fd13e1da1f7cccd ); diff --git a/src/test/java/org/bukkit/potion/PotionTest.java b/src/test/java/org/bukkit/potion/PotionTest.java -index 70a655df7195da8e037c22064c4ebfe5d771e884..cfdf155af7ec29dd221989edbd8623d27529f9e6 100644 +index 8963d93e99bdaf719fa160c11dd5af6a1d86f9a4..d852d8b14f5000415cbb4f06601059b3934b7efc 100644 --- a/src/test/java/org/bukkit/potion/PotionTest.java +++ b/src/test/java/org/bukkit/potion/PotionTest.java @@ -9,6 +9,7 @@ import net.minecraft.resources.ResourceLocation; diff --git a/patches/server/0003-MC-Dev-fixes.patch b/patches/server/0003-MC-Dev-fixes.patch index fffd4bfd5..f2475de9a 100644 --- a/patches/server/0003-MC-Dev-fixes.patch +++ b/patches/server/0003-MC-Dev-fixes.patch @@ -4,28 +4,8 @@ Date: Tue, 30 May 2023 12:12:29 +0900 Subject: [PATCH] MC Dev fixes -diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index b0b2cbd8d9db1772d43a285eca9060f3879acab0..8cde30544e14f8fc2dac32966ae3c21f8cf3a551 100644 ---- a/src/main/java/com/destroystokyo/paper/Metrics.java -+++ b/src/main/java/com/destroystokyo/paper/Metrics.java -@@ -604,15 +604,6 @@ public class Metrics { - metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size())); - metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() ? "bungee" : "offline"))); // Purpur - metrics.addCustomChart(new Metrics.SimplePie("purpur_version", () -> (org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion() != null) ? org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion() : "unknown")); // Purpur -- final String paperVersion; -- final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion(); -- if (implVersion != null) { -- final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1); -- paperVersion = "git-Pufferfish-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Pufferfish -- } else { -- paperVersion = "unknown"; -- } -- metrics.addCustomChart(new Metrics.SimplePie("pufferfish_version", () -> paperVersion)); // Pufferfish - - metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { - Map> map = new HashMap<>(); diff --git a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java -index 733134401fcba393053c7a2dfa1d0d44f8f79ff5..17d931ef47846b59e28dc0c5b5ae91396a1d3e7d 100644 +index 733134401fcba393053c7a2dfa1d0d44f8f79ff5..79fba35fc74723529bff7d8fdcca7de6407fb5ad 100644 --- a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java +++ b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java @@ -71,14 +71,14 @@ public class LeavesFix extends DataFix { diff --git a/patches/server/0004-Rebrand.patch b/patches/server/0004-Rebrand.patch index 081fd2724..8a02a860b 100644 --- a/patches/server/0004-Rebrand.patch +++ b/patches/server/0004-Rebrand.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Rebrand diff --git a/build.gradle.kts b/build.gradle.kts -index 393dab1ece76e0ca1e0b58c0b2c72d5c1c41a84d..cfb74b11743ce2f7a78a6a8085f9dd05b65a3152 100644 +index f083d422678f5fd21825439944af888fbdc9bf3c..526f25bdf5216dba09d51eca73f38884c106e872 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ val alsoShade: Configuration by configurations.creating @@ -17,7 +17,7 @@ index 393dab1ece76e0ca1e0b58c0b2c72d5c1c41a84d..cfb74b11743ce2f7a78a6a8085f9dd05 implementation("io.papermc.paper:paper-mojangapi:${project.version}") { exclude("io.papermc.paper", "paper-api") } -@@ -87,7 +87,7 @@ tasks.jar { +@@ -93,7 +93,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -153,10 +153,10 @@ index ed3527612315e6e0649182ce4e1ae2834b0918a9..ae02c029f0169d30a34d4a4e65ea6cb4 stringbuilder.append("// "); stringbuilder.append(CrashReport.getErrorComment()); diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 27a238cc56702297c88fde0f379178222ccf6c5b..30fc258faa6f087cf3c91411b48116a3ac416031 100644 +index ec268189b19b6fa5c4521f96ce211a531db35ec5..dc95efdefa3bfbd313aa50b1e5ea17362ab4fc92 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java -@@ -108,6 +108,18 @@ public class Main { +@@ -108,6 +108,17 @@ public class Main { */ // CraftBukkit end try { @@ -171,15 +171,14 @@ index 27a238cc56702297c88fde0f379178222ccf6c5b..30fc258faa6f087cf3c91411b48116a3 + """); + LOGGER.warn("Warning! Plazma may cause unexpected problems, so be sure to test it thoroughly before using it on a public server."); + // Plazma end -+ // Paper start if (Boolean.getBoolean("Paper.isRunDev")) { net.minecraft.server.packs.VanillaPackResourcesBuilder.developmentConfig = builder -> { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8c3942d9ce4f8a102a47bec74af5911760fda4e3..cf9f7d52b07cffd41293ba5a6fab3a7f77a2cf03 100644 +index b61c4d1ebb9c15a7ecd7bec5eb864851c053fb7e..b4d5bca6e3a39186a988098fb5d4cae97a776e79 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -914,7 +914,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Wed, 11 Jan 2023 02:24:51 +0900 +From: AlphaKR93 +Date: Fri, 3 Nov 2023 00:11:50 +0900 Subject: [PATCH] Plazma Configurations -diff --git a/src/main/java/io/papermc/paper/configuration/ConfigurationPart.java b/src/main/java/io/papermc/paper/configuration/ConfigurationPart.java -index 7a4a7a654fe2516ed894a68f2657344df9d70f4c..ae51ab3c895b1b98d768e52b7c446bd6a3e89b9f 100644 ---- a/src/main/java/io/papermc/paper/configuration/ConfigurationPart.java -+++ b/src/main/java/io/papermc/paper/configuration/ConfigurationPart.java -@@ -1,6 +1,6 @@ - package io.papermc.paper.configuration; - --abstract class ConfigurationPart { -+public abstract class ConfigurationPart { // Plazma - package -> public - - public static abstract class Post extends ConfigurationPart { - diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java -index 9ef6712c70fcd8912a79f3f61e351aac09572cf3..b7f44c74089058f261163430762f027aa9a5623a 100644 +index c01b4393439838976965823298f12e4762e72eff..78590919c333f632f602b1c916b12002c9afb89b 100644 --- a/src/main/java/io/papermc/paper/configuration/Configurations.java +++ b/src/main/java/io/papermc/paper/configuration/Configurations.java -@@ -88,7 +88,7 @@ public abstract class Configurations { +@@ -41,6 +41,16 @@ public abstract class Configurations { + protected final String globalConfigFileName; + protected final String defaultWorldConfigFileName; + protected final String worldConfigFileName; ++ // Plazma start ++ @org.jetbrains.annotations.VisibleForTesting ++ public static final java.util.function.Supplier SPIGOT_WORLD_DEFAULTS = com.google.common.base.Suppliers.memoize(() -> new org.spigotmc.SpigotWorldConfig(org.apache.commons.lang.RandomStringUtils.randomAlphabetic(255)) { ++ @Override // override to ensure "verbose" is false ++ public void init() { ++ org.spigotmc.SpigotConfig.readConfig(org.spigotmc.SpigotWorldConfig.class, this); ++ } ++ }); ++ protected static final ContextKey> SPIGOT_WORLD_CONFIG_CONTEXT_KEY = new ContextKey<>(new TypeToken<>() {}, "spigot world config"); ++ // Plazma end + + public Configurations( + final Path globalFolder, +@@ -64,18 +74,34 @@ public abstract class Configurations { + .addConstraint(Constraints.Min.class, Number.class, new Constraints.Min.Factory()); + } + ++ // Plazma start + protected YamlConfigurationLoader.Builder createLoaderBuilder() { +- return ConfigurationLoaders.naturallySorted(); ++ return ConfigurationLoaders.naturallySorted().defaultOptions(Configurations::defaultOptions); + } + +- protected abstract boolean isConfigType(final Type type); ++ protected static ConfigurationOptions defaultOptions(ConfigurationOptions options) { ++ return options.serializers(builder -> builder ++ .register(io.papermc.paper.configuration.serializer.collections.MapSerializer.TYPE, new io.papermc.paper.configuration.serializer.collections.MapSerializer(false)) ++ .register(new io.papermc.paper.configuration.serializer.EnumValueSerializer()) ++ .register(new io.papermc.paper.configuration.serializer.ComponentSerializer()) ++ ); ++ } ++ ++ protected boolean isConfigType(final Type type) { ++ return ConfigurationPart.class.isAssignableFrom(io.leangen.geantyref.GenericTypeReflector.erase(type)); ++ } ++ ++ protected static ObjectMapper.Factory.Builder defaultGlobalFactoryBuilder(ObjectMapper.Factory.Builder builder) { ++ return builder.addDiscoverer(io.papermc.paper.configuration.mapping.InnerClassFieldDiscoverer.globalConfig()); ++ } ++ // Plazma end + + protected abstract int globalConfigVersion(); + + protected abstract int worldConfigVersion(); + + protected ObjectMapper.Factory.Builder createGlobalObjectMapperFactoryBuilder() { +- return this.createObjectMapper(); ++ return defaultGlobalFactoryBuilder(this.createObjectMapper()); // Plazma + } + + @MustBeInvokedByOverriders +@@ -93,7 +119,7 @@ public abstract class Configurations { }; } - static CheckedFunction reloader(Class type, T instance) { -+ public static CheckedFunction reloader(Class type, T instance) { // Plazma - package -> public ++ protected static CheckedFunction reloader(Class type, T instance) { // Plazma - package -> protected return node -> { ObjectMapper.Factory factory = (ObjectMapper.Factory) Objects.requireNonNull(node.options().serializers().get(type)); ObjectMapper.Mutable mutable = (ObjectMapper.Mutable) factory.get(type); -@@ -148,7 +148,7 @@ public abstract class Configurations { - final YamlConfigurationLoader loader = result.loader(); - final ConfigurationNode node = loader.load(); - if (result.isNewFile()) { // add version to new files -- node.node(Configuration.VERSION_FIELD).raw(WorldConfiguration.CURRENT_VERSION); -+ node.node(Configuration.VERSION_FIELD).raw(getWorldConfigurationCurrentVersion()); // Plazma - } - this.applyWorldConfigTransformations(contextMap, node); - final W instance = node.require(this.worldConfigClass); -@@ -207,7 +207,7 @@ public abstract class Configurations { - .build(); - final ConfigurationNode worldNode = worldLoader.load(); - if (newFile) { // set the version field if new file -- worldNode.node(Configuration.VERSION_FIELD).set(WorldConfiguration.CURRENT_VERSION); -+ worldNode.node(Configuration.VERSION_FIELD).set(getWorldConfigurationCurrentVersion()); // Plazma +@@ -154,6 +180,7 @@ public abstract class Configurations { + return ContextMap.builder() + .put(WORLD_NAME, WORLD_DEFAULTS) + .put(WORLD_KEY, WORLD_DEFAULTS_KEY) ++ .put(SPIGOT_WORLD_CONFIG_CONTEXT_KEY, SPIGOT_WORLD_DEFAULTS) // Plazma + .put(REGISTRY_ACCESS, registryAccess); + } + +@@ -194,7 +221,11 @@ public abstract class Configurations { + } + + protected ObjectMapper.Factory.Builder createWorldObjectMapperFactoryBuilder(final ContextMap contextMap) { +- return this.createObjectMapper(); ++ // Plazma start ++ return this.createObjectMapper() ++ .addNodeResolver(new io.papermc.paper.configuration.legacy.RequiresSpigotInitialization.Factory(contextMap.require(SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get())) ++ .addNodeResolver(new NestedSetting.Factory()); ++ // Plazma end + } + + @MustBeInvokedByOverriders +@@ -216,7 +247,7 @@ public abstract class Configurations { + final Path dir = contextMap.require(WORLD_DIRECTORY); + final Path worldConfigFile = dir.resolve(this.worldConfigFileName); + if (Files.notExists(worldConfigFile)) { +- PaperConfigurations.createDirectoriesSymlinkAware(dir); ++ createDirectoriesSymlinkAware(dir); + Files.createFile(worldConfigFile); // create empty file as template + newFile = true; } - this.applyWorldConfigTransformations(contextMap, worldNode); - this.applyDefaultsAwareWorldConfigTransformations(contextMap, worldNode, defaultsNode); -@@ -232,6 +232,21 @@ public abstract class Configurations { +@@ -275,6 +306,39 @@ public abstract class Configurations { return level.convertable.levelDirectory.path().resolve(this.worldConfigFileName); } @@ -57,111 +112,154 @@ index 9ef6712c70fcd8912a79f3f61e351aac09572cf3..b7f44c74089058f261163430762f027a + org.bukkit.configuration.file.YamlConfiguration global = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.globalConfigFileName).toFile()); + org.bukkit.configuration.ConfigurationSection worlds = global.createSection("__________WORLDS__________"); + worlds.set("__defaults__", org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.defaultWorldConfigFileName).toFile())); -+ for (ServerLevel level : server.getAllLevels()) { ++ for (ServerLevel level : server.getAllLevels()) + worlds.set(level.getWorld().getName(), org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(getWorldConfigFile(level).toFile())); -+ } + return global; + } + -+ protected abstract int getWorldConfigurationCurrentVersion(); ++ // Symlinks are not correctly checked in createDirectories ++ protected static void createDirectoriesSymlinkAware(Path path) throws IOException { ++ if (!Files.isDirectory(path)) { ++ Files.createDirectories(path); ++ } ++ } ++ ++ protected static ContextMap createWorldContextMap(ServerLevel level) { ++ return createWorldContextMap(level.convertable.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig, level.registryAccess()); ++ } ++ ++ public static ContextMap createWorldContextMap(Path dir, String levelName, ResourceLocation worldKey, org.spigotmc.SpigotWorldConfig spigotConfig, RegistryAccess registryAccess) { ++ return ContextMap.builder() ++ .put(WORLD_DIRECTORY, dir) ++ .put(WORLD_NAME, levelName) ++ .put(WORLD_KEY, worldKey) ++ .put(SPIGOT_WORLD_CONFIG_CONTEXT_KEY, com.google.common.base.Suppliers.ofInstance(spigotConfig)) ++ .put(REGISTRY_ACCESS, registryAccess) ++ .build(); ++ } + // Plazma end + public static class ContextMap { private static final Object VOID = new Object(); -diff --git a/src/main/java/io/papermc/paper/configuration/InnerClassFieldDiscoverer.java b/src/main/java/io/papermc/paper/configuration/InnerClassFieldDiscoverer.java -index a0aa1f1a7adf986d500a2135aa42e138aa3c4f08..28a1d21900dbff4b9d1887b9aa4e68f4703b778f 100644 ---- a/src/main/java/io/papermc/paper/configuration/InnerClassFieldDiscoverer.java -+++ b/src/main/java/io/papermc/paper/configuration/InnerClassFieldDiscoverer.java -@@ -17,7 +17,7 @@ import java.util.Map; +diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java +index fa1c0aee8c3a4d0868482cf5c703bbfd08e09874..da05e8a339857daa96b062ee64d796556933981f 100644 +--- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java ++++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java +@@ -131,6 +131,7 @@ public class PaperConfigurations extends Configurations SPIGOT_WORLD_DEFAULTS = Suppliers.memoize(() -> new SpigotWorldConfig(RandomStringUtils.randomAlphabetic(255)) { + @Override // override to ensure "verbose" is false +@@ -139,6 +140,7 @@ public class PaperConfigurations extends Configurations> SPIGOT_WORLD_CONFIG_CONTEXT_KEY = new ContextKey<>(new TypeToken>() {}, "spigot world config"); ++ */ // Plazma --final class InnerClassFieldDiscoverer implements FieldDiscoverer> { -+public final class InnerClassFieldDiscoverer implements FieldDiscoverer> { // Plazma - package -> public - private final Map, Object> instanceMap = new HashMap<>(); - private final Map, Object> overrides; -@@ -136,7 +136,19 @@ final class InnerClassFieldDiscoverer implements FieldDiscoverer globalConfig() { -+ public static FieldDiscoverer globalConfig() { // Plazma - package -> public - return new InnerClassFieldDiscoverer(Collections.emptyMap()); ++ /* // Plazma + @Override + protected YamlConfigurationLoader.Builder createLoaderBuilder() { + return super.createLoaderBuilder() +@@ -177,6 +180,7 @@ public class PaperConfigurations extends Configurations plazmaLevelConfiguration(Configurations.ContextMap contextMap) { -+ final Map, Object> overrides = Map.of( -+ org.plazmamc.plazma.configurations.LevelConfigurations.class, -+ new org.plazmamc.plazma.configurations.LevelConfigurations( -+ contextMap.require(Configurations.WORLD_KEY) -+ ) -+ ); -+ return new InnerClassFieldDiscoverer(overrides); -+ } -+ // Plazma end - } -diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -index 9b5c2abaa28fa60cedd9f0111e5eb018f93a0561..c09baea03786075d1a6e3f53d7f9820e23cc57cf 100644 ---- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -+++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -@@ -136,7 +136,7 @@ public class PaperConfigurations extends Configurations> SPIGOT_WORLD_CONFIG_CONTEXT_KEY = new ContextKey<>(new TypeToken>() {}, "spigot world config"); -+ public static final ContextKey> SPIGOT_WORLD_CONFIG_CONTEXT_KEY = new ContextKey<>(new TypeToken>() {}, "spigot world config"); // Plazma - package -> public + } ++ /* // Plazma + @Override + protected boolean isConfigType(final Type type) { + return ConfigurationPart.class.isAssignableFrom(erase(type)); + } ++ */ // Plazma - public PaperConfigurations(final Path globalFolder) { -@@ -308,7 +308,7 @@ public class PaperConfigurations extends Configurations public - return createWorldContextMap(level.convertable.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig); ++ /* // Plazma + private static ContextMap createWorldContextMap(ServerLevel level) { + return createWorldContextMap(level.convertable.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig, level.registryAccess()); + } +@@ -335,6 +344,7 @@ public class PaperConfigurations extends Configurations public + static void createDirectoriesSymlinkAware(Path path) throws IOException { if (!Files.isDirectory(path)) { Files.createDirectories(path); } } -+ -+ // Plazma start -+ protected int getWorldConfigurationCurrentVersion() { -+ return WorldConfiguration.CURRENT_VERSION; -+ } -+ // Plazma end ++ */ // Plazma } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index cf9f7d52b07cffd41293ba5a6fab3a7f77a2cf03..11de2f237e6dd950b8ddba3d5cfe9066d09f0903 100644 +index b4d5bca6e3a39186a988098fb5d4cae97a776e79..389322d3ca9b1f3789271936a7e6c60bd7c27893 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop public - + // Plazma start + @Override + public org.plazmamc.plazma.configurations.PlazmaConfigurations plazmaConfigurations() { @@ -208,32 +315,32 @@ index a9b2c8cd4dcd3f884e4306bebee9334d3848fce5..203c34342f19c6afb3020364baf0cc48 + } + // Plazma end + - public static Services create(YggdrasilAuthenticationService authenticationService, File rootDirectory, File userCacheFile, joptsimple.OptionSet optionSet) throws Exception { // Paper - MinecraftSessionService minecraftSessionService = authenticationService.createMinecraftSessionService(); - GameProfileRepository gameProfileRepository = authenticationService.createProfileRepository(); + @Override + public io.papermc.paper.configuration.PaperConfigurations paperConfigurations() { + return java.util.Objects.requireNonNull(this.paperConfigurations); @@ -32,7 +39,11 @@ public record Services(MinecraftSessionService sessionService, ServicesKeySet se final java.nio.file.Path legacyConfigPath = ((File) optionSet.valueOf("paper-settings")).toPath(); final java.nio.file.Path configDirPath = ((File) optionSet.valueOf("paper-settings-directory")).toPath(); io.papermc.paper.configuration.PaperConfigurations paperConfigurations = io.papermc.paper.configuration.PaperConfigurations.setup(legacyConfigPath, configDirPath, rootDirectory.toPath(), (File) optionSet.valueOf("spigot-settings")); - return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations); + // Plazma start -+ final java.nio.file.Path plazmaConfigurationDirPath = ((File) optionSet.valueOf("plazma-configurations-directory")).toPath(); -+ org.plazmamc.plazma.configurations.PlazmaConfigurations plazmaConfigurations = org.plazmamc.plazma.configurations.PlazmaConfigurations.setup(plazmaConfigurationDirPath); ++ final java.nio.file.Path plazmaConfigDirPath = ((File) optionSet.valueOf("plazma-settings-directory")).toPath(); ++ org.plazmamc.plazma.configurations.PlazmaConfigurations plazmaConfigurations = org.plazmamc.plazma.configurations.PlazmaConfigurations.setup(plazmaConfigDirPath); + return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations, plazmaConfigurations); + // Plazma end // Paper end } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index a9f74eeb5b6300a0b7a940da9c17bd7582b0925d..a970e00482952318c258fc406cb7c39a229b65bc 100644 +index 5c6027a3ab7c52087dfebb1e21468a511ec09fa1..00fbcb941fe393197619762722eb51d62fb073c2 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -209,6 +209,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.util.ObfHelper.INSTANCE.getClass(); // Paper - load mappings for stacktrace deobf and etc. - paperConfigurations.initializeGlobalConfiguration(); - paperConfigurations.initializeWorldDefaultsConfiguration(); -+ plazmaConfigurations.initializeGlobalConfiguration(); // Plazma -+ plazmaConfigurations.initializeWorldDefaultsConfiguration(); // Plazma + paperConfigurations.initializeGlobalConfiguration(this.registryAccess()); + paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); ++ plazmaConfigurations.initializeGlobalConfiguration(this.registryAccess()); // Plazma ++ plazmaConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Plazma // Paper start - moved up to right after PlayerList creation but before file load/save if (this.convertOldUsers()) { this.getProfileCache().save(false); // Paper @@ -241,112 +348,189 @@ index a9f74eeb5b6300a0b7a940da9c17bd7582b0925d..a970e00482952318c258fc406cb7c39a org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); thread.start(); // Paper - start console thread after MinecraftServer.console & PaperConfig are initialized io.papermc.paper.command.PaperCommands.registerCommands(this); -+ org.plazmamc.plazma.commands.PlazmaCommands.registerCommands(this); // Plazma ++ org.plazmamc.plazma.commands.Commands.register(this); // Plazma com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Purpur start try { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 670d7649d25f7704b071d27157173a3139481207..e7efdd572716e50ecca217898b8a368e5829f925 100644 +index 1c8724fb56e790922c7e8fc73bc97442b7a6df83..e46207a250a5456589da06fd5fad2a385ef7d4a5 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -694,7 +694,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Holder holder = worlddimension.type(); // CraftBukkit - decompile error // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error -- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), executor); // Paper - Async-Anti-Xray - Pass executor -+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma +- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), executor); // Paper - Async-Anti-Xray - Pass executor ++ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(org.plazmamc.plazma.configurations.PlazmaConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index 2776b124dd15e4c84edcfbf98ba44d53ef149e43..0ee4bd3a7faa0ca7ab3b5ecdbe90c2e6729a8fc9 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -247,7 +247,7 @@ public final class ItemStack { + if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion() && MinecraftServer.getServer() != null) { // Paper - skip conversion if the server doesn't exist (for tests) + CompoundTag savedStack = new CompoundTag(); + this.save(savedStack); +- savedStack = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue(); ++ savedStack = (CompoundTag) MinecraftServer.getServer().getFixerUpper().update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue(); // Plazma - Fix test + this.load(savedStack); + } + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 0325eada6271f021b4cc6e398b6e3e75b915f8aa..e45a5282dc0ea3a35da24c7c3a0c7cda9a773f0c 100644 +index 36a1ac09bec7b4139d1cd44e6ecda72fc30fa8c4..af4eb54d99b67d059534e5e55e952aa41bb87bc7 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -174,7 +174,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return this.paperConfig; +@@ -175,6 +175,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end -- + + // Plazma start -+ private final org.plazmamc.plazma.configurations.LevelConfigurations plazmaLevelConfiguration; -+ public org.plazmamc.plazma.configurations.LevelConfigurations plazmaLevelConfiguration() { -+ return this.plazmaLevelConfiguration; ++ private final org.plazmamc.plazma.configurations.WorldConfigurations plazmaConfig; ++ public org.plazmamc.plazma.configurations.WorldConfigurations plazmaConfig() { ++ return this.plazmaConfig; + } + // Plazma end public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur public final co.aikar.timings.WorldTimingsHandler timings; // Paper -@@ -254,9 +259,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -256,9 +262,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public abstract ResourceKey getTypeKey(); + //protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter // Purpur - dont break ABI - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor -+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaLevelConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma ++ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaWorldConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper -+ this.plazmaLevelConfiguration = plazmaLevelConfigurationCreator.apply(this.spigotConfig); // Plazma ++ this.plazmaConfig = plazmaWorldConfigurationCreator.apply(this.spigotConfig); // Plazma this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), env); // Purpur this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur this.generator = gen; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 005c854a10f343cd7488b282de002249bf5c4ced..3e8f42811e9254567f2522e68b6018704bd63ae2 100644 +index 09c292e22788fdf48b639265f24595e14aceba7a..6537ae98dc4086f2b6668810425f80c19ef57734 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1053,6 +1053,7 @@ public final class CraftServer implements Server { +@@ -1055,6 +1055,7 @@ public final class CraftServer implements Server { - org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot + org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); + this.console.plazmaConfigurations.reloadConfigurations(this.console); // Plazma org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty -@@ -2986,6 +2987,13 @@ public final class CraftServer implements Server { - return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); +@@ -3062,6 +3063,13 @@ public final class CraftServer implements Server { } + // Purpur end + // Plazma start -+ @Override -+ public YamlConfiguration getPlazmaConfiguration() { ++ @Override @org.jetbrains.annotations.NotNull ++ public YamlConfiguration getPlazmaConfig() { + return CraftServer.this.console.plazmaConfigurations.createLegacyObject(CraftServer.this.console); + } + // Plazma end + - // Purpur start @Override - public YamlConfiguration getPurpurConfig() { + public void restart() { + org.spigotmc.RestartCommand.restart(); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 01f581e6c3dfacb0ec6aff05c08539bbd2e580c7..f1b754fbf72cbf3c10a74192c66a9432d8218d4b 100644 +index d41f9c4a3c992b5dadacb4fcb1107235fff79fa8..1da2a66169bf1c55bcb4ef6390194ef1772ba9dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -173,6 +173,14 @@ public class Main { - .describedAs("Jar file"); +@@ -195,6 +195,14 @@ public class Main { + .defaultsTo("Unknown Server") + .describedAs("Name"); // Paper end - ++ + // Plazma start -+ acceptsAll(asList("plazma-dir", "plazma-configurations-directory"), "Directory for Plazma configurations") ++ acceptsAll(asList("plazma-dir", "plazma-settings-directory"), "Directory for Plazma settings") + .withRequiredArg() + .ofType(File.class) -+ .defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR)) -+ .describedAs("Config directory"); ++ .defaultsTo(new File(org.plazmamc.plazma.configurations.PlazmaConfigurations.CONFIG_DIR)) ++ .describedAs("Configuration Directory"); + // Plazma end + } + }; + +diff --git a/src/main/java/org/plazmamc/plazma/Options.java b/src/main/java/org/plazmamc/plazma/Options.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bb86260deca1a16795728b8fdec4c9e2da2c221c +--- /dev/null ++++ b/src/main/java/org/plazmamc/plazma/Options.java +@@ -0,0 +1,6 @@ ++package org.plazmamc.plazma; ++ ++public interface Options { + - // Purpur Start - acceptsAll(asList("purpur", "purpur-settings"), "File for purpur settings") - .withRequiredArg() -diff --git a/src/main/java/org/plazmamc/plazma/commands/PlazmaCommand.java b/src/main/java/org/plazmamc/plazma/commands/PlazmaCommand.java ++ ++} +diff --git a/src/main/java/org/plazmamc/plazma/commands/Commands.java b/src/main/java/org/plazmamc/plazma/commands/Commands.java new file mode 100644 -index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded4e9aa914 +index 0000000000000000000000000000000000000000..4497d8f8a52db0fc89ce27168b54657d172b1445 --- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/commands/PlazmaCommand.java -@@ -0,0 +1,127 @@ ++++ b/src/main/java/org/plazmamc/plazma/commands/Commands.java +@@ -0,0 +1,23 @@ +package org.plazmamc.plazma.commands; + ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.command.Command; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.plazmamc.plazma.commands.plazma.PlazmaCommand; ++ ++import java.util.HashMap; ++import java.util.Map; ++ ++@DefaultQualifier(NonNull.class) ++public class Commands { ++ ++ private static final Map COMMANDS = new HashMap<>() {{ ++ put("plazma", new PlazmaCommand("plazma")); ++ }}; ++ ++ public static void register(final MinecraftServer server) { ++ COMMANDS.forEach((s, command) -> server.server.getCommandMap().register(s, "Plazma", command)); ++ } ++ ++} +diff --git a/src/main/java/org/plazmamc/plazma/commands/PlazmaSubCommand.java b/src/main/java/org/plazmamc/plazma/commands/PlazmaSubCommand.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e25ba7935e2743aab5c1334c6582459556ec643a +--- /dev/null ++++ b/src/main/java/org/plazmamc/plazma/commands/PlazmaSubCommand.java +@@ -0,0 +1,19 @@ ++package org.plazmamc.plazma.commands; ++ ++import org.bukkit.command.CommandSender; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++ ++import java.util.Collections; ++import java.util.List; ++ ++@DefaultQualifier(NonNull.class) ++public interface PlazmaSubCommand { ++ ++ boolean execute(final CommandSender sender, final String subCommand, final String[] args); ++ ++ default List tabComplete(final CommandSender sender, final String subCommand, final String[] args) { ++ return Collections.emptyList(); ++ } ++ ++} +diff --git a/src/main/java/org/plazmamc/plazma/commands/plazma/PlazmaCommand.java b/src/main/java/org/plazmamc/plazma/commands/plazma/PlazmaCommand.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1628bee2fb106ad149cad95fb5e3d1100448c697 +--- /dev/null ++++ b/src/main/java/org/plazmamc/plazma/commands/plazma/PlazmaCommand.java +@@ -0,0 +1,120 @@ ++package org.plazmamc.plazma.commands.plazma; ++ +import io.papermc.paper.command.CommandUtil; +import it.unimi.dsi.fastutil.Pair; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.Util; +import org.bukkit.Bukkit; -+import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permission; @@ -355,9 +539,9 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; -+import org.plazmamc.plazma.commands.subcommands.PlazmaSubCommand; -+import org.plazmamc.plazma.commands.subcommands.ReloadCommand; -+import org.plazmamc.plazma.commands.subcommands.VersionCommand; ++import org.plazmamc.plazma.commands.PlazmaSubCommand; ++import org.plazmamc.plazma.commands.plazma.subcommand.ReloadCommand; ++import org.plazmamc.plazma.commands.plazma.subcommand.VersionCommand; + +import java.util.*; +import java.util.stream.Collectors; @@ -368,10 +552,10 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded +public class PlazmaCommand extends Command { + + private static final Map SUB_COMMANDS = Util.make(() -> { -+ final Map, PlazmaSubCommand> commands = new HashMap<>(); -+ -+ commands.put(Set.of("reload"), new ReloadCommand()); -+ commands.put(Set.of("version"), new VersionCommand()); ++ final Map, PlazmaSubCommand> commands = new HashMap<>() {{ ++ put(Set.of("reload"), new ReloadCommand()); ++ put(Set.of("version"), new VersionCommand()); ++ }}; + + return commands.entrySet().stream() + .flatMap(entry -> entry.getKey().stream().map(key -> Map.entry(key, entry.getValue()))) @@ -379,10 +563,10 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded + }); + + private static final Map ALIASES = Util.make(() -> { -+ final Map> aliases = new HashMap<>(); -+ -+ aliases.put("reload", Set.of("rl")); -+ aliases.put("version", Set.of("ver")); ++ final Map> aliases = new HashMap<>() {{ ++ put("reload", Set.of("rl")); ++ put("version", Set.of("ver")); ++ }}; + + return aliases.entrySet().stream() + .flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey()))) @@ -402,20 +586,7 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded + this.usageMessage = String.format("/plazma [%s]", String.join("|", SUB_COMMANDS.keySet())); + this.setPermission(String.join(";", permissions)); + -+ for (final String perm : permissions) -+ pluginManager.addPermission(new Permission(perm, PermissionDefault.OP)); -+ } -+ -+ @Override -+ public List tabComplete(final CommandSender sender, final String aliases, final String[] args) throws IllegalArgumentException { -+ if (args.length <= 1) -+ return CommandUtil.getListMatchingLast(sender, args, SUB_COMMANDS.keySet()); -+ -+ final @Nullable Pair subCommand = resolveSubCommand(args[0]); -+ if (subCommand != null) -+ return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length)); -+ -+ return Collections.emptyList(); ++ permissions.forEach(perm -> pluginManager.addPermission(new Permission(perm, PermissionDefault.OP))); + } + + @Override @@ -440,6 +611,22 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded + return subCommand.second().execute(sender, subCommand.first(), choppedArgs); + } + ++ @Override ++ public List tabComplete(final CommandSender sender, final String aliases, final String[] args) throws IllegalArgumentException { ++ if (args.length <= 1) return CommandUtil.getListMatchingLast(sender, args, SUB_COMMANDS.keySet()); ++ ++ final @Nullable Pair subCommand = resolveSubCommand(args[0]); ++ ++ if (subCommand != null) return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length)); ++ return Collections.emptyList(); ++ } ++ ++ private static boolean testPermission(final CommandSender sender, final String permission) { ++ if (sender.hasPermission("bukkit.command.plazma." + permission) || sender.hasPermission("bukkit.command.plazma")) return true; ++ sender.sendMessage(Bukkit.permissionMessage()); ++ return false; ++ } ++ + private static @Nullable Pair resolveSubCommand(String label) { + label = label.toLowerCase(Locale.ENGLISH); + @Nullable PlazmaSubCommand subCommand = SUB_COMMANDS.get(label); @@ -448,103 +635,44 @@ index 0000000000000000000000000000000000000000..9fb819b3745ec98d81a53650d9095ded + final @Nullable String command = ALIASES.get(label); + if (command != null) { + label = command; -+ subCommand = SUB_COMMANDS.get(command); ++ subCommand = SUB_COMMANDS.get(label); + } + } + -+ if (subCommand != null) -+ return Pair.of(label, subCommand); -+ ++ if (subCommand != null) return Pair.of(label, subCommand); + return null; + } + -+ private static boolean testPermission(final CommandSender sender, final String permission) { -+ if (sender.hasPermission("bukkit.command.plazma." + permission) || sender.hasPermission("bukkit.command.plazma")) -+ return true; -+ -+ sender.sendMessage(Bukkit.permissionMessage()); -+ return false; -+ } -+} -diff --git a/src/main/java/org/plazmamc/plazma/commands/PlazmaCommands.java b/src/main/java/org/plazmamc/plazma/commands/PlazmaCommands.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4223faf9cdeb76cbafbb9b5b402ca3293c2afc1d ---- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/commands/PlazmaCommands.java -@@ -0,0 +1,25 @@ -+package org.plazmamc.plazma.commands; -+ -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.command.Command; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+import java.util.HashMap; -+import java.util.Map; -+ -+@DefaultQualifier(NonNull.class) -+public final class PlazmaCommands { -+ -+ private PlazmaCommands() {} -+ -+ private static final Map COMMANDS = new HashMap<>(); -+ static { -+ COMMANDS.put("plazma", new PlazmaCommand("plazma")); -+ } -+ -+ public static void registerCommands(final MinecraftServer server) { -+ COMMANDS.forEach((s, command) -> server.server.getCommandMap().register(s, "Plazma", command)); -+ } -+ -+} -diff --git a/src/main/java/org/plazmamc/plazma/commands/subcommands/PlazmaSubCommand.java b/src/main/java/org/plazmamc/plazma/commands/subcommands/PlazmaSubCommand.java -new file mode 100644 -index 0000000000000000000000000000000000000000..32f2f9c933069c32c321f71ec2c57e2261f7ad1e ---- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/commands/subcommands/PlazmaSubCommand.java -@@ -0,0 +1,17 @@ -+package org.plazmamc.plazma.commands.subcommands; -+ -+import org.bukkit.command.CommandSender; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+import java.util.Collections; -+import java.util.List; -+ -+@DefaultQualifier(NonNull.class) -+public interface PlazmaSubCommand { -+ boolean execute(CommandSender sender, String subCommand, String[] args); -+ -+ default List tabComplete(final CommandSender sender, final String subCommand, final String[] args) { -+ return Collections.emptyList(); -+ } +} -diff --git a/src/main/java/org/plazmamc/plazma/commands/subcommands/ReloadCommand.java b/src/main/java/org/plazmamc/plazma/commands/subcommands/ReloadCommand.java +diff --git a/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/ReloadCommand.java b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/ReloadCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..9b1964bf2c05e71cac633fd75f887a5e516623df +index 0000000000000000000000000000000000000000..ca0eca7ae4a62f84d05dadeb692f7afb7f316c6e --- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/commands/subcommands/ReloadCommand.java -@@ -0,0 +1,29 @@ -+package org.plazmamc.plazma.commands.subcommands; ++++ b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/ReloadCommand.java +@@ -0,0 +1,34 @@ ++package org.plazmamc.plazma.commands.plazma.subcommand; + +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.server.MinecraftServer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.plazmamc.plazma.commands.PlazmaSubCommand; + +import static net.kyori.adventure.text.Component.text; + ++@DefaultQualifier(NonNull.class) +public class ReloadCommand implements PlazmaSubCommand { + + @Override -+ public boolean execute(CommandSender sender, String subCommand, String[] args) { -+ this.doReload(sender); ++ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { ++ this.reload(sender); + return true; + } + -+ private void doReload(final CommandSender sender) { ++ private void reload(final CommandSender sender) { + Command.broadcastCommandMessage(sender, text("Please note that this command is not supported and may cause issues.", NamedTextColor.RED)); + Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", NamedTextColor.RED)); + @@ -554,34 +682,41 @@ index 0000000000000000000000000000000000000000..9b1964bf2c05e71cac633fd75f887a5e + + Command.broadcastCommandMessage(sender, text("Successfully reloaded Plazma configuration files.", NamedTextColor.GREEN)); + } ++ +} -diff --git a/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java b/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java +diff --git a/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..85002144e0b350c4ae044e1a4a4c1734cc27c059 +index 0000000000000000000000000000000000000000..b6664ba0fce55f5cfa0c8d3051dc8c2be0fd0703 --- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java -@@ -0,0 +1,15 @@ -+package org.plazmamc.plazma.commands.subcommands; ++++ b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java +@@ -0,0 +1,21 @@ ++package org.plazmamc.plazma.commands.plazma.subcommand; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; ++import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.plazmamc.plazma.commands.PlazmaSubCommand; + ++@DefaultQualifier(NonNull.class) +public class VersionCommand implements PlazmaSubCommand { ++ + @Override -+ public boolean execute(CommandSender sender, String subCommand, String[] args) { ++ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { + final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version"); -+ if (ver != null) ver.execute(sender, "plazma", new String[0]); -+ return true; ++ if (ver != null) return ver.execute(sender, "plazma", new String[0]); ++ return false; + } ++ +} diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..d506e0c2b37f91e46e682652bd134ad91db28f84 +index 0000000000000000000000000000000000000000..69c4d9cb0532621018f6cd99916c409fc150ab7e --- /dev/null +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -0,0 +1,43 @@ +@@ -0,0 +1,26 @@ +package org.plazmamc.plazma.configurations; + +import io.papermc.paper.configuration.Configuration; @@ -591,456 +726,415 @@ index 0000000000000000000000000000000000000000..d506e0c2b37f91e46e682652bd134ad9 + +@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "InnerClassMayBeStatic"}) +public class GlobalConfiguration extends ConfigurationPart { -+ static final int CURRENT_VERSION = 1; -+ static final boolean DO_OPTIMIZE = PlazmaConfigurations.doOptimize(); -+ private static GlobalConfiguration instance; -+ -+ public static GlobalConfiguration get() { -+ return instance; -+ } -+ -+ static void set(@NotNull GlobalConfiguration instance, boolean test) { -+ GlobalConfiguration.instance = instance; -+ if (test) { -+ -+ } -+ } -+ -+ @Setting(Configuration.VERSION_FIELD) -+ public int version = CURRENT_VERSION; + -+ public Misc misc; -+ public class Misc extends ConfigurationPart.Post { ++ private static GlobalConfiguration INSTANCE; ++ static final int VERSION = 2; ++ static final boolean OPTIMIZE = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); + -+ @Override -+ public void postProcess() { -+ -+ -+ } -+ -+ } -+ -+ public Player player; -+ public class Player extends ConfigurationPart { -+ -+ } -+} -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d990c031255daf0d43541efe175c5b52736a6990 ---- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -0,0 +1,45 @@ -+package org.plazmamc.plazma.configurations; -+ -+import io.papermc.paper.configuration.Configuration; -+import io.papermc.paper.configuration.ConfigurationPart; -+import io.papermc.paper.configuration.PaperConfigurations; -+import net.minecraft.resources.ResourceLocation; -+import org.spongepowered.configurate.objectmapping.meta.Setting; -+ -+@SuppressWarnings({"FieldCanBeLocal", "FieldMayBeFinal", "InnerClassMayBeStatic"}) -+public class LevelConfigurations extends ConfigurationPart { -+ public static final int CURRENT_VERSION = 1; -+ private static final boolean DO_OPTIMIZE = PlazmaConfigurations.doOptimize(); -+ -+ private transient final ResourceLocation worldKey; -+ public LevelConfigurations(ResourceLocation worldKey) { -+ this.worldKey = worldKey; ++ public static GlobalConfiguration get() { ++ return INSTANCE; + } + -+ public boolean isDefault() { -+ return this.worldKey.equals(PaperConfigurations.WORLD_DEFAULTS_KEY); ++ static void set(@NotNull GlobalConfiguration instance) { ++ GlobalConfiguration.INSTANCE = instance; + } + + @Setting(Configuration.VERSION_FIELD) -+ public int version = CURRENT_VERSION; -+ -+ public Misc misc; -+ public class Misc extends ConfigurationPart { ++ int version = VERSION; + -+ } -+ -+ public Entity entity; -+ public class Entity extends ConfigurationPart { -+ -+ } -+ -+ public Structure structure; -+ public class Structure extends ConfigurationPart { -+ -+ public NetherPortal netherPortal; -+ public class NetherPortal extends ConfigurationPart { -+ -+ } -+ -+ } +} diff --git a/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..295578fddc8f897763d0af9836cdd93b0d3cef31 +index 0000000000000000000000000000000000000000..8a22550e19cc3ec00b1db85af5685b75674d3594 --- /dev/null +++ b/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java -@@ -0,0 +1,309 @@ +@@ -0,0 +1,278 @@ +package org.plazmamc.plazma.configurations; + -+import com.google.common.collect.Table; +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; -+import io.papermc.paper.configuration.*; -+import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization; -+import io.papermc.paper.configuration.serializer.ComponentSerializer; -+import io.papermc.paper.configuration.serializer.EnumValueSerializer; ++import io.papermc.paper.configuration.Configuration; ++import io.papermc.paper.configuration.ConfigurationPart; ++import io.papermc.paper.configuration.Configurations; ++import io.papermc.paper.configuration.mapping.InnerClassFieldDiscoverer; ++import io.papermc.paper.configuration.serializer.NbtPathSerializer; +import io.papermc.paper.configuration.serializer.PacketClassSerializer; +import io.papermc.paper.configuration.serializer.StringRepresentableSerializer; +import io.papermc.paper.configuration.serializer.collections.FastutilMapSerializer; -+import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.configuration.serializer.collections.TableSerializer; +import io.papermc.paper.configuration.serializer.registry.RegistryHolderSerializer; +import io.papermc.paper.configuration.serializer.registry.RegistryValueSerializer; -+import io.papermc.paper.configuration.transformation.Transformations; -+import io.papermc.paper.configuration.type.*; ++import io.papermc.paper.configuration.type.BooleanOrDefault; ++import io.papermc.paper.configuration.type.Duration; ++import io.papermc.paper.configuration.type.DurationOrDisabled; ++import io.papermc.paper.configuration.type.EngineMode; +import io.papermc.paper.configuration.type.fallback.FallbackValueSerializer; ++import io.papermc.paper.configuration.type.number.DoubleOr; ++import io.papermc.paper.configuration.type.number.IntOr; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; ++import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; -+import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; ++import net.minecraft.world.level.block.Block; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; +import org.jetbrains.annotations.VisibleForTesting; +import org.slf4j.Logger; +import org.spongepowered.configurate.*; ++import org.spongepowered.configurate.objectmapping.FieldDiscoverer; +import org.spongepowered.configurate.objectmapping.ObjectMapper; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + -+import java.io.File; +import java.io.IOException; -+import java.lang.reflect.Type; -+import java.nio.file.Files; +import java.nio.file.Path; -+import java.util.Collections; -+import java.util.List; ++import java.util.Map; +import java.util.function.Function; + +import static io.leangen.geantyref.GenericTypeReflector.erase; + -+@SuppressWarnings("Convert2Diamond") -+public class PlazmaConfigurations extends Configurations { ++@DefaultQualifier(NonNull.class) ++public class PlazmaConfigurations extends Configurations { + -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ static final String GLOBAL_CONFIGURATION_FILE_NAME= "plazma-global.yml"; -+ static final String LEVEL_DEFAULT_CONFIGURATION_FILE_NAME = "plazma-level-defaults.yml"; -+ static final String LEVEL_CONFIGURATION_FILE_NAME = "plazma-configuration.yml"; -+ static final boolean OPTIMIZE_CONFIG = !Boolean.getBoolean("Plazma.disableConfigOptimization"); ++ public static final String CONFIG_DIR = "config"; ++ static final Logger LOGGER = LogUtils.getLogger(); ++ static final String GLOBAL_CONFIG_FILE_NAME = "plazma-global.yml"; ++ static final String WORLD_DEFAULTS_CONFIG_FILE_NAME = "plazma-world-defaults.yml"; ++ static final String WORLD_CONFIG_FILE_NAME = "plazma-world.yml"; ++ static final boolean OPTIMIZE = !Boolean.getBoolean("Plazma.disableConfigOptimization"); + + private static final String HEADER_START = """ -+ # English ++ #### ENGLISH #### + This is the %s configuration file for Plazma. + As you can see, there's a lot to configure. Some options may impact gameplay, + so use with caution, and make sure you know what each option does before configuring. + ++ A description of the options can be found on the official wiki, + If you need help with the configuration or have any questions related to Plazma, -+ join us in our Discord for Plazma, or check the GitHub Wiki pages. ++ join us in our Discord for Plazma, or create issues on our GitHub repository. + + %s + -+ # 한국어 -+ 본 파일은 Plazma의 %s 구성 파일입니다. -+ 보시다시피, 굉장히 많은 설정이 있습니다. 몇몇 설정은 게임플레이에 영향을 줄 수 있으므로, -+ 주의해서 사용하시기 바라며, 각 설정이 어떠한 역할을 하는지 알고 사용하시기 바랍니다. ++ #### 한국어 #### ++ 본 파일은 Plazma의 %s 설정 파일입니다. ++ 보시다시피, 굉장히 많은 설정이 있습니다. 일부 설정은 게임 플레이에 영향을 줄 수 있습니다. ++ 따라서 주의해서 사용하시고, 각 설정이 서버에 어떠한 작용을 하는지 숙지하고 사용하시기 바랍니다. + -+ 만약 구성에 관한 도움이 필요하거나 Plazma에 관련한 질문이 있으시다면, -+ Discord 또는 네이버 카페에 가입하거나, GitHub 위키 페이지를 참고하시기 바랍니다. ++ 구성에 대한 설명은 공식 위키에서 찾을 수 있으며, ++ 만약 설정에 도움이 필요하거나, Plazma에 대 질문이 있으시다면, ++ 공식 Discord 서버에 접속하거나, GitHub 레포지토리에 이슈를 생성해주시기 바랍니다. + + %s + ++ GitHub: https://github.com/PlazmaMC/Plazma + Wiki: https://github.com/PlazmaMC/Plazma/wiki -+ Discord: https://discord.gg/MmfC52K8A8 ++ Discord: https://plazmamc.org/discord + """; + -+ private static final Function LEVEL_SPECIFIC_HEADER = map -> String.format(""" -+ # English -+ This is a level specific configuration file for Plazma. -+ This file may start empty, but can be filled with settings to override ones in the %s/%s ++ private static final String GLOBAL_HEADER = String.format(HEADER_START, ++ "global", String.format("World options can be set in the %s file.", WORLD_DEFAULTS_CONFIG_FILE_NAME), ++ "전역", String.format("월드별 설정은 %s 파일에서 설정할 수 있습니다.", WORLD_DEFAULTS_CONFIG_FILE_NAME) ++ ); ++ ++ private static final String WORLD_DEFAULTS_HEADER = String.format(HEADER_START, ++ "world default", String.format(""" ++ World-specific settings can be set in the %s file within each world folder, ++ and the same settings apply to all worlds unless they are overwritten ++ through the world-specific settings file. ++ """, WORLD_CONFIG_FILE_NAME), ++ "월드 기본", String.format(""" ++ 월드별 설정은 각 월드 폴더 내 %s 파일에서 설정할 수 있으며, 월드별 설정을 통해 값을 ++ 덮어쓰지 않는 한, 모든 월드에 동일한 설정이 적용됩니다. ++ """, WORLD_CONFIG_FILE_NAME) ++ ); ++ ++ private static final Function WORLD_HEADER = map -> String.format(""" ++ #### ENGLISH #### ++ This is world-specific Plazma configuration file for the world %s (%s). ++ This file may start empty, but can be filled with options to override world default configuration. ++ Some options may impact gameplay, so use with caution, ++ and make sure you know what each option does before configuring. + ++ A description of the options can be found on the official wiki, + If you need help with the configuration or have any questions related to Plazma, -+ join us in our Discord for Plazma, or check the GitHub Wiki pages. ++ join us in our Discord for Plazma, or create issues on our GitHub repository. + + -+ # 한국어 -+ 본 파일은 Plazma의 레벨별 구성 파일입니다. -+ 이 파일은 비어있을 수 있지만, %s/%s 파일의 설정을 덮어쓰기 위해 설정을 채울 수 있습니다. ++ #### 한국어 #### ++ 본 파일은 %s (%s) 월드 전용 Plazma 월드별 설정 파일입니다. ++ 이 파일은 비어있을 수 있지만, 월드 기본 설정을 덮어쓰기 위해 옵션을 추가할 수 있습니다. ++ 일부 설정은 게임 플레이에 영향을 줄 수 있으므로, 주의해서 사용하시고, ++ 각 설정이 서버에 어떠한 작용을 하는지 숙지하고 사용하시기 바랍니다. + -+ 만약 구성에 관한 도움이 필요하거나 Plazma에 관련한 질문이 있으시다면, -+ Discord 또는 네이버 카페에 가입하거나, GitHub 위키 페이지를 참고하시기 바랍니다. ++ 구성에 대한 설명은 공식 위키에서 찾을 수 있으며, ++ 만약 설정에 도움이 필요하거나, Plazma에 대 질문이 있으시다면, ++ 공식 Discord 서버에 접속하거나, GitHub 레포지토리에 이슈를 생성해주시기 바랍니다. + + -+ Level: %s (%s) -+ ++ World Default Config Directory: %s/%s ++ GitHub: https://github.com/PlazmaMC/Plazma + Wiki: https://github.com/PlazmaMC/Plazma/wiki -+ Discord: https://discord.gg/MmfC52K8A8 -+ """, PaperConfigurations.CONFIG_DIR, LEVEL_DEFAULT_CONFIGURATION_FILE_NAME, PaperConfigurations.CONFIG_DIR, LEVEL_DEFAULT_CONFIGURATION_FILE_NAME, -+ map.require(WORLD_NAME), map.require(WORLD_KEY)); -+ -+ private static final String GLOBAL_HEADER = String.format(HEADER_START, -+ "global", String.format(""" -+ The level configuration options are inside their respective level folder. -+ The files are named %s -+ """, LEVEL_CONFIGURATION_FILE_NAME), -+ "전역", String.format(""" -+ 레벨 구성 옵션은 각각의 레벨 폴더 안에 있으며, 파일 이름은 %s 입니다. -+ """, LEVEL_CONFIGURATION_FILE_NAME) -+ ); -+ -+ private static final String LEVEL_DEFAULTS_HEADER = String.format(HEADER_START, -+ "level defaults", """ -+ Configuration options here apply to all levels, unless you specify overrides inside -+ the level-specific config file inside each level folder. -+ """, -+ "기본 레벨", """ -+ 이 구성 파일의 설정은 각 레벨 폴더 안 구성 파일에서 덮어쓰기 되지 않는 한 모든 레벨에 적용됩니다. -+ """ -+ ); -+ -+ private static final List DEFAULTS_AWARE_TRANSFORMATIONS = Collections.emptyList(); ++ Discord: https://plazmamc.org/discord ++ """, map.require(WORLD_NAME), map.require(WORLD_KEY), map.require(WORLD_NAME), map.require(WORLD_KEY), ++ CONFIG_DIR, WORLD_DEFAULTS_CONFIG_FILE_NAME); + + public PlazmaConfigurations(final Path globalFolder) { -+ super(globalFolder, GlobalConfiguration.class, LevelConfigurations.class, GLOBAL_CONFIGURATION_FILE_NAME, LEVEL_DEFAULT_CONFIGURATION_FILE_NAME, LEVEL_CONFIGURATION_FILE_NAME); ++ super(globalFolder, GlobalConfiguration.class, WorldConfigurations.class, GLOBAL_CONFIG_FILE_NAME, WORLD_DEFAULTS_CONFIG_FILE_NAME, WORLD_CONFIG_FILE_NAME); + } + -+ // Create Loader Builder -+ private static ConfigurationOptions defaultOptions(@NotNull ConfigurationOptions options) { -+ return options.serializers(builder -> builder -+ .register(MapSerializer.TYPE, new MapSerializer(false)) -+ .register(new EnumValueSerializer()) -+ .register(new ComponentSerializer()) ++ private static ConfigurationOptions defaultGlobalOptions(ConfigurationOptions options) { ++ return options.header(GLOBAL_HEADER).serializers(builder -> builder ++ .register(new PacketClassSerializer()) ++ .register(IntOr.Default.SERIALIZER) + ); + } + + @Override -+ protected YamlConfigurationLoader.Builder createLoaderBuilder() { -+ return super.createLoaderBuilder().defaultOptions(PlazmaConfigurations::defaultOptions); -+ } -+ -+ // Create Global Object Mapper Factory Builder -+ private static ObjectMapper.Factory.Builder defaultGlobalFactoryBuilder(ObjectMapper.Factory.@NotNull Builder builder) { -+ return builder.addDiscoverer(InnerClassFieldDiscoverer.globalConfig()); -+ } -+ -+ @Override -+ protected ObjectMapper.Factory.Builder createGlobalObjectMapperFactoryBuilder() { -+ return defaultGlobalFactoryBuilder(super.createGlobalObjectMapperFactoryBuilder()); -+ } -+ -+ // Create Global Loader Builder -+ private static ConfigurationOptions defaultGlobalOptions(@NotNull ConfigurationOptions options) { -+ return options.header(GLOBAL_HEADER).serializers(builder -> builder.register(new PacketClassSerializer())); -+ } -+ -+ @Override + protected YamlConfigurationLoader.Builder createGlobalLoaderBuilder() { + return super.createGlobalLoaderBuilder().defaultOptions(PlazmaConfigurations::defaultGlobalOptions); + } + -+ // Initialize + @Override -+ public GlobalConfiguration initializeGlobalConfiguration() throws ConfigurateException { -+ GlobalConfiguration configuration = super.initializeGlobalConfiguration(); -+ GlobalConfiguration.set(configuration, false); ++ public GlobalConfiguration initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException { ++ GlobalConfiguration configuration = super.initializeGlobalConfiguration(registryAccess); ++ GlobalConfiguration.set(configuration); + return configuration; + } + + @Override -+ protected ContextMap.Builder createDefaultContextMap() { -+ return super.createDefaultContextMap().put(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY, PaperConfigurations.SPIGOT_WORLD_DEFAULTS); ++ protected void applyGlobalConfigTransformations(final ConfigurationNode node) throws ConfigurateException { ++ ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder(); ++ ++ for (NodePath path : RemovedConfigurations.GLOBAL_PATHS) ++ builder.addAction(path, TransformAction.remove()); ++ ++ builder.build().apply(node); ++ } ++ ++ private static FieldDiscoverer worldConfigDiscoverer(final ContextMap contextMap) { ++ final Map, Object> overrides = Map.of( ++ WorldConfigurations.class, new WorldConfigurations(contextMap.require(WORLD_KEY)) ++ ); ++ return new InnerClassFieldDiscoverer(overrides); + } + + @Override + protected ObjectMapper.Factory.Builder createWorldObjectMapperFactoryBuilder(final ContextMap contextMap) { -+ return super.createWorldObjectMapperFactoryBuilder(contextMap) -+ .addNodeResolver(new RequiresSpigotInitialization.Factory(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get())) -+ .addNodeResolver(new NestedSetting.Factory()) -+ .addDiscoverer(InnerClassFieldDiscoverer.plazmaLevelConfiguration(contextMap)); ++ return super.createWorldObjectMapperFactoryBuilder(contextMap).addDiscoverer(worldConfigDiscoverer(contextMap)); + } + + @Override + protected YamlConfigurationLoader.Builder createWorldConfigLoaderBuilder(final ContextMap contextMap) { -+ return super.createWorldConfigLoaderBuilder(contextMap).defaultOptions(options -> options -+ .header(contextMap.require(WORLD_NAME).equals(WORLD_DEFAULTS) ? LEVEL_DEFAULTS_HEADER : LEVEL_SPECIFIC_HEADER.apply(contextMap)) -+ .serializers(serializers -> serializers -+ .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2IntOpenHashMap::new, Integer.TYPE)) -+ .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2LongOpenHashMap::new, Long.TYPE)) -+ .register(new TypeToken>() {}, new TableSerializer()) -+ .register(new StringRepresentableSerializer()) -+ .register(IntOr.Default.SERIALIZER) -+ .register(DoubleOrDefault.SERIALIZER) -+ .register(BooleanOrDefault.SERIALIZER) -+ .register(Duration.SERIALIZER) -+ .register(EngineMode.SERIALIZER) -+ .register(FallbackValueSerializer.create(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer)) -+ .register(new RegistryValueSerializer<>(new TypeToken>() {}, Registries.ENTITY_TYPE, true)) -+ .register(new RegistryValueSerializer<>(Item.class, Registries.ITEM, true)) -+ .register(new RegistryHolderSerializer<>(new TypeToken>() {}, Registries.CONFIGURED_FEATURE, false)) -+ .register(new RegistryHolderSerializer<>(Item.class, Registries.ITEM, true)) -+ ) -+ ); -+ } -+ -+ private void applyTransformations(final NodePath @NotNull [] paths, final ConfigurationNode node) throws ConfigurateException { -+ if (paths.length > 0) { -+ ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder(); -+ -+ for (NodePath path : paths) -+ builder.addAction(path, TransformAction.remove()); -+ -+ builder.build().apply(node); -+ } ++ final RegistryAccess access = contextMap.require(REGISTRY_ACCESS); ++ return super.createWorldConfigLoaderBuilder(contextMap) ++ .defaultOptions(options -> options ++ .header(contextMap.require(WORLD_NAME).equals(WORLD_DEFAULTS) ? WORLD_DEFAULTS_HEADER : WORLD_HEADER.apply(contextMap)) ++ .serializers(serializers -> serializers ++ .register(new TypeToken<>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2IntOpenHashMap::new, Integer.TYPE)) ++ .register(new TypeToken<>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2LongOpenHashMap::new, Long.TYPE)) ++ .register(new TypeToken<>() {}, new TableSerializer()) ++ .register(StringRepresentableSerializer::isValidFor, new StringRepresentableSerializer()) ++ .register(IntOr.Default.SERIALIZER) ++ .register(IntOr.Disabled.SERIALIZER) ++ .register(DoubleOr.Default.SERIALIZER) ++ .register(BooleanOrDefault.SERIALIZER) ++ .register(Duration.SERIALIZER) ++ .register(DurationOrDisabled.SERIALIZER) ++ .register(EngineMode.SERIALIZER) ++ .register(NbtPathSerializer.SERIALIZER) ++ .register(FallbackValueSerializer.create(contextMap.require(SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer)) ++ .register(new RegistryValueSerializer<>(new TypeToken<>() {}, access, Registries.ENTITY_TYPE, true)) ++ .register(new RegistryValueSerializer<>(Item.class, access, Registries.ITEM, true)) ++ .register(new RegistryValueSerializer<>(Block.class, access, Registries.BLOCK, true)) ++ .register(new RegistryHolderSerializer<>(new TypeToken<>() {}, access, Registries.CONFIGURED_FEATURE, false)) ++ ) ++ ); + } + + @Override -+ protected void applyGlobalConfigTransformations(final ConfigurationNode node) throws ConfigurateException { -+ applyTransformations(RemovedConfigurations.REMOVED_GLOBAL_PATHS, node); ++ public WorldConfigurations createWorldConfig(final ContextMap contextMap) { ++ final String levelName = contextMap.require(WORLD_NAME); ++ try { ++ return super.createWorldConfig(contextMap); ++ } catch (IOException exception) { ++ throw new RuntimeException("Could not create world configuration for " + levelName, exception); ++ } + } + + @Override -+ protected void applyWorldConfigTransformations(final @NotNull ContextMap contextMap, final @NotNull ConfigurationNode node) throws ConfigurateException { ++ protected void applyWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode node) throws ConfigurateException { + final ConfigurationNode version = node.node(Configuration.VERSION_FIELD); + final String world = contextMap.require(WORLD_NAME); ++ ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder(); + + if (version.virtual()) { -+ LOGGER.warn("The Plazma level configuration file for {} didn't have a version field, assuming latest", world); -+ version.raw(LevelConfigurations.CURRENT_VERSION); ++ LOGGER.warn("The world configuration file for " + world + " didn't have a version set, assuming latest"); ++ version.raw(WorldConfigurations.VERSION); + } + -+ applyTransformations(RemovedConfigurations.REMOVED_LEVEL_PATHS, node); -+ } ++ for (NodePath path : RemovedConfigurations.WORLD_PATHS) ++ builder.addAction(path, TransformAction.remove()); + -+ @Override -+ protected void applyDefaultsAwareWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode levelNode, final ConfigurationNode defaultsNode) throws ConfigurateException { -+ final ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder(); -+ DEFAULTS_AWARE_TRANSFORMATIONS.forEach(transform -> transform.apply(builder, contextMap, defaultsNode)); ++ builder.build().apply(node); ++ } + -+ ConfigurationTransformation transformation; ++ public static PlazmaConfigurations setup(final Path configDir) { + try { -+ transformation = builder.build(); -+ } catch (IllegalArgumentException ignored) { -+ return; ++ createDirectoriesSymlinkAware(configDir); ++ return new PlazmaConfigurations(configDir); ++ } catch (IOException e) { ++ throw new RuntimeException("Could not setup Plazma configuration files", e); + } -+ transformation.apply(levelNode); + } + -+ @Override -+ public LevelConfigurations createWorldConfig(final @NotNull ContextMap contextMap) { -+ final String levelName = contextMap.require(WORLD_NAME); ++ public void reloadConfigurations(MinecraftServer server) { + try { -+ return super.createWorldConfig(contextMap); -+ } catch (IOException exception) { -+ throw new RuntimeException(String.format("Could not create Plazma level configuration for %s", levelName), exception); ++ this.initializeGlobalConfiguration(reloader(this.globalConfigClass, GlobalConfiguration.get())); ++ this.initializeWorldDefaultsConfiguration(server.registryAccess()); ++ for (ServerLevel level : server.getAllLevels()) ++ this.createWorldConfig(createWorldContextMap(level), reloader(this.worldConfigClass, level.plazmaConfig())); ++ } catch (Exception e) { ++ throw new RuntimeException("Could not reload Plazma configuration files", e); + } + } + -+ @Override -+ protected boolean isConfigType(Type type) { -+ return ConfigurationPart.class.isAssignableFrom(erase(type)); -+ } -+ -+ @Override -+ protected int getWorldConfigurationCurrentVersion() { -+ return LevelConfigurations.CURRENT_VERSION; -+ } -+ + @VisibleForTesting -+ static @NotNull ConfigurationNode createForTesting() { ++ static ConfigurationNode createForTesting() { + ObjectMapper.Factory factory = defaultGlobalFactoryBuilder(ObjectMapper.factoryBuilder()).build(); + ConfigurationOptions options = defaultGlobalOptions(defaultOptions(ConfigurationOptions.defaults())) + .serializers(builder -> builder.register(type -> ConfigurationPart.class.isAssignableFrom(erase(type)), factory.asTypeSerializer())); + return BasicConfigurationNode.root(options); + } + -+ @Contract("_ -> new") -+ public static @NotNull PlazmaConfigurations setup(final Path configurationDir) throws Exception { -+ try { -+ PaperConfigurations.createDirectoriesSymlinkAware(configurationDir); -+ return new PlazmaConfigurations(configurationDir); -+ } catch (final IOException e) { -+ throw new RuntimeException("Could not setup Plazma configuration files", e); -+ } ++ @Override ++ protected int globalConfigVersion() { ++ return GlobalConfiguration.VERSION; + } + -+ public void reloadConfigurations(MinecraftServer server) { -+ try { -+ this.initializeGlobalConfiguration(reloader(this.globalConfigClass, GlobalConfiguration.get())); -+ this.initializeWorldDefaultsConfiguration(); -+ for (ServerLevel level : server.getAllLevels()) -+ this.createWorldConfig(PaperConfigurations.createWorldContextMap(level), reloader(this.worldConfigClass, level.plazmaLevelConfiguration())); -+ } catch (Exception e) { -+ throw new RuntimeException("Could not reload Plazma configuration files", e); -+ } ++ @Override ++ protected int worldConfigVersion() { ++ return WorldConfigurations.VERSION; + } + -+ public static boolean optimizeConfig() { -+ return OPTIMIZE_CONFIG; ++ public static boolean optimize() { ++ return OPTIMIZE; + } + +} diff --git a/src/main/java/org/plazmamc/plazma/configurations/RemovedConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/RemovedConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..469100cd86e6742eeebad22923097782dc86bf37 +index 0000000000000000000000000000000000000000..25c0f5d28107b45677aa7b19bc0d5238512d9826 --- /dev/null +++ b/src/main/java/org/plazmamc/plazma/configurations/RemovedConfigurations.java -@@ -0,0 +1,11 @@ +@@ -0,0 +1,13 @@ +package org.plazmamc.plazma.configurations; + +import org.spongepowered.configurate.NodePath; + +interface RemovedConfigurations { + -+ NodePath[] REMOVED_GLOBAL_PATHS = {}; ++ NodePath[] WORLD_PATHS = { ++ }; + -+ NodePath[] REMOVED_LEVEL_PATHS = {}; ++ NodePath[] GLOBAL_PATHS = { ++ }; ++ ++} +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +new file mode 100644 +index 0000000000000000000000000000000000000000..842fb520a2d638aaa5bd0a7198190dbe3ecbe14c +--- /dev/null ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -0,0 +1,22 @@ ++package org.plazmamc.plazma.configurations; ++ ++import io.papermc.paper.configuration.Configuration; ++import io.papermc.paper.configuration.ConfigurationPart; ++import net.minecraft.resources.ResourceLocation; ++import org.spongepowered.configurate.objectmapping.meta.Setting; ++ ++@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "InnerClassMayBeStatic"}) ++public class WorldConfigurations extends ConfigurationPart { ++ ++ static final int VERSION = 2; ++ static final boolean OPTIMIZE = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); ++ ++ private transient final ResourceLocation worldKey; ++ public WorldConfigurations(ResourceLocation worldKey) { ++ this.worldKey = worldKey; ++ } ++ ++ @Setting(Configuration.VERSION_FIELD) ++ int version = VERSION; + +} diff --git a/src/test/java/org/bukkit/support/AbstractTestingBase.java b/src/test/java/org/bukkit/support/AbstractTestingBase.java -index 8174b6bb78553cbe124b499ffa235368179d1564..a5f8a128b27906daba5aeb293851bb03402ca9c2 100644 +index 6dd31027808cd309b6ee5ece9fe73d251c03b7cf..a5880e8697bade842a599f3b7b03a83515814fe4 100644 --- a/src/test/java/org/bukkit/support/AbstractTestingBase.java +++ b/src/test/java/org/bukkit/support/AbstractTestingBase.java @@ -64,6 +64,7 @@ public abstract class AbstractTestingBase { - + DummyServer.setup(); DummyEnchantments.setup(); io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper -+ org.plazmamc.plazma.configurations.GlobalConfigurationTestingBase.setupGlobalConfigurationForTest(); // Plazma ++ org.plazmamc.plazma.configurations.GlobalConfigurationTestingBase.setupGlobalConfigForTest(); // Plazma CraftRegistry.setMinecraftRegistry(REGISTRY_CUSTOM); +diff --git a/src/test/java/org/bukkit/support/DummyServer.java b/src/test/java/org/bukkit/support/DummyServer.java +index c20d5ed12efed109f3702a994188ac4af66c8b9a..dd5c15f4969f15a5eeef1fa068be5643197504be 100644 +--- a/src/test/java/org/bukkit/support/DummyServer.java ++++ b/src/test/java/org/bukkit/support/DummyServer.java +@@ -2,6 +2,7 @@ package org.bukkit.support; + + import static org.mockito.Mockito.*; + import java.util.logging.Logger; ++import net.minecraft.server.MinecraftServer; + import org.bukkit.Bukkit; + import org.bukkit.Material; + import org.bukkit.Server; +@@ -47,6 +48,13 @@ public final class DummyServer { + when(instance.getTag(anyString(), any(org.bukkit.NamespacedKey.class), any())).thenAnswer(ignored -> new io.papermc.paper.util.EmptyTag()); + // paper end - testing additions + ++ // Plazma start - Fix tests ++ net.minecraft.server.MinecraftServer handle = mock(withSettings().stubOnly()); ++ when(handle.random()).thenReturn(net.minecraft.util.RandomSource.create()); ++ when(handle.getFixerUpper()).thenReturn(net.minecraft.util.datafix.DataFixers.getDataFixer()); ++ MinecraftServer.setServer(handle); ++ // Plazma end ++ + Bukkit.setServer(instance); + } catch (Throwable t) { + throw new Error(t); diff --git a/src/test/java/org/plazmamc/plazma/configurations/GlobalConfigurationTestingBase.java b/src/test/java/org/plazmamc/plazma/configurations/GlobalConfigurationTestingBase.java new file mode 100644 -index 0000000000000000000000000000000000000000..adf57600250b05e1d7cf617d7f58797d2663bca9 +index 0000000000000000000000000000000000000000..c63942e2dc00ed6d6b4119f418bdaa5a64b4c0fe --- /dev/null +++ b/src/test/java/org/plazmamc/plazma/configurations/GlobalConfigurationTestingBase.java -@@ -0,0 +1,18 @@ +@@ -0,0 +1,20 @@ +package org.plazmamc.plazma.configurations; + +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; + +public class GlobalConfigurationTestingBase { -+ public static void setupGlobalConfigurationForTest() { ++ ++ public static void setupGlobalConfigForTest() { + if (GlobalConfiguration.get() == null) { + ConfigurationNode node = PlazmaConfigurations.createForTesting(); + try { + GlobalConfiguration globalConfiguration = node.require(GlobalConfiguration.class); -+ GlobalConfiguration.set(globalConfiguration, true); ++ GlobalConfiguration.set(globalConfiguration); + } catch (SerializationException e) { + throw new RuntimeException(e); + } + } + } ++ +} diff --git a/patches/server/0007-Setup-basic-configuration-sections.patch b/patches/server/0007-Setup-basic-configuration-sections.patch new file mode 100644 index 000000000..9437bdd3f --- /dev/null +++ b/patches/server/0007-Setup-basic-configuration-sections.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sun, 5 Nov 2023 10:47:05 +0900 +Subject: [PATCH] Setup basic configuration sections + + +diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +index 69c4d9cb0532621018f6cd99916c409fc150ab7e..5875aae8d7d0146ef9903d8b4bc2b673a615fd98 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +@@ -23,4 +23,23 @@ public class GlobalConfiguration extends ConfigurationPart { + @Setting(Configuration.VERSION_FIELD) + int version = VERSION; + ++ public Player player; ++ public class Player extends ConfigurationPart { ++ ++ ++ } ++ ++ @Setting("world-generation") ++ public WorldGeneration worldgen; ++ public class WorldGeneration extends ConfigurationPart { ++ ++ ++ } ++ ++ public Miscellaneous misc; ++ public class Miscellaneous extends ConfigurationPart { ++ ++ ++ } ++ + } +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index 842fb520a2d638aaa5bd0a7198190dbe3ecbe14c..a372b5be3b1da5868d3766a8ba58997a48118581 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -19,4 +19,32 @@ public class WorldConfigurations extends ConfigurationPart { + @Setting(Configuration.VERSION_FIELD) + int version = VERSION; + ++ public Miscellaneous misc; ++ public class Miscellaneous extends ConfigurationPart { ++ ++ ++ } ++ ++ public Entity entity; ++ public class Entity extends ConfigurationPart { ++ ++ public Phantom phantom; ++ public class Phantom extends ConfigurationPart { ++ ++ ++ } ++ ++ } ++ ++ public Structure structure; ++ public class Structure extends ConfigurationPart { ++ ++ public NetherPortal netherPortal; ++ public class NetherPortal extends ConfigurationPart { ++ ++ ++ } ++ ++ } ++ + } diff --git a/patches/server/0008-Always-agree-EULA-on-development-mode.patch b/patches/server/0008-Always-agree-EULA-on-development-mode.patch new file mode 100644 index 000000000..2b8764cfb --- /dev/null +++ b/patches/server/0008-Always-agree-EULA-on-development-mode.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sun, 5 Nov 2023 10:13:14 +0900 +Subject: [PATCH] Always agree EULA on development mode + + +diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java +index dc95efdefa3bfbd313aa50b1e5ea17362ab4fc92..5068d942594f19555c6a8f88d49534aba073f722 100644 +--- a/src/main/java/net/minecraft/server/Main.java ++++ b/src/main/java/net/minecraft/server/Main.java +@@ -177,6 +177,7 @@ public class Main { + + // Spigot Start + boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ); ++ eulaAgreed = eulaAgreed || Boolean.getBoolean("Paper.isRunDev"); // Plazma + if ( eulaAgreed ) + { + System.err.println( "You have used the Spigot command line EULA agreement flag." ); diff --git a/patches/server/0007-Add-more-metrics.patch b/patches/server/0009-Add-more-metrics.patch similarity index 85% rename from patches/server/0007-Add-more-metrics.patch rename to patches/server/0009-Add-more-metrics.patch index 8a62d790b..c278c4006 100644 --- a/patches/server/0007-Add-more-metrics.patch +++ b/patches/server/0009-Add-more-metrics.patch @@ -1,18 +1,18 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Wed, 27 Sep 2023 16:02:29 +0900 +Date: Sun, 5 Nov 2023 10:26:26 +0900 Subject: [PATCH] Add more metrics diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index 7d80d2cf5d607d6051e99e4b08bc1b76098a79da..fa88d48adc3aefcd823f431f099e46c94fd071a1 100644 +index 7d80d2cf5d607d6051e99e4b08bc1b76098a79da..f006c867ad0765e0f52a629729ab131acec5c2fc 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java -@@ -636,16 +636,51 @@ public class Metrics { +@@ -636,16 +636,52 @@ public class Metrics { return map; })); -+ // Plazma start - Add more metrics ++ // Plazma start + metrics.addCustomChart(new DrilldownPie("datapacks", () -> { + int datapacks = Bukkit.getDatapackManager().getEnabledPacks().size(); + Map entry = Collections.singletonMap(String.valueOf(datapacks), 1); @@ -22,7 +22,7 @@ index 7d80d2cf5d607d6051e99e4b08bc1b76098a79da..fa88d48adc3aefcd823f431f099e46c9 + else if (datapacks <= 10) return Collections.singletonMap("6-10", entry); + else if (datapacks <= 25) return Collections.singletonMap("11-25", entry); + else if (datapacks <= 50) return Collections.singletonMap("26-50", entry); -+ return Collections.singletonMap("50+", entry); ++ else return Collections.singletonMap("50+", entry); + })); + + List plugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).toList(); @@ -36,19 +36,20 @@ index 7d80d2cf5d607d6051e99e4b08bc1b76098a79da..fa88d48adc3aefcd823f431f099e46c9 + else if (pluginCount <= 10) return Collections.singletonMap("6-10", entry); + else if (pluginCount <= 25) return Collections.singletonMap("11-25", entry); + else if (pluginCount <= 50) return Collections.singletonMap("26-50", entry); -+ return Collections.singletonMap("50+", entry); ++ else return Collections.singletonMap("50+", entry); + })); + + metrics.addCustomChart(new DrilldownPie("disabled_plugins", () -> { + int disabled = (int) plugins.stream().filter(java.util.function.Predicate.not(Plugin::isEnabled)).count(); + Map entry = Collections.singletonMap(String.valueOf(disabled), 1); + -+ if (disabled == 0) return Collections.singletonMap("0 \uD83D\uDE0E", entry); ++ if (disabled == 0) return Collections.singletonMap("0 \uD83D\uDE0E", entry); // :sunglasses: + else if (disabled <= 5) return Collections.singletonMap("1-5", entry); + else if (disabled <= 10) return Collections.singletonMap("6-10", entry); + else if (disabled <= 25) return Collections.singletonMap("11-25", entry); + else if (disabled <= 50) return Collections.singletonMap("26-50", entry); -+ return Collections.singletonMap("50+ \uD83D\uDE2D", entry); ++ else if (disabled <= 100) return Collections.singletonMap("50-100 \uD83D\uDE2D", entry); // :cry: ++ else return Collections.singletonMap("101+ \uD83D\uDC80", entry); // :skull: + })); + // Plazma end + diff --git a/patches/server/0008-Optimize-default-configurations.patch b/patches/server/0010-Optimize-default-configurations.patch similarity index 60% rename from patches/server/0008-Optimize-default-configurations.patch rename to patches/server/0010-Optimize-default-configurations.patch index bf2d7a08b..0c00d66ca 100644 --- a/patches/server/0008-Optimize-default-configurations.patch +++ b/patches/server/0010-Optimize-default-configurations.patch @@ -3,149 +3,266 @@ From: AlphaKR93 Date: Wed, 27 Sep 2023 16:42:17 +0900 Subject: [PATCH] Optimize default configurations -Reference: YouHaveTrouble/minecraft-optimization, AkiraDevelopment/SimplyMC +[REFERENCE] +- YouHaveTrouble/minecraft-optimization +- AkiraDevelopment/SimplyMC +- YouHaveTrouble/minecraft-exploits-and-how-to-fix-them diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -index 5f223856b06e901b100fcca8e6dd968e0b2e3a8e..13df89e7cc219cdb80c4114d05148c685ad2ecee 100644 +index 9ca1494497ae53e56b1f81fda51b0b8bd02a6d03..97b1366d25537d68469e95ac101b1b8cf9fdc997 100644 --- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -@@ -72,7 +72,7 @@ public class PufferfishConfig { +@@ -64,7 +64,7 @@ public class PufferfishConfig { getString("info.version", "1.0"); setComment("info", "Pufferfish Configuration", - "Check out Pufferfish Host for maximum performance server hosting: https://pufferfish.host", -+ //"Check out Pufferfish Host for maximum performance server hosting: https://pufferfish.host", // Plazma - no advertisement ++ //"Check out Pufferfish Host for maximum performance server hosting: https://pufferfish.host", // Plazma - Nope "Join our Discord for support: https://discord.gg/reZw4vQV9H", "Download new builds at https://ci.pufferfish.host/job/Pufferfish"); -@@ -219,7 +219,7 @@ public class PufferfishConfig { +@@ -211,7 +211,7 @@ public class PufferfishConfig { public static int maxProjectileLoadsPerTick; public static int maxProjectileLoadsPerProjectile; private static void projectileLoading() { - maxProjectileLoadsPerTick = getInt("projectile.max-loads-per-tick", 10, "Controls how many chunks are allowed", "to be sync loaded by projectiles in a tick."); -+ maxProjectileLoadsPerTick = getInt("projectile.max-loads-per-tick", org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 8 : 10, "Controls how many chunks are allowed", "to be sync loaded by projectiles in a tick."); // Plazma - Optimize default configurations ++ maxProjectileLoadsPerTick = getInt("projectile.max-loads-per-tick", org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 8 : 10, "Controls how many chunks are allowed", "to be sync loaded by projectiles in a tick."); // Plazma - Optimize default configurations maxProjectileLoadsPerProjectile = getInt("projectile.max-loads-per-projectile", 10, "Controls how many chunks a projectile", "can load in its lifetime before it gets", "automatically removed."); setComment("projectile", "Optimizes projectile settings"); -@@ -233,7 +233,7 @@ public class PufferfishConfig { +@@ -225,7 +225,7 @@ public class PufferfishConfig { public static int activationDistanceMod; private static void dynamicActivationOfBrains() throws IOException { - dearEnabled = getBoolean("dab.enabled", "activation-range.enabled", false); // Purpur -+ dearEnabled = getBoolean("dab.enabled", "activation-range.enabled", org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize()); // Purpur // Plazma - Optimize default configurations ++ dearEnabled = getBoolean("dab.enabled", "activation-range.enabled", org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize()); // Purpur // Plazma - Optimize default configurations startDistance = getInt("dab.start-distance", "activation-range.start-distance", 12, "This value determines how far away an entity has to be", "from the player to start being effected by DEAR."); -@@ -241,7 +241,7 @@ public class PufferfishConfig { +@@ -233,7 +233,7 @@ public class PufferfishConfig { maximumActivationPrio = getInt("dab.max-tick-freq", "activation-range.max-tick-freq", 20, "This value defines how often in ticks, the furthest entity", "will get their pathfinders and behaviors ticked. 20 = 1s"); - activationDistanceMod = getInt("dab.activation-dist-mod", "activation-range.activation-dist-mod", 8, -+ activationDistanceMod = getInt("dab.activation-dist-mod", "activation-range.activation-dist-mod", org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 7 : 8, // Plazma - Optimize default configurations ++ activationDistanceMod = getInt("dab.activation-dist-mod", "activation-range.activation-dist-mod", org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 7 : 8, // Plazma - Optimize default configurations "This value defines how much distance modifies an entity's", "tick frequency. freq = (distanceToPlayer^2) / (2^value)", "If you want further away entities to tick less often, use 7.", +@@ -253,8 +253,18 @@ public class PufferfishConfig { + public static Map projectileTimeouts; + private static void projectileTimeouts() { + // Set some defaults ++ // Plazma start - Optimize default configurations ++ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize()) { ++ getInt("entity_timeouts.ARROW", 200); ++ getInt("entity_timeouts.EGG", 200); ++ getInt("entity_timeouts.ENDER_PEARL", 200); ++ getInt("entity_timeouts.SNOWBALL", 200); ++ getInt("entity_timeouts.LLAMA_SPIT", 200); ++ } else { ++ // Plazma end + getInt("entity_timeouts.SNOWBALL", -1); + getInt("entity_timeouts.LLAMA_SPIT", -1); ++ } // Plazma + setComment("entity_timeouts", + "These values define a entity's maximum lifespan. If an", + "entity is in this list and it has survived for longer than", diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index c69892a5f31895b85e530beadd8864ac32470ba7..5f652268dadaca96a98203ad12d7a0ba0b19563b 100644 +index a6f58b3457b7477015c5c6d969e7d83017dd3fa1..85e56d726eb7780811e0a990e1ef7d3ec767e36d 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -154,7 +154,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -155,7 +155,7 @@ public class GlobalConfiguration extends ConfigurationPart { public class Watchdog extends ConfigurationPart { public int earlyWarningEvery = 5000; - public int earlyWarningDelay = 10000; -+ public int earlyWarningDelay = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 180000 : 10000; // Plazma - Optimize default configurations ++ public int earlyWarningDelay = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 180000 : 10000; // Plazma - Optimize default configurations } public SpamLimiter spamLimiter; +@@ -193,7 +193,7 @@ public class GlobalConfiguration extends ConfigurationPart { + public Commands commands; + + public class Commands extends ConfigurationPart { +- public boolean suggestPlayerNamesWhenNullTabCompletions = true; ++ public boolean suggestPlayerNamesWhenNullTabCompletions = !org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations + public boolean fixTargetSelectorTagCompletion = true; + public boolean timeCommandAffectsAllWorlds = false; + } +@@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { + public BookSize bookSize; + + public class BookSize extends ConfigurationPart { +- public int pageMax = 2560; // TODO this appears to be a duplicate setting with one above ++ public int pageMax = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 1024 : 2560; // TODO this appears to be a duplicate setting with one above // Plazma - Optimize default configurations + public double totalMultiplier = 0.98D; // TODO this should probably be merged into the above inner class + } + public boolean resolveSelectorsInBooks = false; +@@ -253,7 +253,15 @@ public class GlobalConfiguration extends ConfigurationPart { + public class PacketLimiter extends ConfigurationPart { + public Component kickMessage = Component.translatable("disconnect.exceeded_packet_rate", NamedTextColor.RED); + public PacketLimit allPackets = new PacketLimit(7.0, 500.0, PacketLimit.ViolateAction.KICK); +- public Map>, PacketLimit> overrides = Map.of(ServerboundPlaceRecipePacket.class, new PacketLimit(4.0, 5.0, PacketLimit.ViolateAction.DROP)); ++ // Plazma start - Optimize default configurations ++ public Map>, PacketLimit> overrides = new java.util.HashMap<>() {{ ++ put(ServerboundPlaceRecipePacket.class, new PacketLimit(4.0, 5.0, PacketLimit.ViolateAction.DROP)); ++ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize()) { ++ put(net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket.class, new PacketLimit(1.0, 15.0, PacketLimit.ViolateAction.DROP)); ++ put(net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket.class, new PacketLimit(4.0, 5.0, PacketLimit.ViolateAction.DROP)); ++ } ++ }}; ++ // Plazma end + + @ConfigSerializable + public record PacketLimit(@Required double interval, @Required double maxPacketRate, ViolateAction action) { +@@ -321,7 +329,7 @@ public class GlobalConfiguration extends ConfigurationPart { + executor.setMaximumPoolSize(_chatExecutorMaxSize); + } + } +- public int maxJoinsPerTick = 5; ++ public int maxJoinsPerTick = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 3 : 5; // Plazma - Optimize default configurations + public boolean fixEntityPositionDesync = true; + public boolean loadPermissionsYmlBeforePlugins = true; + @Constraints.Min(4) diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -index ec5e23136423e42e4f55e6ea646b8285c1ca14e2..a1d22ad65fc751fa93384f59853434ab65836133 100644 +index 071d3877e386a0c7c4d2f2e8ddd06e0765c49d0d..79e2a6806311c402e481c5b29cbd3ced85101f6e 100644 --- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -88,15 +88,27 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -96,12 +96,32 @@ public class WorldConfiguration extends ConfigurationPart { public class AntiXray extends ConfigurationPart { public boolean enabled = false; - public EngineMode engineMode = EngineMode.HIDE; -+ public EngineMode engineMode = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? EngineMode.OBFUSCATE_LAYER : EngineMode.HIDE; // Plazma - Optimize default configurations ++ public EngineMode engineMode = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? EngineMode.OBFUSCATE_LAYER : EngineMode.HIDE; // Plazma - Optimize default configurations public int maxBlockHeight = 64; public int updateRadius = 2; - public boolean lavaObscures = false; +- public boolean lavaObscures = false; ++ public boolean lavaObscures = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations public boolean usePermission = false; -- public List hiddenBlocks = List.of("copper_ore", "deepslate_copper_ore", "gold_ore", "deepslate_gold_ore", "iron_ore", "deepslate_iron_ore", -- "coal_ore", "deepslate_coal_ore", "lapis_ore", "deepslate_lapis_ore", "mossy_cobblestone", "obsidian", "chest", "diamond_ore", "deepslate_diamond_ore", -- "redstone_ore", "deepslate_redstone_ore", "clay", "emerald_ore", "deepslate_emerald_ore", "ender_chest"); // TODO update type to List -- public List replacementBlocks = List.of("stone", "oak_planks", "deepslate"); // TODO update type to List +- public List hiddenBlocks = List.of( + // Plazma start - Optimize default configurations -+ public List hiddenBlocks = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? -+ List.of("air", "copper_ore", "deepslate_copper_ore", "raw_copper_block", "iron_ore", -+ "deepslate_iron_ore", "raw_iron_block", "gold_ore", "deepslate_gold_ore", "raw_gold_block", -+ "lapis_ore", "deepslate_lapis_ore", "redstone_ore", "deepslate_redstone_ore", "diamond_ore", -+ "deepslate_diamond_ore") : -+ List.of("copper_ore", "deepslate_copper_ore","gold_ore", "deepslate_gold_ore", -+ "iron_ore", "deepslate_iron_ore", "coal_ore", "deepslate_coal_ore", "lapis_ore", -+ "deepslate_lapis_ore", "mossy_cobblestone", "obsidian", "chest", "diamond_ore", -+ "deepslate_diamond_ore", "redstone_ore", "deepslate_redstone_ore", "clay", "emerald_ore", -+ "deepslate_emerald_ore", "ender_chest");; // TODO update type to List -+ public List replacementBlocks = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? -+ List.of("chest", "amethyst_block", "andesite", "budding_amethyst", "calcite", "coal_ore", -+ "deepslate_coal_ore", "deepslate", "diorite", "dirt", "emerald_ore", "granite", "gravel", -+ "oak_planks", "smooth_basalt", "stone", "tuff") : List.of("stone", "oak_planks", "deepslate"); // TODO update type to List ++ public List hiddenBlocks = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? List.of( ++ // ++ Blocks.AIR, ++ Blocks.COPPER_ORE, ++ Blocks.DEEPSLATE_COPPER_ORE, ++ Blocks.RAW_COPPER_BLOCK, ++ Blocks.IRON_ORE, ++ Blocks.DEEPSLATE_IRON_ORE, ++ Blocks.RAW_IRON_BLOCK, ++ Blocks.GOLD_ORE, ++ Blocks.DEEPSLATE_GOLD_ORE, ++ Blocks.RAW_GOLD_BLOCK, ++ Blocks.REDSTONE_ORE, ++ Blocks.DEEPSLATE_REDSTONE_ORE, ++ Blocks.LAPIS_ORE, ++ Blocks.DEEPSLATE_LAPIS_ORE, ++ Blocks.DIAMOND_ORE, ++ Blocks.DEEPSLATE_DIAMOND_ORE ++ // ++ ) : List.of( + // + Blocks.COPPER_ORE, + Blocks.DEEPSLATE_COPPER_ORE, +@@ -128,7 +148,28 @@ public class WorldConfiguration extends ConfigurationPart { + Blocks.ENDER_CHEST + // + ); +- public List replacementBlocks = List.of(Blocks.STONE, Blocks.OAK_PLANKS, Blocks.DEEPSLATE); ++ public List replacementBlocks = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? List.of( ++ // ++ Blocks.CHEST, ++ Blocks.AMETHYST_BLOCK, ++ Blocks.ANDESITE, ++ Blocks.BUDDING_AMETHYST, ++ Blocks.CALCITE, ++ Blocks.COAL_ORE, ++ Blocks.DEEPSLATE_COAL_ORE, ++ Blocks.DEEPSLATE, ++ Blocks.DIORITE, ++ Blocks.DIRT, ++ Blocks.EMERALD_ORE, ++ Blocks.GRANITE, ++ Blocks.GRAVEL, ++ Blocks.OAK_PLANKS, ++ Blocks.SMOOTH_BASALT, ++ Blocks.STONE, ++ Blocks.TUFF ++ // ++ ) : List.of(Blocks.STONE, Blocks.OAK_PLANKS, Blocks.DEEPSLATE); + // Plazma end } } -@@ -150,7 +162,7 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -152,14 +193,14 @@ public class WorldConfiguration extends ConfigurationPart { + public ArmorStands armorStands; + + public class ArmorStands extends ConfigurationPart { +- public boolean doCollisionEntityLookups = true; +- public boolean tick = true; ++ public boolean doCollisionEntityLookups = !org.plazmamc.plazma.Options.aggressiveOptimize; // Plazma - Optimize default configurations ++ public boolean tick = !org.plazmamc.plazma.Options.aggressiveOptimize; // Plazma - Optimize default configurations + } + + public Markers markers; + + public class Markers extends ConfigurationPart { +- public boolean tick = true; ++ public boolean tick = !org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations + } + + public Sniffer sniffer; +@@ -182,7 +223,7 @@ public class WorldConfiguration extends ConfigurationPart { @MergeMap public Reference2IntMap spawnLimits = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1))); @MergeMap - public Map despawnRanges = Arrays.stream(MobCategory.values()).collect(Collectors.toMap(Function.identity(), category -> new DespawnRange(category.getNoDespawnDistance(), category.getDespawnDistance()))); -+ public Map despawnRanges = Arrays.stream(MobCategory.values()).collect(Collectors.toMap(Function.identity(), category -> new DespawnRange(category.getNoDespawnDistance(), org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? (net.minecraft.server.MinecraftServer.getServer().server.getSimulationDistance() * 16) + 8 : category.getDespawnDistance()))); // Plazma - Optimize default configurations ++ public Map despawnRanges = Arrays.stream(MobCategory.values()).collect(Collectors.toMap(Function.identity(), category -> new DespawnRange(category.getNoDespawnDistance(), org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? (net.minecraft.server.MinecraftServer.getServer().server.getSimulationDistance() * 16) + 8 : category.getDespawnDistance()))); // Plazma - Optimize default configurations @ConfigSerializable public record DespawnRange(@Required int soft, @Required int hard) { -@@ -375,7 +387,7 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -381,7 +422,7 @@ public class WorldConfiguration extends ConfigurationPart { public class Environment extends ConfigurationPart { public boolean disableThunder = false; public boolean disableIceAndSnow = false; - public boolean optimizeExplosions = false; -+ public boolean optimizeExplosions = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize(); // Plazma - Optimize default configurations ++ public boolean optimizeExplosions = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations public boolean disableExplosionKnockback = false; public boolean generateFlatBedrock = false; public FrostedIce frostedIce; -@@ -427,7 +439,7 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -433,7 +474,7 @@ public class WorldConfiguration extends ConfigurationPart { public Fixes fixes; public class Fixes extends ConfigurationPart { - public boolean fixItemsMergingThroughWalls = false; -+ public boolean fixItemsMergingThroughWalls = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize(); // Plazma - Optimize default configurations ++ public boolean fixItemsMergingThroughWalls = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations public boolean disableUnloadedChunkEnderpearlExploit = true; public boolean preventTntFromMovingInWater = false; public boolean splitOverstackedLoot = true; -@@ -455,9 +467,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -460,9 +501,9 @@ public class WorldConfiguration extends ConfigurationPart { public class Collisions extends ConfigurationPart { public boolean onlyPlayersCollide = false; public boolean allowVehicleCollisions = true; - public boolean fixClimbingBypassingCrammingRule = false; -+ public boolean fixClimbingBypassingCrammingRule = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize(); // Plazma - Optimize default configurations ++ public boolean fixClimbingBypassingCrammingRule = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations @RequiresSpigotInitialization(MaxEntityCollisionsInitializer.class) - public int maxEntityCollisions = 8; -+ public int maxEntityCollisions = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 2 : 8; // Plazma - Optimize default configurations ++ public int maxEntityCollisions = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 2 : 8; // Plazma - Optimize default configurations public boolean allowPlayerCrammingDamage = false; } -@@ -465,18 +477,40 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -470,18 +511,41 @@ public class WorldConfiguration extends ConfigurationPart { public class Chunks extends ConfigurationPart { public AutosavePeriod autoSaveInterval = AutosavePeriod.def(); - public int maxAutoSaveChunksPerTick = 24; -+ public int maxAutoSaveChunksPerTick = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 8 : 24; // Plazma - Optimize default configurations ++ public int maxAutoSaveChunksPerTick = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 8 : 24; // Plazma - Optimize default configurations public int fixedChunkInhabitedTime = -1; - public boolean preventMovingIntoUnloadedChunks = false; -+ public boolean preventMovingIntoUnloadedChunks = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize(); // Plazma - Optimize default configurations ++ public boolean preventMovingIntoUnloadedChunks = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize(); // Plazma - Optimize default configurations public Duration delayChunkUnloadsBy = Duration.of("10s"); public Reference2IntMap> entityPerChunkSaveLimit = Util.make(new Reference2IntOpenHashMap<>(BuiltInRegistries.ENTITY_TYPE.size()), map -> { -- map.defaultReturnValue(-1); + map.defaultReturnValue(-1); - map.put(EntityType.EXPERIENCE_ORB, -1); - map.put(EntityType.SNOWBALL, -1); - map.put(EntityType.ENDER_PEARL, -1); @@ -153,7 +270,7 @@ index ec5e23136423e42e4f55e6ea646b8285c1ca14e2..a1d22ad65fc751fa93384f59853434ab - map.put(EntityType.FIREBALL, -1); - map.put(EntityType.SMALL_FIREBALL, -1); + // Plazma start - Optimize default configurations -+ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize()) { ++ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize()) { + map.put(EntityType.AREA_EFFECT_CLOUD, 8); + map.put(EntityType.ARROW, 16); + map.put(EntityType.DRAGON_FIREBALL, 3); @@ -184,86 +301,75 @@ index ec5e23136423e42e4f55e6ea646b8285c1ca14e2..a1d22ad65fc751fa93384f59853434ab }); public boolean flushRegionsOnSave = false; } -@@ -491,9 +525,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -496,9 +560,9 @@ public class WorldConfiguration extends ConfigurationPart { public TickRates tickRates; public class TickRates extends ConfigurationPart { - public int grassSpread = 1; -+ public int grassSpread = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 4 : 1; // Plazma - Optimize default configurations ++ public int grassSpread = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 4 : 1; // Plazma - Optimize default configurations public int containerUpdate = 1; - public int mobSpawner = 1; -+ public int mobSpawner = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? 2 : 1; // Plazma - Optimize default configurations ++ public int mobSpawner = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? 2 : 1; // Plazma - Optimize default configurations + public int wetFarmland = 1; + public int dryFarmland = 1; public Table, String, Integer> sensor = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "secondarypoisensor", 40)); - public Table, String, Integer> behavior = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "validatenearbypoi", -1)); - } -@@ -517,9 +551,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -525,9 +589,9 @@ public class WorldConfiguration extends ConfigurationPart { public class Misc extends ConfigurationPart { public int lightQueueSize = 20; - public boolean updatePathfindingOnBlockUpdate = true; -+ public boolean updatePathfindingOnBlockUpdate = !org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize(); // Plazma - Optimize default configurations ++ public boolean updatePathfindingOnBlockUpdate = !org.plazmamc.plazma.Options.aggressiveOptimize; // Plazma - Optimize default configurations public boolean showSignClickCommandFailureMsgsToPlayer = false; - public RedstoneImplementation redstoneImplementation = RedstoneImplementation.VANILLA; -+ public RedstoneImplementation redstoneImplementation = org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? RedstoneImplementation.ALTERNATE_CURRENT : RedstoneImplementation.VANILLA; // Plazma - Optimize default configurations ++ public RedstoneImplementation redstoneImplementation = org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? RedstoneImplementation.ALTERNATE_CURRENT : RedstoneImplementation.VANILLA; // Plazma - Optimize default configurations public boolean disableEndCredits = false; public float maxLeashDistance = 10f; public boolean disableSprintInterruptionOnAttack = false; diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/ArrowDespawnRate.java b/src/main/java/io/papermc/paper/configuration/type/fallback/ArrowDespawnRate.java -index 24763d3d270c29c95e0b3e85111145234f660a62..ba7cf430cdff947a74ae067fc79020ae01e7e457 100644 +index 24763d3d270c29c95e0b3e85111145234f660a62..80ddc627e02e3c749e6b074afa93d357d9c7d62a 100644 --- a/src/main/java/io/papermc/paper/configuration/type/fallback/ArrowDespawnRate.java +++ b/src/main/java/io/papermc/paper/configuration/type/fallback/ArrowDespawnRate.java @@ -29,6 +29,7 @@ public class ArrowDespawnRate extends FallbackValue.Int { @Override protected int fallback() { -+ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize()) return 100; // Plazma - Optimize default configurations ++ if (org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize()) return 100; // Plazma - Optimize default configurations return this.get(FallbackValue.SPIGOT_WORLD_CONFIG).arrowDespawnRate; } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 30fc258faa6f087cf3c91411b48116a3ac416031..a32a1787cbcacb0d3ed6f0d751a04e8fa9d11dd6 100644 +index 5068d942594f19555c6a8f88d49534aba073f722..8afa3ac6f314d0f3def7d19aedceefed424d9e11 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java -@@ -163,7 +163,7 @@ public class Main { +@@ -162,7 +162,7 @@ public class Main { File configFile = (File) optionset.valueOf("bukkit-settings"); YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); configuration.options().copyDefaults(true); - configuration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"), Charsets.UTF_8))); -+ configuration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream(org.plazmamc.plazma.configurations.PlazmaConfigurations.doOptimize() ? "configurations/bukkit_optimized.yml" : "configurations/bukkit.yml"), Charsets.UTF_8))); ++ configuration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream(org.plazmamc.plazma.configurations.PlazmaConfigurations.optimize() ? "configurations/bukkit_optimized.yml" : "configurations/bukkit.yml"), Charsets.UTF_8))); // Plazma - Optimize default configurations configuration.save(configFile); File commandFile = (File) optionset.valueOf("commands-settings"); -@@ -177,8 +177,7 @@ public class Main { - } - - // Spigot Start -- boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ); -- eulaAgreed = eulaAgreed || Boolean.getBoolean("Paper.isRunDev"); -+ boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ) || Boolean.getBoolean("Paper.isRunDev"); // Plazma - if ( eulaAgreed ) - { - System.err.println( "You have used the Spigot command line EULA agreement flag." ); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index cda4544ae96a4fcb5c6c4483df67a59f1b53fd27..54f2c5187322c6dea70c4e0e63cce2e68e7ac647 100644 +index cda4544ae96a4fcb5c6c4483df67a59f1b53fd27..2282992d04669a705a5b67f616fe921c289182ab 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -@@ -130,15 +130,15 @@ public class DedicatedServerProperties extends Settings -Date: Wed, 27 Sep 2023 16:55:12 +0900 -Subject: [PATCH] Console logging tweaks +Date: Sun, 5 Nov 2023 10:40:49 +0900 +Subject: [PATCH] Tweak console logging diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index e4fd372a1d585887287253a02531cd192929377b..dae0b0e1288afe0d8eb70d0e8e2db152aad42bf4 100644 +index e4fd372a1d585887287253a02531cd192929377b..6624fb97404c3032d60167e3fb108dcfcd066784 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -355,7 +355,7 @@ public final class ChatProcessor { @@ -13,12 +13,12 @@ index e4fd372a1d585887287253a02531cd192929377b..dae0b0e1288afe0d8eb70d0e8e2db152 private void sendToServer(final ChatType.Bound chatType, final @Nullable Function msgFunction) { final PlayerChatMessage toConsoleMessage = msgFunction == null ? ChatProcessor.this.message : ChatProcessor.this.message.withUnsignedContent(msgFunction.apply(ChatProcessor.this.server.console)); - ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) ? null : "Not Secure"); -+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.notSecurePrefix || ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage)) ? null : "Not Secure"); // Plazma ++ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.notSecurePrefix || ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage)) ? null : "Not Secure"); // Plazma - Tweak console logging } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index a970e00482952318c258fc406cb7c39a229b65bc..879c090d9c4574a2cd45a0eb1bf9cb171834d940 100644 +index 00fbcb941fe393197619762722eb51d62fb073c2..770b959d9e51ef0645415d5a0d7d79b7031abd66 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -180,16 +180,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -38,24 +38,19 @@ index a970e00482952318c258fc406cb7c39a229b65bc..879c090d9c4574a2cd45a0eb1bf9cb17 DedicatedServer.LOGGER.info("Loading properties"); DedicatedServerProperties dedicatedserverproperties = this.settings.getProperties(); -@@ -318,6 +308,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -319,6 +309,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord"; String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/"; // Paper end -+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.offlineWarnings) // Plazma - Console logging tweaks ++ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.offlineWarnings) // Plazma - Tweak console logging if (!this.usesAuthentication()) { DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); -@@ -331,9 +322,21 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); - } - // Spigot end -- DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); -+ DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file or set \"console-logs.offline-warning\" to \"false\" in the config/plazma-global.yml file."); // Plazma +@@ -335,6 +326,17 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); } -+ // Plazma start - Console logging tweaks -+ // Moved down ++ // Plazma - Moved down - Tweak console logging + // Paper start - detect running as root + if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.rootUserWarnings && io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin()) { + DedicatedServer.LOGGER.warn("****************************"); @@ -70,27 +65,25 @@ index a970e00482952318c258fc406cb7c39a229b65bc..879c090d9c4574a2cd45a0eb1bf9cb17 if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { return false; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 5c38df8170033dbfee267520991a3cc3285d219e..58cc1bed851994fb591e9b832b98d25eda153b47 100644 +index 182acaad79e14e5e120094916a0d295a4584de7a..e8de78f8b7c90a719e10c483991f45a7886256be 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1440,7 +1440,7 @@ public abstract class PlayerList { - } +@@ -1462,6 +1462,7 @@ public abstract class PlayerList { public void broadcastChatMessage(PlayerChatMessage message, Predicate shouldSendFiltered, @Nullable ServerPlayer sender, ChatType.Bound params, @Nullable Function unsignedFunction) { // Paper end -- boolean flag = this.verifyChatTrusted(message); -+ boolean flag = !org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.notSecurePrefix || this.verifyChatTrusted(message); // Plazma + boolean flag = this.verifyChatTrusted(message); ++ flag = flag || org.plazmamc.plazma.configurations.GlobalConfiguration.get().consoleLogs.notSecurePrefix; // Plazma - Tweak console logging this.server.logChatMessage((unsignedFunction == null ? message.decoratedContent() : unsignedFunction.apply(this.server.console)), params, flag ? null : "Not Secure"); // Paper OutgoingChatMessage outgoingchatmessage = OutgoingChatMessage.create(message); diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index d506e0c2b37f91e46e682652bd134ad91db28f84..44df2c0a1ed3d006b455ba2a47d6bc9059d804e1 100644 +index 5875aae8d7d0146ef9903d8b4bc2b673a615fd98..51413e828500792cc493b836bb1460a394ff4f75 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -40,4 +40,13 @@ public class GlobalConfiguration extends ConfigurationPart { - public class Player extends ConfigurationPart { +@@ -42,4 +42,13 @@ public class GlobalConfiguration extends ConfigurationPart { } -+ + + public ConsoleLogs consoleLogs; + public class ConsoleLogs extends ConfigurationPart { + @@ -99,4 +92,5 @@ index d506e0c2b37f91e46e682652bd134ad91db28f84..44df2c0a1ed3d006b455ba2a47d6bc90 + public boolean notSecurePrefix = true; + + } ++ } diff --git a/patches/server/0010-Add-option-to-allow-any-usernames.patch b/patches/server/0012-Add-option-to-allow-any-usernames.patch similarity index 81% rename from patches/server/0010-Add-option-to-allow-any-usernames.patch rename to patches/server/0012-Add-option-to-allow-any-usernames.patch index a6404e947..bd7ae31e9 100644 --- a/patches/server/0010-Add-option-to-allow-any-usernames.patch +++ b/patches/server/0012-Add-option-to-allow-any-usernames.patch @@ -1,14 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Wed, 27 Sep 2023 16:59:14 +0900 +Date: Sun, 5 Nov 2023 10:49:05 +0900 Subject: [PATCH] Add option to allow any usernames diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index b875f4af9dcb45bcad0ee59a958442ba673268fe..d38685f82d2e6c4e71179bf3a85a8b183aa6c44b 100644 +index 3dcccca8ede9b203c24ba29b2020a583297b895c..dd707019fb9b2c46d706311862fea91b84793ff9 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -161,6 +161,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -160,6 +160,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleHello(ServerboundHelloPacket packet) { Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]); @@ -17,15 +17,14 @@ index b875f4af9dcb45bcad0ee59a958442ba673268fe..d38685f82d2e6c4e71179bf3a85a8b18 // Paper start - validate usernames if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation) { diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 44df2c0a1ed3d006b455ba2a47d6bc9059d804e1..00c95194788d56f539d1c75e9a1ce48e950c096c 100644 +index 51413e828500792cc493b836bb1460a394ff4f75..c85f1a01c951f85c2347eba18a896e87c4c8b368 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -39,6 +39,8 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -26,6 +26,7 @@ public class GlobalConfiguration extends ConfigurationPart { public Player player; public class Player extends ConfigurationPart { + public boolean allowAnyUsername = false; -+ + } - public ConsoleLogs consoleLogs; diff --git a/patches/server/0011-Add-missing-purpur-configuration-options.patch b/patches/server/0013-Add-missing-purpur-configuration-options.patch similarity index 95% rename from patches/server/0011-Add-missing-purpur-configuration-options.patch rename to patches/server/0013-Add-missing-purpur-configuration-options.patch index 2b2911745..6e4529097 100644 --- a/patches/server/0011-Add-missing-purpur-configuration-options.patch +++ b/patches/server/0013-Add-missing-purpur-configuration-options.patch @@ -33,7 +33,7 @@ index c783ce59ea766e6c46a3313628b961f27e01ee8b..3f36eedeae4b94ca684c57f4ec8d2d1a @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index 1d84135c709a90843b1ee34fb47508e78a7ce95d..c97ef420581803b569d130b58a97f67d1fee54f2 100644 +index cd9129bb5049c13f08c58b8581d511b59a5bb1b5..bcc3458afac5ece9637df63b9d02c445aa0a4ef9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java @@ -95,6 +95,18 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl @@ -163,7 +163,7 @@ index 5e66c2bd3807619cadee5b7081d93d21886e2806..66d47c1613532189e761c0f48d893652 @Override diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -index e88c39d405fc7068db64ad34a03dec8d559e749e..bb5d42ca73722f3a02154ed889625ded2ac63e6f 100644 +index d70c1206df96b03c031399049a65e6a765d80347..e885d2f21cfbf1fd1c61b29e34f3f51a9decfe88 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java @@ -41,7 +41,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain @@ -185,7 +185,7 @@ index e88c39d405fc7068db64ad34a03dec8d559e749e..bb5d42ca73722f3a02154ed889625ded @Override diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index 5f0b10932f8dda09131ba68207cbfea4715e0f33..92cb442d9326b4fd47cd6ec0425192f751d3e538 100644 +index f52802e871efb73c02b9d11d914fd17d417ebc55..075108ca9d5123e4d0bbae16fff9479029c93494 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -329,6 +329,7 @@ public class PurpurConfig { @@ -205,10 +205,10 @@ index 5f0b10932f8dda09131ba68207cbfea4715e0f33..92cb442d9326b4fd47cd6ec0425192f7 org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724ab4f69a7 100644 +index 9cb79d203b6ec345d719cd488d2cce8f877fe2bd..fc30f2dcf7227f7cd087b2e5b8d3dc73e18405c6 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1113,7 +1113,15 @@ public class PurpurWorldConfig { +@@ -1115,7 +1115,15 @@ public class PurpurWorldConfig { public boolean allayRidableInWater = true; public boolean allayControllable = true; public List allayRespectNBT = new ArrayList<>(); @@ -224,7 +224,7 @@ index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724 allayRidable = getBoolean("mobs.allay.ridable", allayRidable); allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); allayControllable = getBoolean("mobs.allay.controllable", allayControllable); -@@ -1232,7 +1240,15 @@ public class PurpurWorldConfig { +@@ -1234,7 +1242,15 @@ public class PurpurWorldConfig { public double camelMovementSpeedMin = 0.09D; public double camelMovementSpeedMax = 0.09D; public int camelBreedingTicks = 6000; @@ -240,7 +240,7 @@ index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724 camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin); camelMaxHealthMax = getDouble("mobs.camel.attributes.max_health.max", camelMaxHealthMax); -@@ -1660,7 +1676,15 @@ public class PurpurWorldConfig { +@@ -1662,7 +1678,15 @@ public class PurpurWorldConfig { public boolean frogControllable = true; public float frogRidableJumpHeight = 0.65F; public int frogBreedingTicks = 6000; @@ -256,7 +256,7 @@ index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724 frogRidable = getBoolean("mobs.frog.ridable", frogRidable); frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); frogControllable = getBoolean("mobs.frog.controllable", frogControllable); -@@ -2613,7 +2637,13 @@ public class PurpurWorldConfig { +@@ -2617,7 +2641,13 @@ public class PurpurWorldConfig { public boolean snifferControllable = true; public double snifferMaxHealth = 14.0D; public int snifferBreedingTicks = 6000; @@ -270,7 +270,7 @@ index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724 snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); -@@ -2712,7 +2742,15 @@ public class PurpurWorldConfig { +@@ -2716,7 +2746,15 @@ public class PurpurWorldConfig { public boolean tadpoleRidable = false; public boolean tadpoleRidableInWater = true; public boolean tadpoleControllable = true; @@ -286,7 +286,7 @@ index d65d3fd4572a4f5c9b3d2d4e2c0a907aae824cde..1ea0fe11fd9e9a8f300efc85926b9724 tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); -@@ -2922,7 +2960,15 @@ public class PurpurWorldConfig { +@@ -2926,7 +2964,15 @@ public class PurpurWorldConfig { public boolean wardenRidable = false; public boolean wardenRidableInWater = true; public boolean wardenControllable = true; diff --git a/patches/server/0013-Add-some-missing-Pufferfish-configurations.patch b/patches/server/0014-Add-some-missing-Pufferfish-configurations.patch similarity index 100% rename from patches/server/0013-Add-some-missing-Pufferfish-configurations.patch rename to patches/server/0014-Add-some-missing-Pufferfish-configurations.patch diff --git a/patches/server/0014-Configurable-nether-portal-size.patch b/patches/server/0014-Configurable-nether-portal-size.patch deleted file mode 100644 index 73e46ce22..000000000 --- a/patches/server/0014-Configurable-nether-portal-size.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Sat, 25 Mar 2023 00:10:52 +0900 -Subject: [PATCH] Configurable nether portal size - -Configurable nether portal size - -diff --git a/src/main/java/net/minecraft/world/level/portal/PortalShape.java b/src/main/java/net/minecraft/world/level/portal/PortalShape.java -index e7554ec800f321e4e34c926c53f2375a8c3aa979..c7f974e0b614afa1ced716ff7b6c67ee037a4071 100644 ---- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java -+++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java -@@ -100,7 +100,7 @@ public class PortalShape { - private int calculateWidth() { - int i = this.getDistanceUntilEdgeAboveFrame(this.bottomLeft, this.rightDir); - -- return i >= 2 && i <= 21 ? i : 0; -+ return i >= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.width.min() && i <= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.width.max() ? i : 0; // Plazma - } - - private int getDistanceUntilEdgeAboveFrame(BlockPos pos, Direction direction) { -@@ -133,7 +133,7 @@ public class PortalShape { - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); - int i = this.getDistanceUntilTop(blockposition_mutableblockposition); - -- return i >= 3 && i <= 21 && this.hasTopFrame(blockposition_mutableblockposition, i) ? i : 0; -+ return i >= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.height.min() && i <= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.height.max() && this.hasTopFrame(blockposition_mutableblockposition, i) ? i : 0; // Plazma - } - - private boolean hasTopFrame(BlockPos.MutableBlockPos pos, int height) { -@@ -187,7 +187,7 @@ public class PortalShape { - } - - public boolean isValid() { -- return this.bottomLeft != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21; -+ return this.bottomLeft != null && this.width >= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.width.min() && this.width <= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.width.max() && this.height >= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.height.min() && this.height <= this.level.getMinecraftWorld().plazmaLevelConfiguration().structure.netherPortal.size.height.max(); // Plazma - } - - // CraftBukkit start - return boolean -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index d990c031255daf0d43541efe175c5b52736a6990..36c367c577e61422e51ab08c5aaa2a88c94e1636 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -39,6 +39,27 @@ public class LevelConfigurations extends ConfigurationPart { - public NetherPortal netherPortal; - public class NetherPortal extends ConfigurationPart { - -+ public Size size; -+ public class Size extends ConfigurationPart { -+ -+ public Width width; -+ public class Width extends ConfigurationPart { -+ -+ int min; public int min() { return Math.max(this.min, 1); } -+ int max; public int max() { return Math.max(this.min, this.max); } -+ -+ } -+ -+ public Height height; -+ public class Height extends ConfigurationPart { -+ -+ int min; public int min() { return Math.max(this.min, 2); } -+ int max; public int max() { return Math.max(this.min, this.max); } -+ -+ } -+ -+ } -+ - } - - } diff --git a/patches/server/0012-Completely-remove-Mojang-Profiler.patch b/patches/server/0015-Completely-remove-Mojang-Profiler.patch similarity index 91% rename from patches/server/0012-Completely-remove-Mojang-Profiler.patch rename to patches/server/0015-Completely-remove-Mojang-Profiler.patch index fbc3e9adf..8839479a6 100644 --- a/patches/server/0012-Completely-remove-Mojang-Profiler.patch +++ b/patches/server/0015-Completely-remove-Mojang-Profiler.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Completely remove Mojang Profiler diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 11de2f237e6dd950b8ddba3d5cfe9066d09f0903..44248dc470d0882b7287debd1993cedf0f238aca 100644 +index 8e5492bbdddb199bee021d79769ed2ee051128cf..e915f2cbf83e0eed9faa30e48740617b74d4e4cd 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -113,16 +113,16 @@ import net.minecraft.util.Unit; @@ -49,19 +49,35 @@ index 11de2f237e6dd950b8ddba3d5cfe9066d09f0903..44248dc470d0882b7287debd1993cedf @Nullable private MinecraftServer.TimeProfiler debugCommandProfiler; private boolean debugCommandProfilerDelayStart; -@@ -2309,10 +2309,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +@@ -2557,6 +2560,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma -+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type()/*, minecraftserver::getProfiler*/, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig)), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma // Plazma - Completely remove profiler +- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(org.plazmamc.plazma.configurations.PlazmaConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma ++ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), /*minecraftserver::getProfiler,*/ false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), spigotConfig -> minecraftserver.plazmaConfigurations.createWorldConfig(org.plazmamc.plazma.configurations.PlazmaConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess())), executor); // Paper - Async-Anti-Xray - Pass executor // Plazma // Plazma - Completely remove profiler this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); @@ -172,8 +188,8 @@ index e7efdd572716e50ecca217898b8a368e5829f925..72c2af8638d71b92a9762dedb0efec53 this.entityTickList = new EntityTickList(); - this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); - this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); -+ this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded/*, this.getProfilerSupplier()*/); // Plazma - Completely remove profiler -+ this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded/*, this.getProfilerSupplier()*/); // Plazma - Completely remove profiler ++ this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded); //, this.getProfilerSupplier()); // Plazma - Completely remove profiler ++ this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded); //, this.getProfilerSupplier()); // Plazma - Completely remove profiler this.navigatingMobs = new ObjectOpenHashSet(); this.blockEvents = new ObjectLinkedOpenHashSet(); this.blockEventsToReschedule = new ArrayList(64); @@ -635,38 +651,8 @@ index 863343a87fe34d72f04af89d75268b477b2adc7a..00000000000000000000000000000000 - } - } -} -diff --git a/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java b/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java -deleted file mode 100644 -index 729ebd1b2433327de243d0168289e180a841f47c..0000000000000000000000000000000000000000 ---- a/src/main/java/net/minecraft/util/profiling/metrics/profiling/MetricsRecorder.java -+++ /dev/null -@@ -1,24 +0,0 @@ --package net.minecraft.util.profiling.metrics.profiling; -- --import net.minecraft.util.profiling.ProfilerFiller; -- --@Deprecated(forRemoval = true) --public interface MetricsRecorder { -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- void end(); -- -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- void cancel(); -- -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- void startTick(); -- -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- boolean isRecording(); -- -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- ProfilerFiller getProfiler(); -- -- @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Purpur -- void endTick(); --} diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index d35afa8f8648bbcbfc044323bcda1b1182d7dce4..fb5c21ba15995d00da87ee6ef9e4ab8f6678d67f 100644 +index 599094f231787db475882c38721b724a2e3bf41c..620b5011a675e456ac685d4323df233b5b8f8799 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -147,8 +147,8 @@ public abstract class Mob extends LivingEntity implements Targeting { @@ -675,8 +661,8 @@ index d35afa8f8648bbcbfc044323bcda1b1182d7dce4..fb5c21ba15995d00da87ee6ef9e4ab8f this.restrictRadius = -1.0F; - this.goalSelector = new GoalSelector(world.getProfilerSupplier()); - this.targetSelector = new GoalSelector(world.getProfilerSupplier()); -+ this.goalSelector = new GoalSelector(/*world.getProfilerSupplier()*/); // Plazma - Completely remove profiler -+ this.targetSelector = new GoalSelector(/*world.getProfilerSupplier()*/); // Plazma - Completely remove profiler ++ this.goalSelector = new GoalSelector(); //world.getProfilerSupplier()); // Plazma - Completely remove profiler ++ this.targetSelector = new GoalSelector(); //world.getProfilerSupplier()); // Plazma - Completely remove profiler this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this); // Purpur this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this); // Purpur this.jumpControl = new JumpControl(this); @@ -737,7 +723,7 @@ index 666fc85bc2079cb367b340f2605f29fe002f4d22..36c60716c6aaa446ff7123a3babafb2e // CraftBukkit start - SPIGOT-5667 make sure all types are populated and mutable Map, Object2ObjectLinkedOpenHashMap>> map1 = Maps.newHashMap(); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index e45a5282dc0ea3a35da24c7c3a0c7cda9a773f0c..1a5880ae3c3b17d49f0b083dff66e5619c08ec20 100644 +index af4eb54d99b67d059534e5e55e952aa41bb87bc7..412dd103bad498c3c93b7a3ab98f834944d514eb 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -39,7 +39,7 @@ import net.minecraft.sounds.SoundSource; @@ -758,16 +744,16 @@ index e45a5282dc0ea3a35da24c7c3a0c7cda9a773f0c..1a5880ae3c3b17d49f0b083dff66e561 public final boolean isClientSide; private final WorldBorder worldBorder; private final BiomeManager biomeManager; -@@ -259,7 +259,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -262,7 +262,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public abstract ResourceKey getTypeKey(); + //protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter // Purpur - dont break ABI -- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaLevelConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma -+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder/*, Supplier supplier*/, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaLevelConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma // Plazma - Completely remove profiler +- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaWorldConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma ++ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, /*Supplier supplier,*/ boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.function.Function plazmaWorldConfigurationCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor // Plazma //- Completely remove profiler this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - this.plazmaLevelConfiguration = plazmaLevelConfigurationCreator.apply(this.spigotConfig); // Plazma -@@ -276,7 +276,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.plazmaConfig = plazmaWorldConfigurationCreator.apply(this.spigotConfig); // Plazma +@@ -279,7 +279,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // CraftBukkit end @@ -776,7 +762,7 @@ index e45a5282dc0ea3a35da24c7c3a0c7cda9a773f0c..1a5880ae3c3b17d49f0b083dff66e561 this.levelData = worlddatamutable; this.dimensionTypeRegistration = holder; this.dimensionTypeId = (ResourceKey) holder.unwrapKey().orElseThrow(() -> { -@@ -1830,6 +1830,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1833,6 +1833,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return false; } @@ -784,7 +770,7 @@ index e45a5282dc0ea3a35da24c7c3a0c7cda9a773f0c..1a5880ae3c3b17d49f0b083dff66e561 public ProfilerFiller getProfiler() { if (true || gg.pufferfish.pufferfish.PufferfishConfig.disableMethodProfiler) return net.minecraft.util.profiling.InactiveProfiler.INSTANCE; // Pufferfish // Purpur return (ProfilerFiller) this.profiler.get(); -@@ -1838,6 +1839,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1841,6 +1842,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public Supplier getProfilerSupplier() { return this.profiler; } @@ -816,7 +802,7 @@ index 0f1025495237aebe30132ace0832aa5718d6f9bb..0226280bbdb9d63831d93f980ee117da + */ // Plazma - Completely remove profiler } 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 8d385708df97d47881929d4352f1b90286aad1a2..a25b93f98b2c525b146c979df2a95a9a749300a8 100644 +index 66656c4cf157228c9f52b33b358713ef0172f9ff..a8a360b794cec35b9f7ab137aaf35fba1d610f26 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -25,7 +25,7 @@ import net.minecraft.network.FriendlyByteBuf; @@ -828,7 +814,7 @@ index 8d385708df97d47881929d4352f1b90286aad1a2..a25b93f98b2c525b146c979df2a95a9a import net.minecraft.world.entity.Entity; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; -@@ -445,7 +445,7 @@ public class LevelChunk extends ChunkAccess { +@@ -455,7 +455,7 @@ public class LevelChunk extends ChunkAccess { } if (LightEngine.hasDifferentLightProperties(this, blockposition, iblockdata1, iblockdata)) { @@ -836,7 +822,7 @@ index 8d385708df97d47881929d4352f1b90286aad1a2..a25b93f98b2c525b146c979df2a95a9a + //ProfilerFiller gameprofilerfiller = this.level.getProfiler(); // Plazma - Completely remove profiler //gameprofilerfiller.push("updateSkyLightSources"); // Purpur - this.skyLightSources.update(this, j, i, l); + // Paper - starlight - remove skyLightSources diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java index a8af51a25b0f99c3a64d9150fdfcd6b818aa7581..b9689131a7a46b46c0b75b86f2bb163d7de74921 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java @@ -869,7 +855,7 @@ index a8af51a25b0f99c3a64d9150fdfcd6b818aa7581..b9689131a7a46b46c0b75b86f2bb163d //profiler.markForCharting(MetricCategory.PATH_FINDING); // Purpur // Set set = positions.keySet(); diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootDataManager.java b/src/main/java/net/minecraft/world/level/storage/loot/LootDataManager.java -index dd375fffa727db76fa989248b9b836960974c372..45161f960a29395538c67461ebf864e595f6737f 100644 +index 08f5239d5eea9133340ec9e1a3a7d8d5e792ced0..ad306d5d69b2bd6ac4ddbdd13dd0a34c9c4cc4f5 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootDataManager.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/LootDataManager.java @@ -19,7 +19,7 @@ import net.minecraft.resources.ResourceLocation; @@ -877,16 +863,16 @@ index dd375fffa727db76fa989248b9b836960974c372..45161f960a29395538c67461ebf864e5 import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; -import net.minecraft.util.profiling.ProfilerFiller; -+//import net.minecraft.util.profiling.ProfilerFiller; // Plazma - Completely remove profiler ++//import net.minecraft.util.profiling.ProfilerFiller; // Plazma - Completely remove profiler // Plazma - Completely remove profiler import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; - import org.slf4j.Logger; - -@@ -35,7 +35,7 @@ public class LootDataManager implements PreparableReloadListener, LootDataResolv + import org.bukkit.craftbukkit.CraftLootTable; + import org.bukkit.craftbukkit.util.CraftNamespacedKey; +@@ -36,7 +36,7 @@ public class LootDataManager implements PreparableReloadListener, LootDataResolv public LootDataManager() {} @Override - public final CompletableFuture reload(PreparableReloadListener.PreparationBarrier synchronizer, ResourceManager manager, ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler, Executor prepareExecutor, Executor applyExecutor) { -+ public final CompletableFuture reload(PreparableReloadListener.PreparationBarrier synchronizer, ResourceManager manager/*, ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler*/, Executor prepareExecutor, Executor applyExecutor) { // Plazma - Completely remove profiler ++ public final CompletableFuture reload(PreparableReloadListener.PreparationBarrier synchronizer, ResourceManager manager, /*ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler,*/ Executor prepareExecutor, Executor applyExecutor) { // Plazma - Completely remove profiler Map, Map> map = new HashMap(); CompletableFuture[] acompletablefuture = (CompletableFuture[]) LootDataType.values().map((lootdatatype) -> { return LootDataManager.scheduleElementParse(lootdatatype, manager, prepareExecutor, map); diff --git a/patches/server/0016-Add-option-to-change-nether-portal-size.patch b/patches/server/0016-Add-option-to-change-nether-portal-size.patch new file mode 100644 index 000000000..584c1589f --- /dev/null +++ b/patches/server/0016-Add-option-to-change-nether-portal-size.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sun, 5 Nov 2023 11:27:51 +0900 +Subject: [PATCH] Add option to change nether portal size + + +diff --git a/src/main/java/net/minecraft/world/level/portal/PortalShape.java b/src/main/java/net/minecraft/world/level/portal/PortalShape.java +index e7554ec800f321e4e34c926c53f2375a8c3aa979..fc3c0ea41563995b1b115271cda4e9ca76245c4e 100644 +--- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java ++++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java +@@ -100,7 +100,7 @@ public class PortalShape { + private int calculateWidth() { + int i = this.getDistanceUntilEdgeAboveFrame(this.bottomLeft, this.rightDir); + +- return i >= 2 && i <= 21 ? i : 0; ++ return i >= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.width.min() && i <= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.width.max() ? i : 0; // Plazma - Configurable nether portal size + } + + private int getDistanceUntilEdgeAboveFrame(BlockPos pos, Direction direction) { +@@ -133,7 +133,7 @@ public class PortalShape { + BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); + int i = this.getDistanceUntilTop(blockposition_mutableblockposition); + +- return i >= 3 && i <= 21 && this.hasTopFrame(blockposition_mutableblockposition, i) ? i : 0; ++ return i >= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.height.min() && i <= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.height.max() && this.hasTopFrame(blockposition_mutableblockposition, i) ? i : 0; // Plazma - Configurable nether portal size + } + + private boolean hasTopFrame(BlockPos.MutableBlockPos pos, int height) { +@@ -187,7 +187,7 @@ public class PortalShape { + } + + public boolean isValid() { +- return this.bottomLeft != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21; ++ return this.bottomLeft != null && this.width >= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.width.min() && this.width <= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.width.max() && this.height >= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.height.min() && this.height <= this.level.getMinecraftWorld().plazmaConfig().structure.netherPortal.height.max(); // Plazma - Configurable nether portal size + } + + // CraftBukkit start - return boolean +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index a372b5be3b1da5868d3766a8ba58997a48118581..d79410cc8b6054e5d3297b3e768fb232f97062e4 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -42,6 +42,21 @@ public class WorldConfigurations extends ConfigurationPart { + public NetherPortal netherPortal; + public class NetherPortal extends ConfigurationPart { + ++ public Width width; ++ public class Width extends ConfigurationPart { ++ ++ int min = 2; public int min() { return Math.max(this.min, 1); } ++ int max = 21; public int max() { return Math.max(this.min, this.max); } ++ ++ } ++ ++ public Height height; ++ public class Height extends ConfigurationPart { ++ ++ int min = 3; public int min() { return Math.max(this.min, 2); } ++ int max = 21; public int max() { return Math.max(this.min, this.max); } ++ ++ } + + } + diff --git a/patches/server/0015-Reduce-create-random-instance.patch b/patches/server/0017-Reduce-create-random-instance.patch similarity index 62% rename from patches/server/0015-Reduce-create-random-instance.patch rename to patches/server/0017-Reduce-create-random-instance.patch index 3b06b07a5..8625c4376 100644 --- a/patches/server/0015-Reduce-create-random-instance.patch +++ b/patches/server/0017-Reduce-create-random-instance.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Reduce create random instance diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 44248dc470d0882b7287debd1993cedf0f238aca..ee571f465ca1e83e760a4d57b3d11accb53c6cfe 100644 +index 6ca87960654becdc7fd7d9b8465a140c0db2b8b9..cda99102949ae9d722c347e0dd610dfff625b5b8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -228,7 +228,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 2147483647L ? Integer.MAX_VALUE : (int) l; int j1 = this.getCoprime(i1); - int k1 = RandomSource.create().nextInt(i1); -+ int k1 = (worldserver.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? worldserver.getRandom() : RandomSource.create()).nextInt(i1); // Plazma - Reduce create random instance ++ int k1 = (worldserver.plazmaConfig().misc.reduceRandom ? worldserver.getRandom() : RandomSource.create()).nextInt(i1); // Plazma - Reduce create random instance for (int l1 = 0; l1 < i1; ++l1) { int i2 = (k1 + j1 * l1) % i1; -@@ -485,7 +485,7 @@ public class ServerPlayer extends Player { +@@ -486,7 +486,7 @@ public class ServerPlayer extends Player { long l = k * k; int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; int j1 = this.getCoprime(i1); - int k1 = RandomSource.create().nextInt(i1); -+ int k1 = (world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create()).nextInt(i1); // Plazma - Reduce create random instance ++ int k1 = (world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create()).nextInt(i1); // Plazma - Reduce create random instance for (int l1 = 0; l1 < i1; ++l1) { int i2 = (k1 + j1 * l1) % i1; diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index d38685f82d2e6c4e71179bf3a85a8b183aa6c44b..1265e6a521222be0c957065f5b788d68cb3d863f 100644 +index dd707019fb9b2c46d706311862fea91b84793ff9..05ef30ecdb68d1d254246431e7d5cecf9a38427e 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -70,7 +70,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -61,12 +61,12 @@ index d38685f82d2e6c4e71179bf3a85a8b183aa6c44b..1265e6a521222be0c957065f5b788d68 this.server = server; this.connection = connection; - this.challenge = Ints.toByteArray(RandomSource.create().nextInt()); -+ this.challenge = Ints.toByteArray((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? server.getRandom() : RandomSource.create()).nextInt()); // Plazma - Reduce create random instance ++ this.challenge = Ints.toByteArray((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? server.random() : RandomSource.create()).nextInt()); // Plazma - Reduce create random instance } @Override diff --git a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java -index 1ef089dbf83de35d875c00efdf468c397be56978..7f4c0827d2269baa032dac4798fe6c2a740ba7fa 100644 +index 1ef089dbf83de35d875c00efdf468c397be56978..832c3fa9f6f6706c48d5744e15d3c748edafe8a4 100644 --- a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java +++ b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java @@ -349,7 +349,7 @@ public class QueryThreadGs4 extends GenericThread { @@ -74,25 +74,12 @@ index 1ef089dbf83de35d875c00efdf468c397be56978..7f4c0827d2269baa032dac4798fe6c2a this.identBytes[3] = bs[6]; this.ident = new String(this.identBytes, StandardCharsets.UTF_8); - this.challenge = RandomSource.create().nextInt(16777216); -+ this.challenge = (org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create()).nextInt(16777216); // Plazma - Reduce create random instance ++ this.challenge = (org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create()).nextInt(16777216); // Plazma - Reduce create random instance this.challengeBytes = String.format(Locale.ROOT, "\t%s%d\u0000", this.ident, this.challenge).getBytes(StandardCharsets.UTF_8); } -diff --git a/src/main/java/net/minecraft/util/datafix/fixes/EntityZombieVillagerTypeFix.java b/src/main/java/net/minecraft/util/datafix/fixes/EntityZombieVillagerTypeFix.java -index 8311073e44ca8a2c8ac6f6864a875d6c90338664..8e488389b41c63809993262183204b77f73c0e55 100644 ---- a/src/main/java/net/minecraft/util/datafix/fixes/EntityZombieVillagerTypeFix.java -+++ b/src/main/java/net/minecraft/util/datafix/fixes/EntityZombieVillagerTypeFix.java -@@ -8,7 +8,7 @@ import net.minecraft.util.RandomSource; - - public class EntityZombieVillagerTypeFix extends NamedEntityFix { - private static final int PROFESSION_MAX = 6; -- private static final RandomSource RANDOM = RandomSource.create(); -+ private static final RandomSource RANDOM = org.plazmamc.plazma.PlazmaOptions.createNewRandom() ? RandomSource.create() : net.minecraft.server.MinecraftServer.getServer().getRandom(); // Plazma - Reduce create random source - - public EntityZombieVillagerTypeFix(Schema outputSchema, boolean changesType) { - super(outputSchema, changesType, "EntityZombieVillagerTypeFix", References.ENTITY, "Zombie"); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java -index fe3ab3d388f0481fb0db06b7f730f868dbf8e8a5..265d8479b5c02994dba4288060b842789ebc7179 100644 +index fe3ab3d388f0481fb0db06b7f730f868dbf8e8a5..57d4eec19146f2ec36c8f99a4c77f2a20aa7cd09 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java @@ -15,7 +15,7 @@ import net.minecraft.util.RandomSource; @@ -100,12 +87,12 @@ index fe3ab3d388f0481fb0db06b7f730f868dbf8e8a5..265d8479b5c02994dba4288060b84278 public class ShufflingList implements Iterable { public final List> entries; // Paper - public - private final RandomSource random = RandomSource.create(); -+ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create(); // Plazma ++ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma private final boolean isUnsafe; // Paper public ShufflingList() { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -index 7094701d213c73ba47ace806962244c10fdf4dda..288ae299240c9626e576a7ae1c45c53d83f7f097 100644 +index 7094701d213c73ba47ace806962244c10fdf4dda..590c26307374edd65a2e22de18d12f34addcef64 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java @@ -8,7 +8,7 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType; @@ -113,12 +100,12 @@ index 7094701d213c73ba47ace806962244c10fdf4dda..288ae299240c9626e576a7ae1c45c53d public abstract class Sensor { - private static final RandomSource RANDOM = RandomSource.createThreadSafe(); -+ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance && org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.suppressThreadSafeRandom ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.createThreadSafe(); // Plazma - Reduce create random instance ++ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom && org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.ignoreThreadSafeRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.createThreadSafe(); // Plazma - Reduce create random instance private static final int DEFAULT_SCAN_RATE = 20; protected static final int TARGETING_RANGE = 16; private static final TargetingConditions TARGET_CONDITIONS = TargetingConditions.forNonCombat().range(16.0D); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java -index ece82743df21f0b776382821ad75dee96d0a0748..c25affe40eea32e1964aa4c62fdd27faa37baf28 100644 +index ece82743df21f0b776382821ad75dee96d0a0748..44db438185d1ffb1adea09ba5f1cf4515a113700 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java @@ -32,7 +32,7 @@ public class AngerManagement { @@ -126,12 +113,12 @@ index ece82743df21f0b776382821ad75dee96d0a0748..c25affe40eea32e1964aa4c62fdd27fa protected static final int MAX_ANGER = 150; private static final int DEFAULT_ANGER_DECREASE = 1; - private int conversionDelay = Mth.randomBetweenInclusive(RandomSource.create(), 0, 2); -+ private int conversionDelay = Mth.randomBetweenInclusive((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create()), 0, 2); // Plazma - Reduce create random instance ++ private int conversionDelay = Mth.randomBetweenInclusive((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create()), 0, 2); // Plazma - Reduce create random instance int highestAnger; private static final Codec> SUSPECT_ANGER_PAIR = RecordCodecBuilder.create((instance) -> { return instance.group(UUIDUtil.CODEC.fieldOf("uuid").forGetter(Pair::getFirst), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("anger").forGetter(Pair::getSecond)).apply(instance, Pair::of); diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index a5443f92786427c42092aec8350e7ab37704db7a..b1a44e460175b974e8830030ce61e523533bef8c 100644 +index a5443f92786427c42092aec8350e7ab37704db7a..0383c9e75a12c5832cf69daf14b8037365c43cfb 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -32,7 +32,7 @@ public class WanderingTraderSpawner implements CustomSpawner { @@ -139,12 +126,12 @@ index a5443f92786427c42092aec8350e7ab37704db7a..b1a44e460175b974e8830030ce61e523 private static final int SPAWN_ONE_IN_X_CHANCE = 10; private static final int NUMBER_OF_SPAWN_ATTEMPTS = 10; - private final RandomSource random = RandomSource.create(); -+ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create(); // Plazma - reduce create random instace ++ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - reduce create random instace private final ServerLevelData serverLevelData; private int tickDelay; private int spawnDelay; diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index a9eaa079a43bc8a5e81deaf6df5ce2f9c53cb319..f1b0b8fd1042f2ce8a514000d95df5123223cc27 100644 +index a2093158e57d5f43c4afa66386481b82b3c4c3c4..2b75115caf82b9c4ccdd813b98af569e80ac2629 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java @@ -86,7 +86,7 @@ public class FishingHook extends Projectile { @@ -152,12 +139,12 @@ index a9eaa079a43bc8a5e81deaf6df5ce2f9c53cb319..f1b0b8fd1042f2ce8a514000d95df512 private FishingHook(EntityType type, Level world, int luckOfTheSeaLevel, int lureLevel) { super(type, world); - this.syncronizedRandom = RandomSource.create(); -+ this.syncronizedRandom = world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instance ++ this.syncronizedRandom = world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instance this.openWater = true; this.currentState = FishingHook.FishHookState.FLYING; this.noCulling = true; diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java -index eaa2943b667967f93f28d9d794d702fdaeb670ec..75ba586277ece1aa56186679d3a8ebf0b3f7a0cb 100644 +index eaa2943b667967f93f28d9d794d702fdaeb670ec..689a4ee7b3f136b14e8e56709cac7d2da89c8efd 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raid.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java @@ -109,7 +109,7 @@ public class Raid { @@ -165,7 +152,7 @@ index eaa2943b667967f93f28d9d794d702fdaeb670ec..75ba586277ece1aa56186679d3a8ebf0 public Raid(int id, ServerLevel world, BlockPos pos) { this.raidEvent = new ServerBossEvent(Raid.RAID_NAME_COMPONENT, BossEvent.BossBarColor.RED, BossEvent.BossBarOverlay.NOTCHED_10); - this.random = RandomSource.create(); -+ this.random = world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace ++ this.random = world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace this.waveSpawnPos = Optional.empty(); this.id = id; this.level = world; @@ -174,12 +161,12 @@ index eaa2943b667967f93f28d9d794d702fdaeb670ec..75ba586277ece1aa56186679d3a8ebf0 public Raid(ServerLevel world, CompoundTag nbt) { this.raidEvent = new ServerBossEvent(Raid.RAID_NAME_COMPONENT, BossEvent.BossBarColor.RED, BossEvent.BossBarOverlay.NOTCHED_10); - this.random = RandomSource.create(); -+ this.random = world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace ++ this.random = world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace this.waveSpawnPos = Optional.empty(); this.level = world; this.id = nbt.getInt("Id"); diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -index d604b7ec46f08993647979ed220a84842e3fe325..f2a3049252a37ca6d6d5cb1cc51d512c7ebf5679 100644 +index d604b7ec46f08993647979ed220a84842e3fe325..b0b6580a08b15dbfc542ee1fd9e5b6737f8af004 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java @@ -97,7 +97,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { @@ -187,12 +174,12 @@ index d604b7ec46f08993647979ed220a84842e3fe325..f2a3049252a37ca6d6d5cb1cc51d512c // Purpur end }; - this.random = RandomSource.create(); -+ this.random = playerInventory.player.level().plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? playerInventory.player.level().random : RandomSource.create(); // Plazma - Reduce create random instace ++ this.random = playerInventory.player.level().plazmaConfig().misc.reduceRandom ? playerInventory.player.level().random : RandomSource.create(); // Plazma - Reduce create random instace this.enchantmentSeed = DataSlot.standalone(); this.costs = new int[3]; this.enchantClue = new int[]{-1, -1, -1}; diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index ef9b1687dd2dfda5398523140aecc678b4690642..66a1db10249995144490dac292e09fd0aa30f168 100644 +index ef9b1687dd2dfda5398523140aecc678b4690642..130a41387a2546b31019ad918849b2c283ed09d9 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -82,7 +82,7 @@ public class Explosion { @@ -200,12 +187,12 @@ index ef9b1687dd2dfda5398523140aecc678b4690642..66a1db10249995144490dac292e09fd0 public Explosion(Level world, @Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Explosion.BlockInteraction destructionType) { - this.random = RandomSource.create(); -+ this.random = world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace ++ this.random = world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create(); // Plazma - Reduce create random instace this.toBlow = new ObjectArrayList(); this.hitPlayers = Maps.newHashMap(); this.level = world; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1a5880ae3c3b17d49f0b083dff66e5619c08ec20..e175cde654b36d8ffc98a36ef099d22e9f1d15e9 100644 +index 412dd103bad498c3c93b7a3ab98f834944d514eb..7a7f417c2a0af73a35297274b8ddd6ac581901ae 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -124,16 +124,16 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -219,16 +206,16 @@ index 1a5880ae3c3b17d49f0b083dff66e5619c08ec20..e175cde654b36d8ffc98a36ef099d22e protected float oThunderLevel; public float thunderLevel; public final RandomSource random = RandomSource.create(); -+ protected int randValue = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? random.nextInt() : RandomSource.create().nextInt(); // Plazma - Reduce create random instace ++ protected int randValue = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? random.nextInt() : RandomSource.create().nextInt(); // Plazma - Reduce create random instace /** @deprecated */ @Deprecated - private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); -+ private final RandomSource threadSafeRandom = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.suppressThreadSafeRandom ? random : RandomSource.createThreadSafe(); // Plazma - Reduce create random instace ++ private final RandomSource threadSafeRandom = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.ignoreThreadSafeRandom ? random : RandomSource.createThreadSafe(); // Plazma - Reduce create random instace private final ResourceKey dimensionTypeId; private final Holder dimensionTypeRegistration; public final WritableLevelData levelData; diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java -index b7370e64fd0d50e8725d7d5afc30af2e8bc8455d..b8d2c91a343478d89a5242254f3379dfa2556348 100644 +index b7370e64fd0d50e8725d7d5afc30af2e8bc8455d..9ec2a60c8240f7a3e4cd7944d070156dbf55ac2c 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java @@ -22,7 +22,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable @@ -236,12 +223,12 @@ index b7370e64fd0d50e8725d7d5afc30af2e8bc8455d..b8d2c91a343478d89a5242254f3379df public float oRot; public float tRot; - private static final RandomSource RANDOM = RandomSource.create(); -+ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create(); // Plazma - Reduce create random instace ++ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - Reduce create random instace private Component name; private int lapis = 0; // Purpur diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index 7291e4056b8e46ab59b71818388ac55fbb12993f..22faea52bc54cdcb52ff18a9d5a8c1bd1a64fa73 100644 +index 7291e4056b8e46ab59b71818388ac55fbb12993f..b847f59c5d3e0d7ccb22eaa5d9068082db5ba9a4 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -368,7 +368,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -249,12 +236,12 @@ index 7291e4056b8e46ab59b71818388ac55fbb12993f..22faea52bc54cdcb52ff18a9d5a8c1bd private static void spawnGatewayPortal(ServerLevel world, BlockPos pos, EndGatewayConfiguration config) { - Feature.END_GATEWAY.place(config, world, world.getChunkSource().getGenerator(), RandomSource.create(), pos); -+ Feature.END_GATEWAY.place(config, world, world.getChunkSource().getGenerator(), (world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create()), pos); // Plazma - Reduce create random instance ++ Feature.END_GATEWAY.place(config, world, world.getChunkSource().getGenerator(), (world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create()), pos); // Plazma - Reduce create random instance } @Override diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java -index f8cd23fb6ea7909b8f30bd21d3f2c7bcc483ef21..c85340232624529d4685bf34035bb62d294695c9 100644 +index f8cd23fb6ea7909b8f30bd21d3f2c7bcc483ef21..3a4044271e23faf4c5271237aba700103f6df830 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java @@ -221,7 +221,7 @@ public class ChunkGeneratorStructureState { @@ -262,12 +249,12 @@ index f8cd23fb6ea7909b8f30bd21d3f2c7bcc483ef21..c85340232624529d4685bf34035bb62d int k = placement.spread(); HolderSet holderset = placement.preferredBiomes(); - RandomSource randomsource = RandomSource.create(); -+ RandomSource randomsource = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceCreateRandomInstance ? net.minecraft.server.MinecraftServer.getServer().getRandom() : RandomSource.create(); // Plazma - Reduce create random instace ++ RandomSource randomsource = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - Reduce create random instace // Paper start if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { diff --git a/src/main/java/net/minecraft/world/level/dimension/end/DragonRespawnAnimation.java b/src/main/java/net/minecraft/world/level/dimension/end/DragonRespawnAnimation.java -index 18fce94f0d4b9d28e3afec61c7578f672973a71f..2dfb801ec15a372bcb997942969fec64aea9e49e 100644 +index 18fce94f0d4b9d28e3afec61c7578f672973a71f..c98d65c146213bdf530916b8ec371e0b0b8f23e7 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/DragonRespawnAnimation.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/DragonRespawnAnimation.java @@ -62,7 +62,7 @@ public enum DragonRespawnAnimation { @@ -275,12 +262,12 @@ index 18fce94f0d4b9d28e3afec61c7578f672973a71f..2dfb801ec15a372bcb997942969fec64 world.explode((Entity)null, (double)((float)endSpike.getCenterX() + 0.5F), (double)endSpike.getHeight(), (double)((float)endSpike.getCenterZ() + 0.5F), 5.0F, Level.ExplosionInteraction.BLOCK); SpikeConfiguration spikeConfiguration = new SpikeConfiguration(true, ImmutableList.of(endSpike), new BlockPos(0, 128, 0)); - Feature.END_SPIKE.place(spikeConfiguration, world, world.getChunkSource().getGenerator(), RandomSource.create(), new BlockPos(endSpike.getCenterX(), 45, endSpike.getCenterZ())); -+ Feature.END_SPIKE.place(spikeConfiguration, world, world.getChunkSource().getGenerator(), (world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create()), new BlockPos(endSpike.getCenterX(), 45, endSpike.getCenterZ())); // Plazma - Reduce create random instance ++ Feature.END_SPIKE.place(spikeConfiguration, world, world.getChunkSource().getGenerator(), (world.plazmaConfig().misc.reduceRandom ? world.getRandom() : RandomSource.create()), new BlockPos(endSpike.getCenterX(), 45, endSpike.getCenterZ())); // Plazma - Reduce create random instance } } else if (bl) { fight.setRespawnStage(SUMMONING_DRAGON); diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index c1ff2e15bc5da1a642872ac0fdcdc457e8abb063..67b4a65980059b0b2d4929c619c400c48e201e18 100644 +index c1ff2e15bc5da1a642872ac0fdcdc457e8abb063..c8b29f79725bb9ccec5b48476e242609a452402c 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java @@ -472,7 +472,7 @@ public class EndDragonFight { @@ -288,7 +275,7 @@ index c1ff2e15bc5da1a642872ac0fdcdc457e8abb063..67b4a65980059b0b2d4929c619c400c4 return iregistry.getHolder(EndFeatures.END_GATEWAY_DELAYED); }).ifPresent((holder_c) -> { - ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos); -+ ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), pos); // Plazma - Reduce create random instace ++ ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaConfig().misc.reduceRandom ? this.level.getRandom() : RandomSource.create()), pos); // Plazma - Reduce create random instace }); } @@ -297,36 +284,15 @@ index c1ff2e15bc5da1a642872ac0fdcdc457e8abb063..67b4a65980059b0b2d4929c619c400c4 } // Paper end - if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation)) { -+ if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), this.portalLocation)) { // Plazma - Reduce create random instace ++ if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaConfig().misc.reduceRandom ? this.level.getRandom() : RandomSource.create()), this.portalLocation)) { // Plazma - Reduce create random instace int i = Mth.positiveCeilDiv(4, 16); this.level.getChunkSource().chunkMap.waitForLightBeforeSending(new ChunkPos(this.portalLocation), i); -diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java -index d38cabc9eeb45dd863e5f87b7df3b6327ea6a4a2..d4bcdbc6ea420bdb05c0a8859d368213d87dba67 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java -@@ -77,6 +77,6 @@ public class WorldOptions { - } - - public static long randomSeed() { -- return RandomSource.create().nextLong(); -+ return (org.plazmamc.plazma.PlazmaOptions.createNewRandom() ? RandomSource.create() : net.minecraft.server.MinecraftServer.getServer().getRandom()).nextLong(); // Plazma - Reduce create random instance - } - } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java -index 68c5af9b67a2834ee6e2f80ceefa19c3a982b8ed..aabbf9ae1b772c9101e6f36236e5d34a5620a4d3 100644 +index c13cdbaf7abdf120a3969f8e887b4c3b78989c9c..5bb9bfbad85a115bf32955c2abc89edc2e7a6e43 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java -@@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.entity; - - import com.google.common.base.Preconditions; - import java.util.Random; -+ -+import net.minecraft.util.RandomSource; - import net.minecraft.world.entity.projectile.FireworkRocketEntity; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; -@@ -14,11 +16,12 @@ import org.bukkit.inventory.meta.FireworkMeta; +@@ -14,11 +14,12 @@ import org.bukkit.inventory.meta.FireworkMeta; public class CraftFirework extends CraftProjectile implements Firework { @@ -336,59 +302,32 @@ index 68c5af9b67a2834ee6e2f80ceefa19c3a982b8ed..aabbf9ae1b772c9101e6f36236e5d34a public CraftFirework(CraftServer server, FireworkRocketEntity entity) { super(server, entity); -+ this.random = this.getHandle().level().plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.getHandle().level().getRandom() : RandomSource.create(); // Plazma - Reduce create random instance ++ this.random = this.getHandle().level().plazmaConfig().misc.reduceRandom ? this.getHandle().level().getRandom() : net.minecraft.util.RandomSource.create(); // Plazma - Reduce create random instance // Paper Start - Expose firework item directly // ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM); -diff --git a/src/main/java/org/plazmamc/plazma/PlazmaOptions.java b/src/main/java/org/plazmamc/plazma/PlazmaOptions.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4421110e20a006c3773e922eb0facc88174ffb43 ---- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/PlazmaOptions.java -@@ -0,0 +1,10 @@ -+package org.plazmamc.plazma; -+ -+public class PlazmaOptions { -+ -+ static final boolean DONT_CREATE_NEW_RANDOM_INSTANCE = Boolean.getBoolean("Plazma.doNotCreateRandomInstance"); -+ public static boolean createNewRandom() { -+ return !DONT_CREATE_NEW_RANDOM_INSTANCE; -+ } -+ -+} diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 00c95194788d56f539d1c75e9a1ce48e950c096c..9e26e598d7c381368de422ab0c3cc7936e3bbb6d 100644 +index c85f1a01c951f85c2347eba18a896e87c4c8b368..d88208cb454d1042440803c817d99c5dcb775330 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -18,7 +18,7 @@ public class GlobalConfiguration extends ConfigurationPart { - static void set(@NotNull GlobalConfiguration instance, boolean test) { - GlobalConfiguration.instance = instance; - if (test) { -- -+ instance.misc.reduceCreateRandomInstance = false; - } - } +@@ -40,6 +40,8 @@ public class GlobalConfiguration extends ConfigurationPart { + public Miscellaneous misc; + public class Miscellaneous extends ConfigurationPart { -@@ -34,6 +34,9 @@ public class GlobalConfiguration extends ConfigurationPart { ++ public boolean reduceRandom = OPTIMIZE; ++ public boolean ignoreThreadSafeRandom = false; - } - -+ public boolean reduceCreateRandomInstance = DO_OPTIMIZE; -+ public boolean suppressThreadSafeRandom = DO_OPTIMIZE; -+ } - public Player player; -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 36c367c577e61422e51ab08c5aaa2a88c94e1636..146af5bb54da67c134485dc67e8d9a569889434a 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -26,6 +26,8 @@ public class LevelConfigurations extends ConfigurationPart { - public Misc misc; - public class Misc extends ConfigurationPart { +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index d79410cc8b6054e5d3297b3e768fb232f97062e4..e9850b634c4e9bbebea6534690632b067b69b0b6 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -22,6 +22,7 @@ public class WorldConfigurations extends ConfigurationPart { + public Miscellaneous misc; + public class Miscellaneous extends ConfigurationPart { + ++ public boolean reduceRandom = OPTIMIZE; -+ public boolean reduceCreateRandomInstance = DO_OPTIMIZE; -+ } - public Entity entity; diff --git a/patches/server/0016-Apply-various-optimizations.patch b/patches/server/0018-Apply-various-optimizations.patch similarity index 85% rename from patches/server/0016-Apply-various-optimizations.patch rename to patches/server/0018-Apply-various-optimizations.patch index d8baa0557..22880936e 100644 --- a/patches/server/0016-Apply-various-optimizations.patch +++ b/patches/server/0018-Apply-various-optimizations.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Apply various optimizations Akarin - Swaps the predicate order of collision diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1ca91631b03c9690b4f661ecfb4d500d23cb47ec..4461dc1b76cc2939130680f8039b69af902aa050 100644 +index a13e6d41584a55e3e17d55d568b23f48082750ef..23eb620351ee08cac97e0408f1fc6cee33f036d0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2105,8 +2105,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2139,8 +2139,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public void playerTouch(Player player) {} public void push(Entity entity) { @@ -21,7 +21,7 @@ index 1ca91631b03c9690b4f661ecfb4d500d23cb47ec..4461dc1b76cc2939130680f8039b69af if (this.level.paperConfig().collisions.onlyPlayersCollide && !(entity instanceof ServerPlayer || this instanceof ServerPlayer)) return; // Paper double d0 = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); -@@ -2135,7 +2136,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2169,7 +2170,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } diff --git a/patches/server/0017-Avoid-double-I-O-operation-on-load-player-file.patch b/patches/server/0019-Avoid-double-I-O-operation-on-load-player-file.patch similarity index 100% rename from patches/server/0017-Avoid-double-I-O-operation-on-load-player-file.patch rename to patches/server/0019-Avoid-double-I-O-operation-on-load-player-file.patch diff --git a/patches/server/0020-Add-option-to-disable-moved-to-quickly-check-for-spe.patch b/patches/server/0020-Add-option-to-disable-moved-to-quickly-check-for-spe.patch deleted file mode 100644 index be03001c5..000000000 --- a/patches/server/0020-Add-option-to-disable-moved-to-quickly-check-for-spe.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Wed, 27 Sep 2023 22:21:47 +0900 -Subject: [PATCH] Add option to disable moved to quickly check for specific - players - - -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e001787e40cc0a843e65b36582e9d6593d0fff0e..1af44c18724b2d2dc1d910f5af49254eb845feaf 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1435,6 +1435,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - if (!this.player.isChangingDimension() && (!this.player.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) { - float f2 = this.player.isFallFlying() ? 300.0F : 100.0F; - -+ if (this.player.getBukkitEntity().hasPermission("plazma.bypass-moved-to-quickly-check") || !this.player.level().plazmaLevelConfiguration().entity.player.checkSpectatorMovecToQuickly && this.player.isSpectator()) return; // Plazma - if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { - // CraftBukkit end - // Paper start - Add fail move event -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 0a23900b18ec46ce2a7d47160dff013c7c8a8533..414baade911fab3450430af9378feedc419868f3 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -33,6 +33,13 @@ public class LevelConfigurations extends ConfigurationPart { - public Entity entity; - public class Entity extends ConfigurationPart { - -+ public Player player; -+ public class Player extends ConfigurationPart { -+ -+ public boolean checkSpectatorMovecToQuickly = !DO_OPTIMIZE; -+ -+ } -+ - public Phantom phantom; - public class Phantom extends ConfigurationPart { - diff --git a/patches/server/0018-Don-t-refresh-LootTable-for-non-player-interaction.patch b/patches/server/0020-Don-t-refresh-LootTable-for-non-player-interaction.patch similarity index 60% rename from patches/server/0018-Don-t-refresh-LootTable-for-non-player-interaction.patch rename to patches/server/0020-Don-t-refresh-LootTable-for-non-player-interaction.patch index 140b9da69..330fa0338 100644 --- a/patches/server/0018-Don-t-refresh-LootTable-for-non-player-interaction.patch +++ b/patches/server/0020-Don-t-refresh-LootTable-for-non-player-interaction.patch @@ -1,30 +1,30 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Wed, 27 Sep 2023 22:15:39 +0900 +Date: Sun, 5 Nov 2023 12:03:06 +0900 Subject: [PATCH] Don't refresh LootTable for non player interaction diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 081691f9710ff1115e4308f79ed49fbc38941193..79a27755534384ab94e79e422c0a5e9ccecacd8c 100644 +index 02364a148b347e3669275553004391e31d77c0b5..cd2d3707c8e4a313ad15958b2f926be6e05bcd4d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -70,6 +70,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc } public void unpackLootTable(@Nullable Player player) { -+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.dontRefreshLootTableForNonPlayerInteraction && player == null) return; // Plazma - if (this.lootableData.shouldReplenish(player) && this.level.getServer() != null) { // Paper ++ if (player == null && org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.refreshLootTableForNonPlayerInteraction) return; // Plazma + if (this.level != null && this.lootableData.shouldReplenish(player) && this.level.getServer() != null) { // Paper - don't unpack loot table if not in world LootTable lootTable = this.level.getServer().getLootData().getLootTable(this.lootTable); if (player instanceof ServerPlayer) { diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 9e26e598d7c381368de422ab0c3cc7936e3bbb6d..5a62bffe495002b3bbf5fd995df135c5d174458a 100644 +index d88208cb454d1042440803c817d99c5dcb775330..c687f448761a591900ae5ebad9c8dfca572e9b31 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -36,6 +36,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -42,6 +42,7 @@ public class GlobalConfiguration extends ConfigurationPart { - public boolean reduceCreateRandomInstance = DO_OPTIMIZE; - public boolean suppressThreadSafeRandom = DO_OPTIMIZE; -+ public boolean dontRefreshLootTableForNonPlayerInteraction = DO_OPTIMIZE; + public boolean reduceRandom = OPTIMIZE; + public boolean ignoreThreadSafeRandom = false; ++ public boolean refreshLootTableForNonPlayerInteraction = !OPTIMIZE; } diff --git a/patches/server/0019-Don-t-load-chunks-to-spawn-phantom.patch b/patches/server/0021-Don-t-load-chunks-to-spawn-phantom.patch similarity index 51% rename from patches/server/0019-Don-t-load-chunks-to-spawn-phantom.patch rename to patches/server/0021-Don-t-load-chunks-to-spawn-phantom.patch index 13dbf61d4..5e30d04cc 100644 --- a/patches/server/0019-Don-t-load-chunks-to-spawn-phantom.patch +++ b/patches/server/0021-Don-t-load-chunks-to-spawn-phantom.patch @@ -1,36 +1,30 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Wed, 27 Sep 2023 22:17:11 +0900 +Date: Sun, 5 Nov 2023 12:07:06 +0900 Subject: [PATCH] Don't load chunks to spawn phantom diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index f74c5eda91a3d521763ec7bc33f23e0c62458cc2..e7a9683fe6bd72e9e7644770953506195567e03b 100644 +index f74c5eda91a3d521763ec7bc33f23e0c62458cc2..49a8a81c586908278d1e3cbd51dea307540f28ec 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -71,6 +71,7 @@ public class PhantomSpawner implements CustomSpawner { if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21)); -+ if (world.plazmaLevelConfiguration().entity.phantom.dontLoadChunksToSpawn && world.hasChunkAt(blockposition1)) continue; // Plazma ++ if (!world.plazmaConfig().entity.phantom.loadChunksToSpawn && !world.hasChunkAt(blockposition1)) continue; // Plazma BlockState iblockdata = world.getBlockState(blockposition1); FluidState fluid = world.getFluidState(blockposition1); -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 146af5bb54da67c134485dc67e8d9a569889434a..0a23900b18ec46ce2a7d47160dff013c7c8a8533 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -33,6 +33,13 @@ public class LevelConfigurations extends ConfigurationPart { - public Entity entity; - public class Entity extends ConfigurationPart { +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index e9850b634c4e9bbebea6534690632b067b69b0b6..036c0b12553ae203e8c73d44dc2e3d625b812af5 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -32,6 +32,7 @@ public class WorldConfigurations extends ConfigurationPart { + public Phantom phantom; + public class Phantom extends ConfigurationPart { -+ public Phantom phantom; -+ public class Phantom extends ConfigurationPart { -+ -+ public boolean dontLoadChunksToSpawn = DO_OPTIMIZE; -+ -+ } -+ - } ++ public boolean loadChunksToSpawn = !OPTIMIZE; + + } - public Structure structure; diff --git a/patches/server/0022-Add-option-to-disable-moved-to-quickly-check-for-spe.patch b/patches/server/0022-Add-option-to-disable-moved-to-quickly-check-for-spe.patch new file mode 100644 index 000000000..ba984356e --- /dev/null +++ b/patches/server/0022-Add-option-to-disable-moved-to-quickly-check-for-spe.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sun, 5 Nov 2023 12:16:14 +0900 +Subject: [PATCH] Add option to disable moved to quickly check for specific + players + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index a7e82f95db5c6c054175192f019072006a3ef31f..21def42f813f00c9fbc9c920b9ba61efc5928ef6 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -1439,6 +1439,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + if (!this.player.isChangingDimension() && (!this.player.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) { + float f2 = this.player.isFallFlying() ? 300.0F : 100.0F; + ++ if (!this.player.getBukkitEntity().hasPermission("plazma.bypass-moved-to-quickly-check") || !(org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.checkSpectatorMovedToQuickly && this.player.isSpectator())) // Plazma + if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { + // CraftBukkit end + // Paper start - Add fail move event +diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +index c687f448761a591900ae5ebad9c8dfca572e9b31..f3cf7634a5fd470e7fb295ae1f88e14f0c4a0d1d 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +@@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { + public class Player extends ConfigurationPart { + + public boolean allowAnyUsername = false; ++ public boolean checkSpectatorMovedToQuickly = !OPTIMIZE; + + } + diff --git a/patches/server/0023-Implement-No-Chat-Reports.patch b/patches/server/0023-Implement-No-Chat-Reports.patch index 68627eb91..23b80448c 100644 --- a/patches/server/0023-Implement-No-Chat-Reports.patch +++ b/patches/server/0023-Implement-No-Chat-Reports.patch @@ -3,6 +3,7 @@ From: AlphaKR93 Date: Thu, 28 Sep 2023 11:47:50 +0900 Subject: [PATCH] Implement No Chat Reports +Implemented: 62fbdef42dfbfec551d8324b7084c4ccf248bab7 diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java index 40f51062624161892c780ddae05e22859e2cd021..b0b515b8ebeffe25a760d7d6faa87cbc1a585b2d 100644 @@ -81,22 +82,22 @@ index 9d6db4a378036559efab91c8b7dcf2a6b0c2cce6..4d9f73add791cef03cc7aeaf1598a73c } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 879c090d9c4574a2cd45a0eb1bf9cb171834d940..d6e8d96372d4212c72a50602207075ccd3f5062d 100644 +index 770b959d9e51ef0645415d5a0d7d79b7031abd66..82670c8bc74cbb208a91cec433498b823e86ce2e 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -683,6 +683,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -682,6 +682,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + @Override public boolean enforceSecureProfile() { DedicatedServerProperties dedicatedserverproperties = this.getProperties(); - + if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().noChatReports.enabled) return false; // Plazma - Implement No Chat Reports - return dedicatedserverproperties.enforceSecureProfile && dedicatedserverproperties.onlineMode && this.services.profileKeySignatureValidator() != null; - } - + // Paper start - fix secure profile with proxy online mode + return dedicatedserverproperties.enforceSecureProfile + && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 6f6228edfe77668552a40a814ab3cebd74c4cb5a..22f26761965d3c03b109939585ff528d382eab21 100644 +index b19c59a87d4136da583a0b687f6b27fef3456f09..b54372c32845d2bc340951c0ea88d480efc1dd6a 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -270,6 +270,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -262,6 +262,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet, @Nullable PacketSendListener callbacks) { @@ -111,10 +112,10 @@ index 6f6228edfe77668552a40a814ab3cebd74c4cb5a..22f26761965d3c03b109939585ff528d 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 58cc1bed851994fb591e9b832b98d25eda153b47..4fbe96813067d3ccf1d8f29151ac3fac0840d76f 100644 +index e8de78f8b7c90a719e10c483991f45a7886256be..0ff64fc50768a4bed9c871fed1089753912b89d2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1471,6 +1471,7 @@ public abstract class PlayerList { +@@ -1493,6 +1493,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public @@ -123,14 +124,13 @@ index 58cc1bed851994fb591e9b832b98d25eda153b47..4fbe96813067d3ccf1d8f29151ac3fac } diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 5a62bffe495002b3bbf5fd995df135c5d174458a..989aa0aeb05a878945849adc6fb6663027e15927 100644 +index f3cf7634a5fd470e7fb295ae1f88e14f0c4a0d1d..5dafbe4ca74071e25ce79128ca08c7bfebb778d5 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -55,4 +55,22 @@ public class GlobalConfiguration extends ConfigurationPart { - public boolean notSecurePrefix = true; +@@ -56,4 +56,22 @@ public class GlobalConfiguration extends ConfigurationPart { } -+ + + public NoChatReports noChatReports; + public class NoChatReports extends ConfigurationPart { + @@ -148,4 +148,5 @@ index 5a62bffe495002b3bbf5fd995df135c5d174458a..989aa0aeb05a878945849adc6fb66630 + } + + } ++ } diff --git a/patches/server/0022-Ignore-useless-entity-packets.patch b/patches/server/0024-Ignore-useless-entity-packets.patch similarity index 68% rename from patches/server/0022-Ignore-useless-entity-packets.patch rename to patches/server/0024-Ignore-useless-entity-packets.patch index c3e1d31d5..0198d4e59 100644 --- a/patches/server/0022-Ignore-useless-entity-packets.patch +++ b/patches/server/0024-Ignore-useless-entity-packets.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Ignore useless entity packets diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index c6d80accdac49564b5386717a92dbd5a10237f06..ddbff17499746cd370fdf18ff78606b0ac770df4 100644 +index c6ef510d335b8baea58c4491853414a52a06b66b..e2dcdc9f317a4ab1a9b30e482607dc041abb7035 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -200,6 +200,8 @@ public class ServerEntity { @@ -13,7 +13,7 @@ index c6d80accdac49564b5386717a92dbd5a10237f06..ddbff17499746cd370fdf18ff78606b0 flag5 = true; } + -+ if (this.entity.level().plazmaLevelConfiguration().entity.ignoreUselessPackets && isUselessPacket(packet1)) packet1 = null; // Plazma ++ if (this.level.plazmaConfig().entity.ignoreUselessPackets && isUselessPacket(packet1)) packet1 = null; // Plazma } if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { @@ -37,16 +37,16 @@ index c6d80accdac49564b5386717a92dbd5a10237f06..ddbff17499746cd370fdf18ff78606b0 public void removePairing(ServerPlayer player) { this.entity.stopSeenByPlayer(player); player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()})); -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 414baade911fab3450430af9378feedc419868f3..914cc4f9a5598d2d70c7338d7cfc9be0fe5f0e31 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -33,6 +33,8 @@ public class LevelConfigurations extends ConfigurationPart { +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index 036c0b12553ae203e8c73d44dc2e3d625b812af5..909a74c19501d9440f3d2435b6514d738efcfc05 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -29,6 +29,8 @@ public class WorldConfigurations extends ConfigurationPart { public Entity entity; public class Entity extends ConfigurationPart { -+ public boolean ignoreUselessPackets = DO_OPTIMIZE; ++ public boolean ignoreUselessPackets = OPTIMIZE; + - public Player player; - public class Player extends ConfigurationPart { + public Phantom phantom; + public class Phantom extends ConfigurationPart { diff --git a/patches/server/0024-Improve-biome-temperature-cache.patch b/patches/server/0025-Improve-biome-temperature-cache.patch similarity index 85% rename from patches/server/0024-Improve-biome-temperature-cache.patch rename to patches/server/0025-Improve-biome-temperature-cache.patch index 98b6241c3..79d5897cb 100644 --- a/patches/server/0024-Improve-biome-temperature-cache.patch +++ b/patches/server/0025-Improve-biome-temperature-cache.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Thu, 28 Sep 2023 12:33:14 +0900 +Date: Mon, 6 Nov 2023 10:39:01 +0900 Subject: [PATCH] Improve biome temperature cache diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java -index ed439b7e94646141c93a7dd3704d1cdeb5c27e16..71880b6fde3a287aa75c3799ffdd82a7943bb9db 100644 +index ed439b7e94646141c93a7dd3704d1cdeb5c27e16..642fd0e06f9ab53b4ef2cafe1dc3321a3fd7ee9e 100644 --- a/src/main/java/net/minecraft/world/level/biome/Biome.java +++ b/src/main/java/net/minecraft/world/level/biome/Biome.java @@ -67,7 +67,7 @@ public final class Biome { @@ -13,7 +13,7 @@ index ed439b7e94646141c93a7dd3704d1cdeb5c27e16..71880b6fde3a287aa75c3799ffdd82a7 private final BiomeSpecialEffects specialEffects; // Pufferfish start - use our cache - private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { -+ private static final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { // Plazma - Improve BiomeTemperatureCache ++ private static final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { // Plazma - Improve biome temperature cache return Util.make(() -> { /* Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { @@ -22,7 +22,7 @@ index ed439b7e94646141c93a7dd3704d1cdeb5c27e16..71880b6fde3a287aa75c3799ffdd82a7 long l = blockPos.asLong(); // Pufferfish start - gg.airplane.structs.Long2FloatAgingCache cache = this.temperatureCache.get(); -+ gg.airplane.structs.Long2FloatAgingCache cache = temperatureCache.get(); // Plazma - Improve BiomeTemperatureCache ++ gg.airplane.structs.Long2FloatAgingCache cache = temperatureCache.get(); // Plazma - Improve biome temperature cache float f = cache.getValue(l); if (!Float.isNaN(f)) { return f; diff --git a/patches/server/0026-Configurable-entity-sensor-tick.patch b/patches/server/0026-Configurable-entity-sensor-tick.patch new file mode 100644 index 000000000..2e29a1152 --- /dev/null +++ b/patches/server/0026-Configurable-entity-sensor-tick.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Mon, 6 Nov 2023 11:36:08 +0900 +Subject: [PATCH] Configurable entity sensor tick + + +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index aeae6117b398b84d5c8ecaa175a72867416ff166..c9df97eebe3635009737be83a28f36d291fcce79 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -936,10 +936,10 @@ public abstract class Mob extends LivingEntity implements Targeting { + } + // Paper end + //this.level().getProfiler().push("sensing"); // Purpur +- this.sensing.tick(); + //this.level().getProfiler().pop(); // Purpur + int i = this.level().getServer().getTickCount() + this.getId(); + ++ if (i % this.level().plazmaConfig().entity.sensorTick == 0) this.sensing.tick(); // Plazma - Configurable entity sensor tick + if (i % 2 != 0 && this.tickCount > 1) { + //this.level().getProfiler().push("targetSelector"); // Purpur + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index 909a74c19501d9440f3d2435b6514d738efcfc05..b036b54d551c892cc48d0a6816382bce5e38efd4 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -30,6 +30,7 @@ public class WorldConfigurations extends ConfigurationPart { + public class Entity extends ConfigurationPart { + + public boolean ignoreUselessPackets = OPTIMIZE; ++ public int sensorTick = 1; + + public Phantom phantom; + public class Phantom extends ConfigurationPart { diff --git a/patches/server/0026-Configurable-sensor-tick.patch b/patches/server/0026-Configurable-sensor-tick.patch deleted file mode 100644 index 780ba9a6a..000000000 --- a/patches/server/0026-Configurable-sensor-tick.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Fri, 29 Sep 2023 21:12:38 +0900 -Subject: [PATCH] Configurable sensor tick - - -diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index fb5c21ba15995d00da87ee6ef9e4ab8f6678d67f..4710f85197bc80e554cc1b2b84058c8dc8049c1f 100644 ---- a/src/main/java/net/minecraft/world/entity/Mob.java -+++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -938,10 +938,10 @@ public abstract class Mob extends LivingEntity implements Targeting { - } - // Paper end - //this.level().getProfiler().push("sensing"); // Purpur -- this.sensing.tick(); - //this.level().getProfiler().pop(); // Purpur - int i = this.level().getServer().getTickCount() + this.getId(); - -+ if (i % this.level().plazmaLevelConfiguration().entity.sensorTick == 0) this.sensing.tick(); // Plazma - moved down - if (i % 2 != 0 && this.tickCount > 1) { - //this.level().getProfiler().push("targetSelector"); // Purpur - if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index bb0f561f0b0d71697de52c834d2ed1798b2022df..6711b3d93eb5292314bcd89280d88f367eada9df 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -33,6 +33,8 @@ public class LevelConfigurations extends ConfigurationPart { - public Entity entity; - public class Entity extends ConfigurationPart { - -+ public int sensorTick = DO_OPTIMIZE ? 10 : 1; -+ - public boolean ignoreUselessPackets = DO_OPTIMIZE; - - public Player player; diff --git a/patches/server/0027-Configurable-cave-lava-sea-level.patch b/patches/server/0027-Configurable-cave-lava-sea-level.patch new file mode 100644 index 000000000..761261472 --- /dev/null +++ b/patches/server/0027-Configurable-cave-lava-sea-level.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Tue, 7 Nov 2023 15:32:24 +0900 +Subject: [PATCH] Configurable cave lava sea level + +This patch also fix MC-237017. + +diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +index 58609a0911c4e32b6f80f050cd3d23f70ad75b1b..2db6c1b9530b4b082ef6f6ec17c542ba8ad7fa5f 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +@@ -72,6 +72,15 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + } + + private static Aquifer.FluidPicker createFluidPicker(NoiseGeneratorSettings settings) { ++ // Plazma start ++ if (true) { ++ org.plazmamc.plazma.configurations.GlobalConfiguration config = org.plazmamc.plazma.configurations.GlobalConfiguration.get(); ++ return (x, y, z) -> new Aquifer.FluidStatus( ++ config.worldgen.caveLavaSeaLevel.useCustomSeaLevel ? config.worldgen.caveLavaSeaLevel.customSeaLevel : settings.seaLevel(), ++ config.worldgen.caveLavaSeaLevel.customSeaLevel(settings) ++ ); ++ } ++ // Plazma end + Aquifer.FluidStatus aquifer_b = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState()); + int i = settings.seaLevel(); + Aquifer.FluidStatus aquifer_b1 = new Aquifer.FluidStatus(i, settings.defaultFluid()); +diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +index 5dafbe4ca74071e25ce79128ca08c7bfebb778d5..3cfb9357d0c61e84488c2c60f073fa12df942b8e 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +@@ -35,6 +35,25 @@ public class GlobalConfiguration extends ConfigurationPart { + public WorldGeneration worldgen; + public class WorldGeneration extends ConfigurationPart { + ++ public CaveLavaSeaLevel caveLavaSeaLevel; ++ public class CaveLavaSeaLevel extends ConfigurationPart { ++ ++ public boolean useCustomSeaLevel = false; ++ public int customSeaLevel = -54; ++ String customSeaBlock = "default"; ++ ++ public net.minecraft.world.level.block.state.BlockState customSeaLevel(net.minecraft.world.level.levelgen.NoiseGeneratorSettings settings) { ++ if (this.customSeaBlock.equalsIgnoreCase("default")) return settings.defaultFluid(); ++ return net.minecraft.core.registries.BuiltInRegistries.BLOCK ++ .getOptional(new net.minecraft.resources.ResourceLocation(this.customSeaBlock)) ++ .orElseGet(() -> { ++ PlazmaConfigurations.LOGGER.warn("Invalid custom sea level block: " + this.customSeaBlock, ", defaulting to lava"); ++ return net.minecraft.world.level.block.Blocks.LAVA; ++ }) ++ .defaultBlockState(); ++ } ++ ++ } + + } + diff --git a/patches/server/0027-Variable-entity-wakeup-duration.patch b/patches/server/0028-Variable-entity-wakeup-duration.patch similarity index 53% rename from patches/server/0027-Variable-entity-wakeup-duration.patch rename to patches/server/0028-Variable-entity-wakeup-duration.patch index 400184796..74357b7c5 100644 --- a/patches/server/0027-Variable-entity-wakeup-duration.patch +++ b/patches/server/0028-Variable-entity-wakeup-duration.patch @@ -1,28 +1,28 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Sat, 30 Sep 2023 21:56:32 +0900 +Date: Mon, 4 Dec 2023 23:01:32 +0900 Subject: [PATCH] Variable entity wakeup duration -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 82975c1c92c84294740a411b4a351efb8a2e6769..cb21da3cff4dbb08c7786c09b39e381abdf45c33 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -51,6 +51,20 @@ public class LevelConfigurations extends ConfigurationPart { +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index b036b54d551c892cc48d0a6816382bce5e38efd4..459cba838468b95547b2a515c497fcbb7bd45718 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -39,6 +39,20 @@ public class WorldConfigurations extends ConfigurationPart { } + public WakeUpDurationVariance wakeUpDurationVariance; + public class WakeUpDurationVariance extends ConfigurationPart { + -+ double defaultValue() { -+ return DO_OPTIMIZE ? 0.2 : 0.0; ++ private double defaultValue() { ++ return OPTIMIZE ? 0.2 : 0.0; + } + -+ double animal = defaultValue(); public double animal() { return Math.max(0, this.animal); } -+ double monster = defaultValue(); public double monster() { return Math.max(0, this.monster); } -+ double flyingMonster = defaultValue(); public double flyingMonster() { return Math.max(0, this.flyingMonster); } -+ double villager = defaultValue(); public double villager() { return Math.max(0, this.villager); } ++ double animal = defaultValue(); public double animal() { return Math.max(this.animal, 0.0); } ++ double monster = defaultValue(); public double monster() { return Math.max(this.monster, 0.0); } ++ double flying = defaultValue(); public double flying() { return Math.max(this.flying, 0.0); } ++ double villager = defaultValue(); public double villager() { return Math.max(this.villager, 0.0); } + + } + @@ -30,47 +30,47 @@ index 82975c1c92c84294740a411b4a351efb8a2e6769..cb21da3cff4dbb08c7786c09b39e381a public Structure structure; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 062a793a134f774ebf918aab10443527c06c4fd1..3a362fef29c6fa29c37eff539e343eb3a56bf122 100644 +index 0b03dae85e6008283e68b07fa438daccf0e4f5fa..5b981300a8addb85fce32b814dfe70cb2bc4beb3 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -68,6 +68,13 @@ public class ActivationRange +@@ -68,29 +68,36 @@ public class ActivationRange Activity.PANIC }; + // Plazma start - Variable entity wakeup duration -+ private static final java.util.Random WAKEUP_DURATION_RANDOM = org.plazmamc.plazma.PlazmaOptions.useJavaRandom() ? new java.util.Random() : new org.plazmamc.plazma.Random(); -+ private static int getWakeupDurationWithVariance(int duration, double deviation) { ++ private static int getWakeupDuration(net.minecraft.util.RandomSource random, int duration, double deviation) { + if (deviation == 0) return duration; -+ return (int) Math.min(Integer.MAX_VALUE, Math.max(1, Math.round(duration * WAKEUP_DURATION_RANDOM.nextGaussian(1, deviation)))); ++ return (int) Math.min(Integer.MAX_VALUE, Math.max(1, Math.round(duration * (1 + deviation * random.nextGaussian())))); + } + // Plazma end private static int checkInactiveWakeup(Entity entity) { Level world = entity.level(); SpigotWorldConfig config = world.spigotConfig; -@@ -75,22 +82,22 @@ public class ActivationRange ++ org.plazmamc.plazma.configurations.WorldConfigurations plazmaConfig = world.plazmaConfig(); // Plazma + long inactiveFor = MinecraftServer.currentTick - entity.activatedTick; if (entity.activationType == ActivationType.VILLAGER) { if (inactiveFor > config.wakeUpInactiveVillagersEvery && world.wakeupInactiveRemainingVillagers > 0) { world.wakeupInactiveRemainingVillagers--; - return config.wakeUpInactiveVillagersFor; -+ return getWakeupDurationWithVariance(config.wakeUpInactiveVillagersFor, world.plazmaLevelConfiguration().entity.wakeUpDurationVariance.villager()); // Plazma - Variable entity wakeup duration ++ return getWakeupDuration(world.getRandom(), config.wakeUpInactiveVillagersFor, plazmaConfig.entity.wakeUpDurationVariance.villager()); // Plazma } } else if (entity.activationType == ActivationType.ANIMAL) { if (inactiveFor > config.wakeUpInactiveAnimalsEvery && world.wakeupInactiveRemainingAnimals > 0) { world.wakeupInactiveRemainingAnimals--; - return config.wakeUpInactiveAnimalsFor; -+ return getWakeupDurationWithVariance(config.wakeUpInactiveAnimalsFor, world.plazmaLevelConfiguration().entity.wakeUpDurationVariance.animal()); // Plazma - Variable entity wakeup duration ++ return getWakeupDuration(world.getRandom(), config.wakeUpInactiveAnimalsFor, plazmaConfig.entity.wakeUpDurationVariance.animal()); // Plazma } } else if (entity.activationType == ActivationType.FLYING_MONSTER) { if (inactiveFor > config.wakeUpInactiveFlyingEvery && world.wakeupInactiveRemainingFlying > 0) { world.wakeupInactiveRemainingFlying--; - return config.wakeUpInactiveFlyingFor; -+ return getWakeupDurationWithVariance(config.wakeUpInactiveFlyingFor, world.plazmaLevelConfiguration().entity.wakeUpDurationVariance.flyingMonster()); // Plazma - Variable entity wakeup duration ++ return getWakeupDuration(world.getRandom(), config.wakeUpInactiveFlyingFor, plazmaConfig.entity.wakeUpDurationVariance.flying()); // Plazma } } else if (entity.activationType == ActivationType.MONSTER || entity.activationType == ActivationType.RAIDER) { if (inactiveFor > config.wakeUpInactiveMonstersEvery && world.wakeupInactiveRemainingMonsters > 0) { world.wakeupInactiveRemainingMonsters--; - return config.wakeUpInactiveMonstersFor; -+ return getWakeupDurationWithVariance(config.wakeUpInactiveMonstersFor, world.plazmaLevelConfiguration().entity.wakeUpDurationVariance.monster()); // Plazma - Variable entity wakeup duration ++ return getWakeupDuration(world.getRandom(), config.wakeUpInactiveMonstersFor, plazmaConfig.entity.wakeUpDurationVariance.monster()); // Plazma } } return -1; diff --git a/patches/server/0028-Optimise-state-lookup-more.patch b/patches/server/0029-Optimise-state-lookup-more.patch similarity index 67% rename from patches/server/0028-Optimise-state-lookup-more.patch rename to patches/server/0029-Optimise-state-lookup-more.patch index 3a1cdd378..bad645e20 100644 --- a/patches/server/0028-Optimise-state-lookup-more.patch +++ b/patches/server/0029-Optimise-state-lookup-more.patch @@ -1,59 +1,57 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Sat, 30 Sep 2023 22:02:58 +0900 +Date: Mon, 4 Dec 2023 23:12:47 +0900 Subject: [PATCH] Optimise state lookup more diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java -index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..0832e4fa92b6464a6206475fbceb3b36462757b3 100644 +index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..50d97c5ab33f33b81dbafd7cf42da5afd9856eeb 100644 --- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java +++ b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java @@ -17,6 +17,7 @@ public final class ZeroCollidingReferenceStateTable { protected final StateHolder this_state; protected long[] index_table; -+ public long[] index_table() { return this.index_table; } // Plazma - getter ++ public long[] index_table() { return this.index_table; } // Plazma - Getter protected StateHolder[][] value_table; public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index 5f285d190186a2ff5a61d05070593e1d633dd79a..7b61a956892e90c7556db46d9277da8d252547cd 100644 +index 5f285d190186a2ff5a61d05070593e1d633dd79a..669c42f1598e2a06bb0b95aa0bc413911346f3ff 100644 --- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -@@ -114,21 +114,15 @@ public abstract class StateHolder { +@@ -114,6 +114,12 @@ public abstract class StateHolder { } public , V extends T> S trySetValue(Property property, V value) { -- Comparable comparable = this.values.get(property); -- if (comparable != null && !comparable.equals(value)) { -- S object = this.neighbours.get(property, value); -- if (object == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -- } else { -- return object; -- } -- } else { -- return (S)this; -- } -+ // Plazma start - optimise state lookup more ++ // Plazma start - Optimise state lookup more + final S ret = (S) this.optimisedTable.get(property, value); + if (ret == null) throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); + return ret; ++ /* + // Plazma end + Comparable comparable = this.values.get(property); + if (comparable != null && !comparable.equals(value)) { + S object = this.neighbours.get(property, value); +@@ -125,10 +131,11 @@ public abstract class StateHolder { + } else { + return (S)this; + } ++ */ // Plazma - Optimise state lookup more } public void populateNeighbours(Map, Comparable>, S> states) { - if (this.neighbours != null) { -+ if (this.optimisedTable.index_table() != null) { // Plazma - optimise state lookup more ++ if (this.optimisedTable.index_table() != null) { // Plazma - optimise state lookup throw new IllegalStateException(); } else { Table, Comparable, S> table = HashBasedTable.create(); -@@ -143,7 +137,7 @@ public abstract class StateHolder { +@@ -143,7 +150,7 @@ public abstract class StateHolder { } } - this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup -+ this.optimisedTable.loadInTable((Table) (table.isEmpty() ? table : ArrayTable.create(table)), this.values); // Paper - optimise state lookup // Plazma - more ++ this.optimisedTable.loadInTable((Table) (table.isEmpty() ? table : ArrayTable.create(table)), this.values); // Plazma - Optimize state lookup more } } diff --git a/patches/server/0029-Suppress-error-from-dirty-attributes.patch b/patches/server/0029-Suppress-error-from-dirty-attributes.patch deleted file mode 100644 index 91d707f7f..000000000 --- a/patches/server/0029-Suppress-error-from-dirty-attributes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Sat, 30 Sep 2023 22:06:00 +0900 -Subject: [PATCH] Suppress error from dirty attributes - - -diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index b2770e053f6db173dedbf044d67aa315e2fd7302..30b4c6bf1a0c847d00fc466ca9c997f9049bb697 100644 ---- a/src/main/java/net/minecraft/server/level/ServerEntity.java -+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -395,7 +395,8 @@ public class ServerEntity { - } - - if (this.entity instanceof LivingEntity) { -- Set set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); -+ Set attributes = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); // Plazma - Suppress error from dirty attributes -+ final Set set = this.entity.level().plazmaLevelConfiguration().entity.suppressErrorFromDirtyAttributes ? java.util.Collections.synchronizedSet(attributes) : attributes; // Plazma - Suppress error from dirty attributes - - if (!set.isEmpty()) { - // CraftBukkit start - Send scaled max health -@@ -406,7 +407,7 @@ public class ServerEntity { - this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set)); - } - -- set.clear(); -+ attributes.clear(); // Plazma - Suppress error from dirty attributes - } - - } -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index cb21da3cff4dbb08c7786c09b39e381abdf45c33..dfd408dc42a6000eb5fa56bbdb64f2329e545078 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -36,6 +36,7 @@ public class LevelConfigurations extends ConfigurationPart { - public int sensorTick = DO_OPTIMIZE ? 10 : 1; - - public boolean ignoreUselessPackets = DO_OPTIMIZE; -+ public boolean suppressErrorFromDirtyAttributes = false; - - public Player player; - public class Player extends ConfigurationPart { diff --git a/patches/server/0030-Suppress-errors-from-dirty-attributes.patch b/patches/server/0030-Suppress-errors-from-dirty-attributes.patch new file mode 100644 index 000000000..1992bcb7e --- /dev/null +++ b/patches/server/0030-Suppress-errors-from-dirty-attributes.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Mon, 4 Dec 2023 23:15:43 +0900 +Subject: [PATCH] Suppress errors from dirty attributes + + +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index e2dcdc9f317a4ab1a9b30e482607dc041abb7035..085dfb2cf8596f5f0be4b1bf9a3cbe1a0e9b2967 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -395,7 +395,8 @@ public class ServerEntity { + } + + if (this.entity instanceof LivingEntity) { +- Set set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); ++ Set attributes = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); // Plazma - Suppress errors from dirty attributes ++ final Set set = this.level.plazmaConfig().entity.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes; // Plazma - Suppress errors from dirty attributes + + if (!set.isEmpty()) { + // CraftBukkit start - Send scaled max health +@@ -406,7 +407,7 @@ public class ServerEntity { + this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set)); + } + +- set.clear(); ++ attributes.clear(); // Plazma - Suppress errors from dirty attributes + } + + } +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index 459cba838468b95547b2a515c497fcbb7bd45718..b1293935e55fcb1c45224e5bda9be8d1045ff4e8 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -31,6 +31,7 @@ public class WorldConfigurations extends ConfigurationPart { + + public boolean ignoreUselessPackets = OPTIMIZE; + public int sensorTick = 1; ++ public boolean suppressErrorsFromDirtyAttributes = OPTIMIZE; + + public Phantom phantom; + public class Phantom extends ConfigurationPart { diff --git a/patches/server/0030-Skip-event-if-no-listeners.patch b/patches/server/0031-Skip-event-if-no-listeners.patch similarity index 53% rename from patches/server/0030-Skip-event-if-no-listeners.patch rename to patches/server/0031-Skip-event-if-no-listeners.patch index 6b854ad15..d982627a5 100644 --- a/patches/server/0030-Skip-event-if-no-listeners.patch +++ b/patches/server/0031-Skip-event-if-no-listeners.patch @@ -1,29 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Sat, 30 Sep 2023 22:10:59 +0900 +Date: Mon, 4 Dec 2023 23:17:15 +0900 Subject: [PATCH] Skip event if no listeners 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 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..6016c304ddbeb6ffbd591f30914c85fcb6371e80 100644 +index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..23594fb7eb4b2f33146592866608c2858ef23937 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -26,7 +26,7 @@ import java.util.Map; - import java.util.Set; - import java.util.logging.Level; - --class PaperEventManager { -+public class PaperEventManager { // Plazma - package -> public - - private final Server server; - -@@ -36,15 +36,17 @@ class PaperEventManager { +@@ -36,15 +36,16 @@ class PaperEventManager { // SimplePluginManager public void callEvent(@NotNull Event event) { + // Plazma start - Skip event if no listeners -+ HandlerList handlers = event.getHandlers(); -+ RegisteredListener[] listeners = handlers.getRegisteredListeners(); ++ RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); + if (listeners.length == 0) return; + // Plazma end if (event.isAsynchronous() && this.server.isPrimaryThread()) { @@ -38,15 +28,3 @@ index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..6016c304ddbeb6ffbd591f30914c85fc for (RegisteredListener registration : listeners) { if (!registration.getPlugin().isEnabled()) { continue; -diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index d17df5621717b1c8d1d9a5549feb73c3600ecf3d..ddbc37857bd2706844074925bc27b7a84efa5832 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -31,7 +31,6 @@ public class GlobalConfiguration extends ConfigurationPart { - @Override - public void postProcess() { - -- - } - - public boolean reduceCreateRandomInstance = DO_OPTIMIZE; diff --git a/patches/server/0031-Optimize-Spigot-event-bus.patch b/patches/server/0032-Optimize-spigot-event-bus.patch similarity index 55% rename from patches/server/0031-Optimize-Spigot-event-bus.patch rename to patches/server/0032-Optimize-spigot-event-bus.patch index 6335f3ee0..ed4cfb7ab 100644 --- a/patches/server/0031-Optimize-Spigot-event-bus.patch +++ b/patches/server/0032-Optimize-spigot-event-bus.patch @@ -1,27 +1,33 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Sat, 30 Sep 2023 22:17:02 +0900 -Subject: [PATCH] Optimize Spigot event bus +Date: Mon, 4 Dec 2023 23:19:46 +0900 +Subject: [PATCH] Optimize spigot event bus 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 6016c304ddbeb6ffbd591f30914c85fcb6371e80..482e2cdbd4f76f2a56c62bec12bfc39d7193b6ce 100644 +index 23594fb7eb4b2f33146592866608c2858ef23937..94eecf374f1e6b00556a380fd28376f720d61e8e 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -41,11 +41,14 @@ public class PaperEventManager { // Plazma - package -> public - RegisteredListener[] listeners = handlers.getRegisteredListeners(); +@@ -39,12 +39,19 @@ class PaperEventManager { + // Plazma start - Skip event if no listeners + RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); if (listeners.length == 0) return; - // Plazma end +- // Plazma end - if (event.isAsynchronous() && this.server.isPrimaryThread()) { - throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); - } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { - throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); -+ // Plazma start - Optimize Spigot event bus -+ if (event.asynchronous() != net.kyori.adventure.util.TriState.NOT_SET) { -+ final boolean async = event.isAsynchronous(); -+ final boolean primary = this.server.isPrimaryThread(); -+ if (async && primary) throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); -+ if (!async && !primary && !this.server.isStopping()) throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); ++ ++ // Optimize Spigot event bus ++ if (event.asynchronous() == net.kyori.adventure.util.TriState.NOT_SET) { ++ boolean async = event.isAsynchronous(); ++ boolean primary = this.server.isPrimaryThread(); ++ ++ if (async && primary) ++ throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); ++ ++ if (!async && !primary && !this.server.isStopping()) ++ throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); } + // Plazma end diff --git a/patches/server/0025-Implement-FixMySpawnR.patch b/patches/server/0033-Add-Entity-spawn-deadlock-timer.patch similarity index 53% rename from patches/server/0025-Implement-FixMySpawnR.patch rename to patches/server/0033-Add-Entity-spawn-deadlock-timer.patch index f564e716a..23ae3275c 100644 --- a/patches/server/0025-Implement-FixMySpawnR.patch +++ b/patches/server/0033-Add-Entity-spawn-deadlock-timer.patch @@ -1,11 +1,13 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 -Date: Fri, 29 Sep 2023 21:10:26 +0900 -Subject: [PATCH] Implement FixMySpawnR +Date: Tue, 5 Dec 2023 13:29:28 +0900 +Subject: [PATCH] Add Entity spawn deadlock timer +[REFERENCE] +- AbsolemJackdaw/FixMySpawnR diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 64d911bee1607880514061c75116d8672df8bb8f..7868590696f620cc5f0785125c9573d7494d8477 100644 +index 914564a528c360f352927e7681ab2e31ed365b21..090643e977257a097a99a3f54d1d73b995cfd82a 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -46,6 +46,8 @@ public abstract class BaseSpawner { @@ -14,17 +16,17 @@ index 64d911bee1607880514061c75116d8672df8bb8f..7868590696f620cc5f0785125c9573d7 private int tickDelay = 0; // Paper + private int blockExistsTick = 0; // Plazma - Implement FixMySpawnR + private boolean blockLockedByTime = false; // Plazma - Implement FixMySpawnR - - public BaseSpawner() {} - -@@ -81,6 +83,17 @@ public abstract class BaseSpawner { + // Paper start - ported from 1.20.3 Fix MC-259321 + static net.minecraft.world.level.entity.EntityTypeTest forExactClass(Class clazz) { + return new net.minecraft.world.level.entity.EntityTypeTest<>() { +@@ -97,6 +99,17 @@ public abstract class BaseSpawner { } public void serverTick(ServerLevel world, BlockPos pos) { + // Plazma start - Implement FixMySpawnR -+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().gameMechanics.spawning.deadlockTimer.enabled) { ++ if (world.plazmaConfig().entity.spawnDeadlockTimer.enabled) { + if (!this.blockLockedByTime) { -+ if (this.blockExistsTick > org.plazmamc.plazma.configurations.GlobalConfiguration.get().gameMechanics.spawning.deadlockTimer.timerTimeout) ++ if (this.blockExistsTick > world.plazmaConfig().entity.spawnDeadlockTimer.timerTimeout) + blockLockedByTime = true; + else blockExistsTick++; + } @@ -35,22 +37,20 @@ index 64d911bee1607880514061c75116d8672df8bb8f..7868590696f620cc5f0785125c9573d7 if (spawnCount <= 0 || maxNearbyEntities <= 0) return; // Paper - Ignore impossible spawn tick // Paper start - Configurable mob spawner tick rate if (spawnDelay > 0 && --tickDelay > 0) return; -@@ -286,6 +299,14 @@ public abstract class BaseSpawner { +@@ -301,6 +314,12 @@ public abstract class BaseSpawner { + if (nbt.contains("SpawnRange", 99)) { this.spawnRange = nbt.getShort("SpawnRange"); } - + // Plazma start - Implement FixMySpawnR -+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().gameMechanics.spawning.deadlockTimer.enabled -+ && nbt.contains("Plazma.SpawnerTicks", 99)) { ++ if (nbt.contains("Plazma.SpawnerTicks", 99)) { + this.blockExistsTick = nbt.getInt("Plazma.SpawnerTicks"); + this.blockLockedByTime = nbt.getBoolean("Plazma.SpawnerLocked"); + } + // Plazma end -+ + this.displayEntity = null; } - -@@ -314,6 +335,9 @@ public abstract class BaseSpawner { +@@ -330,6 +349,9 @@ public abstract class BaseSpawner { })); } @@ -60,32 +60,22 @@ index 64d911bee1607880514061c75116d8672df8bb8f..7868590696f620cc5f0785125c9573d7 nbt.put("SpawnPotentials", (Tag) SpawnData.LIST_CODEC.encodeStart(NbtOps.INSTANCE, this.spawnPotentials).result().orElseThrow()); return nbt; } -diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 989aa0aeb05a878945849adc6fb6663027e15927..d17df5621717b1c8d1d9a5549feb73c3600ecf3d 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -40,6 +40,24 @@ public class GlobalConfiguration extends ConfigurationPart { +diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +index b1293935e55fcb1c45224e5bda9be8d1045ff4e8..e5e0b0f0bd3b2249dc1db029682b8957b0addcac 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java +@@ -54,6 +54,14 @@ public class WorldConfigurations extends ConfigurationPart { - } + } -+ public GameMechanics gameMechanics; -+ public class GameMechanics extends ConfigurationPart { -+ -+ public Spawning spawning; -+ public class Spawning extends ConfigurationPart { ++ public SpawnDeadlockTimer spawnDeadlockTimer; ++ public class SpawnDeadlockTimer extends ConfigurationPart { + -+ public DeadlockTimer deadlockTimer; -+ public class DeadlockTimer extends ConfigurationPart { -+ -+ public boolean enabled = DO_OPTIMIZE; -+ public int timerTimeout = 0; -+ -+ } ++ public boolean enabled = OPTIMIZE; ++ public int timerTimeout = 0; + + } + -+ } -+ - public Player player; - public class Player extends ConfigurationPart { + } + public Structure structure; diff --git a/patches/server/0021-Use-faster-random.patch b/patches/unapplied/server/0023-Use-faster-random.patch similarity index 89% rename from patches/server/0021-Use-faster-random.patch rename to patches/unapplied/server/0023-Use-faster-random.patch index f6a80d2fd..7b16846fd 100644 --- a/patches/server/0021-Use-faster-random.patch +++ b/patches/unapplied/server/0023-Use-faster-random.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use faster random diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -index 5408cbc21fc7577a6100b5a1ca0463e899d2df8b..f17b42176e9e5148b98baf4a6a7e7528242406d9 100644 +index 5408cbc21fc7577a6100b5a1ca0463e899d2df8b..253781726a586900ce8c2b5646dd634ff410508f 100644 --- a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java +++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java @@ -16,7 +16,7 @@ import java.util.UUID; @@ -13,38 +13,38 @@ index 5408cbc21fc7577a6100b5a1ca0463e899d2df8b..f17b42176e9e5148b98baf4a6a7e7528 public class PaperLootableInventoryData { - private static final Random RANDOM = new Random(); -+ private static final Random RANDOM = org.plazmamc.plazma.PlazmaOptions.useJavaRandom() ? new Random() : new org.plazmamc.plazma.Random(); // Plazma - use faster random ++ private static final Random RANDOM = org.plazmamc.plazma.Options.JAVA_RANDOM ? new Random() : new org.plazmamc.plazma.Random(); // Plazma - use faster random private long lastFill = -1; private long nextRefill = -1; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ee571f465ca1e83e760a4d57b3d11accb53c6cfe..1a92a7f6391df6395c11d11efdbf2f4eda5c6651 100644 +index 02b82020609e2b1426d26e9f073723e316846fc6..b51cde094e0464f7b2dad50aa68f33390e856659 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -680,7 +680,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Thu, 4 May 2023 16:54:53 +0900 -Subject: [PATCH] Optimize VarInts - -https://github.com/PaperMC/Paper/pull/8418 - -diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -index c0bd2997fe3ebbfe926de832a36d209cc875f3e2..8bb552410207b39a3b4160a5df51410455107fcf 100644 ---- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java -+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -@@ -99,12 +99,26 @@ public class FriendlyByteBuf extends ByteBuf { - private static final Gson GSON = new Gson(); - - public static boolean hasItemSerializeEvent = false; // Purpur -+ public static boolean optimizeVarInts = false; // Plazma - - public FriendlyByteBuf(ByteBuf parent) { - this.source = parent; - } - -+ // Plazma start - Optimize VarInts -+ private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33]; -+ static { -+ for (int i = 0; i <= 32; ++i) { -+ VARINT_EXACT_BYTE_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d); -+ } -+ VARINT_EXACT_BYTE_LENGTHS[32] = 1; // Special case for the number 0. -+ } -+ // Plazma end - public static int getVarIntSize(int value) { -+ // Plazma start - Optimize VarInts -+ if (optimizeVarInts) -+ return VARINT_EXACT_BYTE_LENGTHS[Integer.numberOfLeadingZeros(value)]; -+ // Plazma end - for (int j = 1; j < 5; ++j) { - if ((value & -1 << j * 7) == 0) { - return j; -@@ -620,6 +634,25 @@ public class FriendlyByteBuf extends ByteBuf { - } - - public FriendlyByteBuf writeVarInt(int value) { -+ // Plazma start - Optimize VarInts -+ if (optimizeVarInts) { -+ // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes -+ // that the proxy will write, to improve inlining. -+ if ((value & (0xFFFFFFFF << 7)) == 0) { -+ writeByte(value); -+ } else if ((value & (0xFFFFFFFF << 14)) == 0) { -+ int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); -+ writeShort(w); -+ } else { -+ while ((value & -128) != 0) { -+ this.writeByte(value & 127 | 128); -+ value >>>= 7; -+ } -+ this.writeByte(value); -+ } -+ return this; -+ } -+ // Plazma end - while ((value & -128) != 0) { - this.writeByte(value & 127 | 128); - value >>>= 7; -diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index b2c9ac1947e6c9ad0e693cfeaf6f2f4bfd521aa0..525fe30b6abba295709fca3d10f9b24679112571 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -38,11 +38,17 @@ public class GlobalConfiguration extends ConfigurationPart { - } - - public Misc misc; -- public class Misc extends ConfigurationPart { -+ public class Misc extends ConfigurationPart.Post { - - public boolean reduceCreateRandomInstance = DO_OPTIMIZE; - public boolean doNotTriggerLootTableRefreshForNonPlayerInteraction = DO_OPTIMIZE; - public boolean doNotSendUselessEntityPackets = DO_OPTIMIZE; -+ public boolean optimizeVarInts = DO_OPTIMIZE; -+ -+ @Override -+ public void postProcess() { -+ net.minecraft.network.FriendlyByteBuf.optimizeVarInts = optimizeVarInts; -+ } - - } -