From bcb9a051af83387003ba86a80997b2baa683b9c2 Mon Sep 17 00:00:00 2001 From: AlphaKR93 Date: Thu, 18 Jan 2024 23:16:05 +0900 Subject: [PATCH] API, Generated API Patches done --- .gitignore | 2 +- README.md | 19 +- build.gradle.kts | 42 +- .../alwaysuptodate/tasks/PaperUpdateTask.kt | 4 +- .../alwaysuptodate/tasks/PurpurUpdateTask.kt | 3 +- gradle.properties | 6 +- gradle/libs.versions.toml | 2 +- libs/api.versions.toml | 2 +- libs/common.versions.toml | 2 +- patches/api/0001-Pufferfish-API-Changes.patch | 18 +- patches/api/0002-Purpur-API-Changes.patch | 203 +- patches/api/0003-Build-system-changes.patch | 36 +- patches/api/0004-Plazma-Configurations.patch | 4 +- .../api/0006-Implement-No-Chat-Reports.patch | 4 +- .../0001-Purpur-Generated-API-Changes.patch | 49 + .../0001-Pufferfish-Server-Changes.patch | 465 ++- .../server/0002-Purpur-Server-Changes.patch | 2946 +++++++++-------- 17 files changed, 2036 insertions(+), 1771 deletions(-) create mode 100644 patches/generated-api/0001-Purpur-Generated-API-Changes.patch diff --git a/.gitignore b/.gitignore index 3e9533a..14a5b5f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,4 @@ build-data/ *-API *-MojangAPI *-Server -*.jar +paper-api-generator diff --git a/README.md b/README.md index 580e995..d87f843 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ ### A Server Platform for Minecraft: Java Edition based on [Paper](https://github.com/PaperMC/Paper) [![Discord](https://img.shields.io/discord/1083716853928558652?style=for-the-badge&logo=discord&logoColor=ffffff&label=DISCORD&color=5865F2&link=https%3A%2F%2Fdiscord.gg%2FMmfC52K8A8)](https://discord.gg/MmfC52K8A8) -[![Build Status](https://img.shields.io/github/actions/workflow/status/PlazmaMC/Plazma/build.yml?branch=ver/1.20.2&logo=GoogleAnalytics&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/actions/workflows/build.yml?query=branch:ver/1.20.2) -[![MC Version](https://img.shields.io/badge/MC-1.20.2-6047ff?&logo=Webpack&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/releases/build/1.20.2/latest) +[![Build Status](https://img.shields.io/github/actions/workflow/status/PlazmaMC/Plazma/build.yml?branch=ver/1.20.4&logo=GoogleAnalytics&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/actions/workflows/build.yml?query=branch:ver/1.20.4) +[![MC Version](https://img.shields.io/badge/MC-1.20.4-6047ff?&logo=Webpack&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/releases/build/1.20.4/latest) [![License](https://img.shields.io/github/license/PlazmaMC/Plazma?logo=github&style=flat-square&logoColor=ffffff)](LICENSE) [![Downloads](https://img.shields.io/github/downloads/PlazmaMC/Plazma/total?label=Downloads&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAbvSURBVHhe7Z3vixVlFMf3jj9KLC0tqAgJlIoQSjOIIqggwohsCylxrYzU1BfZf7D1IvoLsiIqCwxXqQzCF722N0a+sEKo0BXXosLW1QpX3dvnzHOuuD9m5pm7M/Pc2Xs+cHhmnjnPr/Ode3Zm7o/tqRvNZjMaGxvbgH2L/at2EOuTY+pmlAEBnkug91EmMYDNVnejaAj+my7OqfSru1EkBH8Bdk6DnMYwfvO0WcdTp5y5qtFozNftNBZi97vNzqdOAizS0ofFWnY8tRGAs7+hm5nk8Q2NXbYFxgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEBgTIDAmQGBMgMCYAIExAQJjAgTGBAiMCRAYEyAwJkBgTIDAmACBMQECYwIExgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEJjSBWg2m7PHxsZWYs9gj2AL9FDHIXPDHsV6sRUydz1UT1jEauyX+Nu7CvtnKfqxOermBf5rpb0na7WZF/jPYV5vYP+45g6ZO/aEutULJr4Ou6RrmQTHvqDwFgHfUgTAV37+4EvXbDIcu4g9p+71gHnfxKTlTE8Fn88p5mqzVPArXADGvwpLDP4VDGM3aLNCKeVvAJNd12g0rtHdRPDpxXdAAqFVlcG4Ivwe5rDG1aSyEP8+3S6Usv4I36NlJhqAPSww19+E6SDBx/Z6Br/FCi0LpSMuQyUQBERE8EpH00FebYwzwJhPaVVQyhLgsJbeEJDS05EK7Jt2JvK9loVSlgC7Wew53fZGA1NKOtIzP2/aiaHdMMWnbq9YShEgiqI/KDYx8Uuuxh8JEO0KTUf6qpIzP3faYR4XKV5lTaddTY1g4RuxiywiN7Tbr4GLoaqty1C25Tpf7jlyI3PHXtau6oksAEu8IUuDdnKNHqcjytwCUKbeZKVBOwn+Rumn9rCQV2RBurZc0C6+WcNyCUA7uclq98y/gNX7zJ8IC5puOpKfpfQC3/VY96adJGRhWLvp6JRuZoLvkG7mgnYzJ+0kwQLbTkdlwpxmXtpJQs6yThJB5tI1wW8hC8baSkdFosGf2WknCRYeNB0xdveknSTk7AshgozZ9cFvIYHAKktHGvzOTDvMT94fnUdZ6aNqxqwkHTFG5WmHYeUn9yWmyQ8ZcZBPLuzD/sbkN/mPY2/R6Hp1KR3GKzUdSd8yhg5XOoy1iGHfphzEJKansb3YSnVxUPEiNuXCqZfGS9W1dBirlHSk63tJhykdiRk26EYfD/Wj2IaWo5z5F/TYlHD8MEVln5FhvELTkawPqyztMKQ8BDziRp8ajp/H7hZn+a8TmeD8rPZfCYxXSDqSPqQv7bYSGNb3weGALPQv3UkFv53af2Uw5rTSEW0rTTstJFZuBung96dc6fj+Ln+e3+8vhCiKPqTYwlxzv7NGG3kna3Oj0fjY1VSKb6wWR0zQ67f2ff2KBhE+oMj19qb6blEBKydPTCu91m8XAvkRxWZ51bqaZDT4m0IFPy+1EEDwSUcci9OOClYLaiOAQGAlHa3HzsQV45G6vrqc+S28BeDs6oj/y0KA5SMrS7HXsU+o2kW5g3KZHIudApMrVlwKjdIgE/y+1iZGBsTqgIYtFfzOyytAPvXlw21aGikQVzn7b3d7mQyLACfddibLUKxjv17UKSCAfI9gidvLZEgEOOq20+GSVT4qmOurP13KGmLl+9zsqAjwndv2YgcKz9JtYwIam9fcnheH5A+GfBvQG/y3a2NjAhIbDZMX+C8X1eRrpCdcVTb4yn80vVfHNBTich/2n4tSNvjKt0cb8ixI7h53uW6ywX8+DQ/QwSqt6nok+BQHiM3VrsaL3fg34y0CuoROUt+UmYiojW1j0/tmbqbB2mcRg+0SizgonmjsbtZuHFS8r8dzQbsjmDy3v5HdjrhbLhNZo6wVk3ftUt/1SoJ272l3PZcDRqUocpSXRVvX+vQrqWwQ+5k+4u8IxwdmCKypwZKuZVNuspaw29ZbtPQxQts7sN9lf9wZiwhbOfCO7holgABboyh6V3fHC8DBCNuPCE9qlVEgGtte7HJ2mJSzcboOO4jTXVplFAAx/YHiQc7+EVfjmHQFQ+Dl4dzjNDjmaozpQiyPU6yeGHxhyktIHE8ixMM0/EmrjDbRM/8hiamrGU/iNTwCnMAeoIOvtMrICbHbTyFpJ/GJc+pNFAKcwZ6mI7nhOqvVRgbEakRiRux6p0o7V+J946T3Cf3YC3Sc55a7ayDo5ynksU4/gf8trszAW4AWCHELxTbseYSo7EO7nQyB/5XiM2wngT8VV3qSW4AWDCp3hsvZfAyTB3N3YrdiCxGm9J+dCQHrHaWQq8QhTN7IOoR9w3p/xNq48+/p+R+4L+/7RtGOvAAAAABJRU5ErkJggg==&style=flat-square&color=green)](https://github.com/PlazmaMC/Plazma/releases) @@ -19,8 +19,8 @@ [main]: https://github.com/PlazmaMC/Plazma > [!IMPORTANT] -This is the branch for Plazma 1.20.2. If you want to know more about Plazma, please check the **[main branch][main]**.
-이곳은 플라즈마의 1.20.2용 분기입니다. 플라즈마에 대해 자세히 알고 싶다면 **[main 브랜치][main]** 를 확인해주세요. +This is the branch for Plazma 1.20.4. If you want to know more about Plazma, please check the **[main branch][main]**.
+이곳은 플라즈마의 1.20.4용 분기입니다. 플라즈마에 대해 자세히 알고 싶다면 **[main 분기][main]** 를 확인해주세요. ## ⬇️ Downloads > [!NOTE] @@ -28,11 +28,12 @@ If you don't know about Mojmap or Bundler, download **Reobf Paperclip**
Mojmap 또는 Bundler에 대해 잘 알지 못한다면, **Reobf Paperclip**을 사용하세요 -[paperReobf]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.2/latest/plazma-paperclip-1.20.2-R0.1-SNAPSHOT-reobf.jar -[paperMojmap]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.2/latest/plazma-paperclip-1.20.2-R0.1-SNAPSHOT-mojmap.jar -[bundlerReobf]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.2/latest/plazma-bundler-1.20.2-R0.1-SNAPSHOT-reobf.jar -[bundlerMojmap]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.2/latest/plazma-bundler-1.20.2-R0.1-SNAPSHOT-mojmap.jar +[paperReobf]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.4/latest/plazma-paperclip-1.20.4-R0.1-SNAPSHOT-reobf.jar +[paperMojmap]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.4/latest/plazma-paperclip-1.20.4-R0.1-SNAPSHOT-mojmap.jar +[bundlerReobf]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.4/latest/plazma-bundler-1.20.4-R0.1-SNAPSHOT-reobf.jar +[bundlerMojmap]: https://github.com/PlazmaMC/Plazma/releases/download/build/1.20.4/latest/plazma-bundler-1.20.4-R0.1-SNAPSHOT-mojmap.jar | **Reobf Paperclip (Default)** | Mojmap Paperclip | Reobf Bundler | Mojmap Bundler | |:-----------------------------:|:-----------------------:|:------------------------:|:-------------------------:| -| [Download][paperReobf] | [Download][paperMojmap] | [Download][bundlerReobf] | [Download][bundlerMojmap] | +| Work | In | Progress | !!! | + diff --git a/build.gradle.kts b/build.gradle.kts index f3c0cbe..a032275 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ -import io.papermc.paperweight.util.constants.PAPERCLIP_CONFIG +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent group = "org.plazmamc.plazma" @@ -19,7 +20,7 @@ repositories { mavenCentral() maven("https://papermc.io/repo/repository/maven-public/") { content { - onlyForConfigurations(PAPERCLIP_CONFIG) + onlyForConfigurations(configurations.paperclip.name) } } } @@ -62,7 +63,7 @@ subprojects { withType().configureEach { options.compilerArgs.addAll(listOf("--add-modules=jdk.incubator.vector", "-Xmaxwarns", "1")) options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release = 17 } withType { @@ -74,30 +75,27 @@ subprojects { } withType { - minHeapSize = "2g" - maxHeapSize = "2g" + testLogging { + showStackTraces = true + exceptionFormat = TestExceptionFormat.FULL + events(TestLogEvent.STANDARD_OUT) + } } } repositories { mavenCentral() - maven("https://oss.sonatype.org/content/groups/public/") maven("https://papermc.io/repo/repository/maven-public/") - maven("https://ci.emc.gs/nexus/content/groups/aikar/") - maven("https://repo.aikar.co/content/groups/aikar") - maven("https://repo.md-5.net/content/repositories/releases/") - maven("https://hub.spigotmc.org/nexus/content/groups/public/") maven("https://jitpack.io") - maven("https://oss.sonatype.org/content/repositories/snapshots/") } } paperweight { - serverProject.set(project(":plazma-server")) + serverProject = project(":plazma-server") - remapRepo.set("https://maven.fabricmc.net/") - decompileRepo.set("https://files.minecraftforge.net/maven/") + remapRepo = "https://repo.papermc.io/repository/maven-public/" + decompileRepo = "https://repo.papermc.io/repository/maven-public/" usePaperUpstream(providers.gradleProperty("paperCommit")) { withPaperPatcher { @@ -107,6 +105,13 @@ paperweight { serverPatchDir.set(layout.projectDirectory.dir("patches/server")) serverOutputDir.set(layout.projectDirectory.dir("Plazma-Server")) } + + patchTasks.register("generatedApi") { + isBareDirectory = true + upstreamDirPath = "paper-api-generator/generated" + patchDir = layout.projectDirectory.dir("patches/generated-api") + outputDir = layout.projectDirectory.dir("paper-api-generator/generated") + } } } @@ -125,7 +130,16 @@ tasks { mojangApiCoordinates.set("io.papermc.paper:paper-mojangapi") libraryRepositories.addAll( "https://repo.maven.apache.org/maven2/", + "https://maven.pkg.github.com/PlazmaMC/Plazma", "https://papermc.io/repo/repository/maven-public/" ) } } + +publishing { + publications.create("devBundle") { + artifact(tasks.generateDevelopmentBundle) { + artifactId = "dev-bundle" + } + } +} diff --git a/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PaperUpdateTask.kt b/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PaperUpdateTask.kt index 849b859..e5fd66b 100644 --- a/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PaperUpdateTask.kt +++ b/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PaperUpdateTask.kt @@ -35,10 +35,10 @@ abstract class PaperUpdateTask : Task() { } -fun updatePaperCommit(repo: String, branch: String, properties: File) { +fun updatePaperCommit(repo: String, branch: String, properties: File, regexRule: String = "paperCommit = ") { val latestCommit = Git(properties.parentFile.toPath())("ls-remote", repo).readText()?.lines() ?.filterNot { "[a-z0-9]{40}\trefs/heads/$branch".toRegex().matches(it) }?.first()?.split("\t")?.first() ?: throw AlwaysUpToDateException("Failed to get latest Paper commit") - properties.writeText(properties.readText().replace("paperCommit = .*".toRegex(), "paperCommit = $latestCommit")) + properties.writeText(properties.readText().replace("$regexRule.*".toRegex(), "$regexRule$latestCommit")) } diff --git a/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PurpurUpdateTask.kt b/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PurpurUpdateTask.kt index 444a6dc..848a3d7 100644 --- a/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PurpurUpdateTask.kt +++ b/buildSrc/src/main/kotlin/org/plazmamc/alwaysuptodate/tasks/PurpurUpdateTask.kt @@ -84,7 +84,7 @@ abstract class PurpurUpdateTask : Task() { val pufferfish = git.clone("Pufferfish", property.pufferfishRepository.get(), property.pufferfishBranch.get(), dir) val purpur = git.clone("Purpur", property.purpurRepository.get(), property.purpurBranch.get(), dir) - updatePaperCommit(property.paperRepository.get(), property.paperBranch.get(), pufferfish.resolve("gradle.properties").toFile()) + updatePaperCommit(property.paperRepository.get(), property.paperBranch.get(), pufferfish.resolve("gradle.properties").toFile(), "paperRef=") updatePaperCommit(property.paperRepository.get(), property.paperBranch.get(), purpur.resolve("gradle.properties").toFile()) updatePaperCommit(property.paperRepository.get(), property.paperBranch.get(), project.file("gradle.properties")) @@ -107,6 +107,7 @@ abstract class PurpurUpdateTask : Task() { copySource(paper) Git(paper)("add", ".").executeOut() Git(paper)("commit", "-m", "Vanilla Sources", "--author=Vanilla ").executeOut() + Thread.sleep(1_000) paper.resolve(".git").toFile().copyRecursively(dotGit, overwrite = true) Git(it).addCommit("Pufferfish Server Changes\n\n$pufferfishCommit", "--author=Kevin Raneri ") diff --git a/gradle.properties b/gradle.properties index 98d02f0..886b32e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ -version = 1.20.2-R0.1-SNAPSHOT -mcVersion = 1.20.2 +version = 1.20.4-R0.1-SNAPSHOT +mcVersion = 1.20.4 -paperCommit = 931781c220b98dde0159c9a3c8dce06c3b2b1e13 +paperCommit = 94807a1d2e74b26b1a3154974d4024daa4c95f51 purpurCommit = c46cb7ef66675e00a48e20c40febed7ff914f35d pufferfishCommit = bc89152d4cd4bb0f9644da2fe10774df4cc25661 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 02be563..b0a8f41 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] shadow = "8.1.1" -paperweight = "1.5.10" +paperweight = "1.5.11" paperclip = "3.0.3" decompiler = "2.0.627.2" remapper = "0.3.0:fat" diff --git a/libs/api.versions.toml b/libs/api.versions.toml index 4519023..e012682 100644 --- a/libs/api.versions.toml +++ b/libs/api.versions.toml @@ -5,7 +5,7 @@ guava = "32.1.2-jre" sentry = "5.4.0" fastutil = "8.5.6" findbugs = "1.3.9" -slf4j-api = "1.8.0-beta4" +slf4j-api = "2.0.9" bungeechat = "1.20-R0.1-deprecated+build.14" json-simple = "1.1.1" annotations = "24.0.1" diff --git a/libs/common.versions.toml b/libs/common.versions.toml index 89798d5..ec81036 100644 --- a/libs/common.versions.toml +++ b/libs/common.versions.toml @@ -5,7 +5,7 @@ mockito = "5.5.0" jupiter = "5.10.0" hamcrest = "2.2" snakeyaml = "2.2" -adventure = "4.14.0" +adventure = "4.15.0" commons-lang2 = "2.6" commons-lang3 = "3.12.0" maven-provider = "3.8.5" diff --git a/patches/api/0001-Pufferfish-API-Changes.patch b/patches/api/0001-Pufferfish-API-Changes.patch index aec2e53..39c9227 100644 --- a/patches/api/0001-Pufferfish-API-Changes.patch +++ b/patches/api/0001-Pufferfish-API-Changes.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Kevin Raneri -Date: Sun, 26 Nov 2023 23:32:01 +0000 +Date: Tue, 9 Nov 2021 14:01:56 -0500 Subject: [PATCH] Pufferfish API Changes -Original: Kevin Raneri -Copyright (C) 2023 Pufferfish Studios LLC +Pufferfish +Copyright (C) 2022 Pufferfish Studios LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,18 +20,18 @@ 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 e827ee211e3c65dc68ac5867fd8476639df63645..b9c75a190dbd7a90ac5ef0fbc6e6fe34806acc4e 100644 +index bf01892c248b988531d21d9fb0f74d0adf2205ac..80833c13a2d19e31d6f648e7ef5b3456025e767e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -47,6 +47,7 @@ dependencies { +@@ -51,6 +51,7 @@ dependencies { apiAndDocs("net.kyori:adventure-text-logger-slf4j") api("org.apache.logging.log4j:log4j-api:$log4jVersion") api("org.slf4j:slf4j-api:$slf4jVersion") + api("io.sentry:sentry:5.4.0") // Pufferfish - implementation("org.ow2.asm:asm:9.4") - implementation("org.ow2.asm:asm-commons:9.4") -@@ -106,6 +107,13 @@ val generateApiVersioningFile by tasks.registering { + implementation("org.ow2.asm:asm:9.5") + implementation("org.ow2.asm:asm-commons:9.5") +@@ -109,6 +110,13 @@ val generateApiVersioningFile by tasks.registering { } } @@ -480,7 +480,7 @@ 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 f9b57b872780aa6b9b959494874b57c7a8ff0c53..90953bfc81168068a281be4d2d3942d5e7dd69ff 100644 +index 7e4f7cb2afbc145e532285c793573ad107bc3033..12449e18180d604e9cbbc744da74a8b222a18e1f 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -50,6 +50,8 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm diff --git a/patches/api/0002-Purpur-API-Changes.patch b/patches/api/0002-Purpur-API-Changes.patch index 709798c..596e0af 100644 --- a/patches/api/0002-Purpur-API-Changes.patch +++ b/patches/api/0002-Purpur-API-Changes.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 26 Nov 2023 23:37:25 +0000 +From: granny +Date: Thu, 18 Jan 2024 22:51:24 +0900 Subject: [PATCH] Purpur API Changes -Original: PurpurMC -Copyright (C) 2023 PurpurMC +PurpurMC +Copyright (C) 2024 PurpurMC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -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 b9c75a190dbd7a90ac5ef0fbc6e6fe34806acc4e..41d7b75e904b94073dfcd12b776a7759a963b66f 100644 +index 80833c13a2d19e31d6f648e7ef5b3456025e767e..0a33275fdf16bda47771bab9ddfeb2bf8616c2dc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -126,6 +126,8 @@ tasks.jar { +@@ -129,6 +129,8 @@ tasks.jar { } tasks.withType { @@ -168,29 +168,6 @@ index e801e79fa57c44b2e5d359647c920f88064826f1..1abfcee0f6d632f4cd8d74b4994a90c9 return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS, new ArrayList(TIMINGS_SUBCOMMANDS.size())); } -diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -index 0c4dbb9ef63fa8575b5546239443cb2bd91ba847..b347224c223569297ee67ac630a710fdf28748ea 100644 ---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -@@ -198,6 +198,18 @@ public interface VanillaGoal extends Goal { - GoalKey CLIMB_ON_TOP_OF_POWDER_SNOW = GoalKey.of(Mob.class, NamespacedKey.minecraft("climb_on_top_of_powder_snow")); - GoalKey WOLF_PANIC = GoalKey.of(Wolf.class, NamespacedKey.minecraft("wolf_panic")); - -+ // Purpur start -+ GoalKey MOB_HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider")); -+ GoalKey HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider")); -+ GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider")); -+ GoalKey FIND_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal")); -+ GoalKey ORBIT_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal")); -+ GoalKey DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager")); -+ GoalKey ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager")); -+ GoalKey AVOID_RABID_WOLF = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolf")); -+ GoalKey RECEIVE_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("receive_flower")); -+ // Purpur end -+ - /** - * @deprecated removed in 1.20.2 - */ diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48cc50fad5b 100644 --- a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java @@ -209,10 +186,10 @@ index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48c @Override diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 4863d9f21f0a0f11974be85360edc587ffd7eab3..8ea42a1f07df756bf504609d2bbff578f20bb808 100644 +index 48fab492609e0bae459d20cc2eae78b87e37ab75..109304f8064ab2fab57f9c0f1745e446e6748b3d 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2832,4 +2832,127 @@ public final class Bukkit { +@@ -2842,4 +2842,127 @@ public final class Bukkit { public static Server.Spigot spigot() { return server.spigot(); } @@ -431,10 +408,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 7ca70b269e15e818e61a9329e2775789abb4bc73..aa9ca3e33903747a455ad0949387684ce4b917af 100644 +index f9af60356da4668cec8b24e73f5747ab82e35a91..b304ad1307cdd6785653b1eab9781e070fb14c5a 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -11054,4 +11054,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -11557,4 +11557,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla public boolean isEnabledByFeature(@NotNull World world) { return Bukkit.getDataPackManager().isEnabledByFeature(this, world); } @@ -595,10 +572,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 f1fa97d12f97baf97beb92ca0719cf3cf906b225..dd99f53e3d559685a4b3a454a9e607c310fc6aff 100644 +index 9af4bc16da09e59009c47911219e99450cdf2aa5..529fb1beadefc79ce6bf5755d5223301b9933152 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2190,6 +2190,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2198,6 +2198,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Paper end @@ -617,7 +594,7 @@ index f1fa97d12f97baf97beb92ca0719cf3cf906b225..dd99f53e3d559685a4b3a454a9e607c3 /** * Sends the component to the player * -@@ -2473,4 +2485,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2481,4 +2493,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ boolean isOwnedByCurrentRegion(@NotNull Entity entity); // Paper end - Folia region threading API @@ -724,10 +701,10 @@ index f1fa97d12f97baf97beb92ca0719cf3cf906b225..dd99f53e3d559685a4b3a454a9e607c3 + // Purpur end } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 567a36a4887da8994c9170e2885aa8cc357efa0c..405d60bd2c99ba741d2614b16f4bda5da48a0387 100644 +index bf4b94ea2577e9d7e344385209fc0644a4e6bfbb..eea802fbee51e919595f6501161bf2fd58d6a1c1 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -4235,6 +4235,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -4172,6 +4172,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable public DragonBattle getEnderDragonBattle(); @@ -977,10 +954,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 9e3cb75536ae260dc898ab9dafbc1d98398782bc..ed9627dff9a33524da546c46e1d1be71ae1d1e0c 100644 +index 1d0fd7ff8449f815a7d980af0b378181ea8bf8d8..42b8de355855baecd0a435314909116c210d002d 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1063,4 +1063,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent +@@ -1107,4 +1107,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ @NotNull String getScoreboardEntryName(); // Paper end - entity scoreboard name @@ -1129,10 +1106,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 a599ed2795ba1baf2cbb465d1c7145580c27e1ea..298acbfb93663e40e627f6a47d51fd87a1551feb 100644 +index 47b0154928b3d36e2602da202df07defbcf82108..7498179f6df47008c4da6ad6d67b2ce16f49e7a6 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1243,4 +1243,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -1276,4 +1276,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setBodyYaw(float bodyYaw); // Paper end @@ -1200,10 +1177,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 47fcfa2a3358766dfda2efc9bbcf5b50e3f2f7c1..eea83040ff15ea7c9bf97a45f5557294b309b4c8 100644 +index ae61a39b25267b84fe0b8766e4b12d9b24b44ded..3aa79be25d63f704170baaf799482ccdde6a2830 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3366,4 +3366,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3574,4 +3574,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end @@ -1439,10 +1416,10 @@ index c9f395064656dd0126410eb3c6e197baa450c063..13156a12e5df50cdc1e465dc0bd9d941 * When a player gets bad omen after killing a patrol captain. */ diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java -index cbce826add9dc2b3187c7bea00c27b785d7517df..3a98de6407d9a6307f89c207be1f09e639385ebe 100644 +index daa1306a7324d946d66ad5a674bbc84371d8d4d6..f3b2d7b6fda051211add2b3215f120fb6911aeed 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryType.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -151,7 +151,7 @@ public enum InventoryType { +@@ -165,7 +165,7 @@ public enum InventoryType { SMITHING_NEW(4, "Upgrade Gear"), ; @@ -1471,10 +1448,10 @@ index c60be4fd24c7fdf65251dd6169e5e1ac3b588d95..569deccd2f1cf21da9b5906433ac493c + // 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 +index f680545b6b59bf8d2ad154b0472dda4cba42a162..58a62ba0635f9158bf18043da89aba7521e0e2e1 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 { +@@ -353,4 +353,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 @@ -2149,7 +2126,7 @@ index 36e3fbc727cd748aa138f52976154ba32954cd87..9ecfc504df089a74add168cd5a8376d7 + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java -index 523818cbb0d6c90481ec97123e7fe0e2ff4eea14..bfeb8171a723d84b94bfaacd8aaf7d4d48ecd051 100644 +index db8bcc66bdc4bedfffb4705db6338eda4c0ad29a..feda3ddfaaf37b6ee218a0e0b1fbc199899bd364 100644 --- a/src/main/java/org/bukkit/inventory/RecipeChoice.java +++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java @@ -10,6 +10,7 @@ import java.util.function.Predicate; @@ -2246,10 +2223,10 @@ index 301e82369603f3dd6e6c1bd380da4bacacd7ef6c..0c6ca7588fb3d6b6497ddf032fe75e5c /** * This class was not meant to be constructed explicitly diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -index e4b6f278a811acbb0070e311c5c3bdaff7b00474..ee83ecb054099cb85168a9499dfe967a0a9ec796 100644 +index 653135352c104a6ddeb74a1b6d4916c6952d6271..46b0d02aa759b3735e6ac811523d459cf263aa8b 100644 --- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -@@ -65,6 +65,7 @@ public class LibraryLoader +@@ -66,6 +66,7 @@ public class LibraryLoader @Override public void transferStarted(@NotNull TransferEvent event) throws TransferCancelledException { @@ -2257,7 +2234,7 @@ index e4b6f278a811acbb0070e311c5c3bdaff7b00474..ee83ecb054099cb85168a9499dfe967a logger.log( Level.INFO, "Downloading {0}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName() ); } } ); -@@ -80,6 +81,7 @@ public class LibraryLoader +@@ -81,6 +82,7 @@ public class LibraryLoader { return null; } @@ -2265,7 +2242,7 @@ index e4b6f278a811acbb0070e311c5c3bdaff7b00474..ee83ecb054099cb85168a9499dfe967a logger.log( Level.INFO, "[{0}] Loading {1} libraries... please wait", new Object[] { java.util.Objects.requireNonNullElseGet(desc.getPrefix(), desc::getName), desc.getLibraries().size() // Paper - use configured log prefix -@@ -118,6 +120,7 @@ public class LibraryLoader +@@ -119,6 +121,7 @@ public class LibraryLoader } jarFiles.add( url ); @@ -2274,10 +2251,10 @@ index e4b6f278a811acbb0070e311c5c3bdaff7b00474..ee83ecb054099cb85168a9499dfe967a { java.util.Objects.requireNonNullElseGet(desc.getPrefix(), desc::getName), file // Paper - use configured log prefix diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java -index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf235eba7e89 100644 +index c8ab330ef171795d08fa201cf8320703c7f1c66b..93e2ea220dc03c122f82af65d5e9fda5b582290c 100644 --- a/src/main/java/org/bukkit/potion/PotionEffect.java +++ b/src/main/java/org/bukkit/potion/PotionEffect.java -@@ -32,12 +32,14 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -33,6 +33,7 @@ public class PotionEffect implements ConfigurationSerializable { private static final String AMBIENT = "ambient"; private static final String PARTICLES = "has-particles"; private static final String ICON = "has-icon"; @@ -2285,34 +2262,46 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 private final int amplifier; private final int duration; private final PotionEffectType type; - private final boolean ambient; +@@ -40,6 +41,7 @@ public class PotionEffect implements ConfigurationSerializable { private final boolean particles; private final boolean icon; + private final PotionEffect hiddenEffect; // Paper + @Nullable private final NamespacedKey key; // Purpur /** * Creates a potion effect. -@@ -50,6 +52,36 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -50,11 +52,12 @@ public class PotionEffect implements ConfigurationSerializable { + * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} + * @param particles the particle status, see {@link PotionEffect#hasParticles()} + * @param icon the icon status, see {@link PotionEffect#hasIcon()} ++ * @param key the namespacedKey, see {@link PotionEffect#getKey()} + * @param hiddenEffect the hidden PotionEffect + * @hidden Internal-- hidden effects are only shown internally + */ + @org.jetbrains.annotations.ApiStatus.Internal // Paper +- public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect) { // Paper ++ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect, @Nullable NamespacedKey key) { // Paper // Purpur + Preconditions.checkArgument(type != null, "effect type cannot be null"); + this.type = type; + this.duration = duration; +@@ -62,6 +65,7 @@ public class PotionEffect implements ConfigurationSerializable { + this.ambient = ambient; + this.particles = particles; + this.icon = icon; ++ this.key = key; // Purpur + // Paper start + this.hiddenEffect = hiddenEffect; + } +@@ -77,10 +81,27 @@ public class PotionEffect implements ConfigurationSerializable { * @param icon the icon status, see {@link PotionEffect#hasIcon()} */ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) { -+ // Purpur start -+ this(type, duration, amplifier, ambient, particles, icon, null); -+ } -+ -+ /** -+ * Create a potion effect. -+ * @param duration measured in ticks, see {@link -+ * PotionEffect#getDuration()} -+ * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()} -+ * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} -+ * @param particles the particle status, see {@link PotionEffect#hasParticles()} -+ * @param key the namespacedKey, see {@link PotionEffect#getKey()} -+ */ -+ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, @Nullable NamespacedKey key) { -+ this(type, duration, amplifier, ambient, particles, particles, key); -+ } -+ +- this(type, duration, amplifier, ambient, particles, icon, null); ++ this(type, duration, amplifier, ambient, particles, icon, null, null); // Purpur + // Paper end + } + ++ // Purpur start + /** + * Creates a potion effect. + * @param type effect type @@ -2325,24 +2314,19 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 + * @param key the namespacedKey, see {@link PotionEffect#getKey()} + */ + public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable NamespacedKey key) { -+ // Purpur end - Preconditions.checkArgument(type != null, "effect type cannot be null"); - this.type = type; - this.duration = duration; -@@ -57,6 +89,7 @@ public class PotionEffect implements ConfigurationSerializable { - this.ambient = ambient; - this.particles = particles; - this.icon = icon; -+ this.key = key; // Purpur - add key - } - ++ this(type, duration, amplifier, ambient, particles, icon, null, key); ++ } ++ // Purpur end ++ /** -@@ -104,36 +137,43 @@ public class PotionEffect implements ConfigurationSerializable { + * Creates a potion effect with no defined color. + * +@@ -126,33 +147,33 @@ public class PotionEffect implements ConfigurationSerializable { * @param map the map to deserialize from */ public PotionEffect(@NotNull Map map) { -- this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true))); -+ this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), getKey(map)); // Purpur - getKey +- this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT)); // Paper ++ this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT), getKey(map)); // Paper // Purpur - getKey } // Paper start @@ -2376,6 +2360,10 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 - return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); + return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key } + + /** +@@ -169,6 +190,13 @@ public class PotionEffect implements ConfigurationSerializable { + } // Paper end + // Purpur start @@ -2388,7 +2376,7 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 @NotNull private static PotionEffectType getEffectType(@NotNull Map map) { PotionEffectType effect; -@@ -166,17 +206,33 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -201,6 +229,17 @@ public class PotionEffect implements ConfigurationSerializable { return def; } @@ -2406,35 +2394,28 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 @Override @NotNull public Map serialize() { -- return ImmutableMap.builder() -+ // Purpur start - add key, don't serialize if null. -+ ImmutableMap.Builder builder = ImmutableMap.builder() - .put(TYPE, type.getKey().toString()) - .put(DURATION, duration) - .put(AMPLIFIER, amplifier) - .put(AMBIENT, ambient) - .put(PARTICLES, particles) -- .put(ICON, icon) -- .build(); -+ .put(ICON, icon); -+ if(key != null) { +@@ -215,6 +254,11 @@ public class PotionEffect implements ConfigurationSerializable { + if (this.hiddenEffect != null) { + builder.put(HIDDEN_EFFECT, this.hiddenEffect); + } ++ // Purpur start ++ if (key != null) { + builder.put(KEY, key.toString()); + } -+ return builder.build(); + // Purpur end + return builder.build(); + // Paper end } - - /** -@@ -200,7 +256,7 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -243,7 +287,7 @@ public class PotionEffect implements ConfigurationSerializable { return false; } PotionEffect that = (PotionEffect) obj; -- return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon; -+ return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && this.key == that.key; // Purpur - add key +- return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect); // Paper ++ return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect) && this.key == that.key; // Paper // Purpur - add key } /** -@@ -296,6 +352,24 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -339,6 +383,24 @@ public class PotionEffect implements ConfigurationSerializable { return icon; } @@ -2459,12 +2440,12 @@ index 037af5fd6d71a526c0e6620f2db0cd6df9625261..939ed1931492854c5854cab06730cf23 @Override public int hashCode() { int hash = 1; -@@ -310,6 +384,6 @@ public class PotionEffect implements ConfigurationSerializable { +@@ -354,6 +416,6 @@ public class PotionEffect implements ConfigurationSerializable { @Override public String toString() { -- return type.getName() + (ambient ? ":(" : ":") + duration + "t-x" + amplifier + (ambient ? ")" : ""); -+ return type.getName() + (ambient ? ":(" : ":") + duration + "t-x" + amplifier + (ambient ? ")" : "") + (hasKey() ? "(" + key + ")" : ""); // Purpur - add key if not null +- return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + '}'; // Paper ++ return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + ", key=" + key + '}'; // Paper // Purpur - add key } } diff --git a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/util/permissions/CommandPermissions.java diff --git a/patches/api/0003-Build-system-changes.patch b/patches/api/0003-Build-system-changes.patch index 24a7893..1563af9 100644 --- a/patches/api/0003-Build-system-changes.patch +++ b/patches/api/0003-Build-system-changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Build system changes diff --git a/build.gradle.kts b/build.gradle.kts -index 41d7b75e904b94073dfcd12b776a7759a963b66f..c37b8a63b050dcc2ad2b33955017df48120c4393 100644 +index 0a33275fdf16bda47771bab9ddfeb2bf8616c2dc..dfc2fe81a776acc490189d96c195dea1be7ca690 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,11 +9,13 @@ java { @@ -15,55 +15,59 @@ index 41d7b75e904b94073dfcd12b776a7759a963b66f..c37b8a63b050dcc2ad2b33955017df48 +/* // Plazma - Use libs.versions.toml val annotationsVersion = "24.0.1" val bungeeCordChatVersion = "1.20-R0.1" - val adventureVersion = "4.14.0" - val slf4jVersion = "1.8.0-beta4" + val adventureVersion = "4.15.0" + val slf4jVersion = "2.0.9" val log4jVersion = "2.17.1" + */ // Plazma - Use libs.versions.toml val apiAndDocs: Configuration by configurations.creating { attributes { attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) -@@ -28,15 +30,39 @@ configurations.api { +@@ -28,6 +30,7 @@ configurations.api { dependencies { // api dependencies are listed transitively to API consumers + /* // Plazma - Use libs.versions.toml api("com.google.guava:guava:32.1.2-jre") api("com.google.code.gson:gson:2.10.1") - api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.14") // Paper + // Paper start - adventure +@@ -38,9 +41,35 @@ dependencies { api("org.yaml:snakeyaml:2.2") api("org.joml:joml:1.10.5") -+ */ // Plazma - Use libs.versions.toml // Paper start - api("com.googlecode.json-simple:json-simple:1.1.1") { -+ api(api.jsonsimple) { // Plazma - Use libs.versions.toml - isTransitive = false // includes junit - } + // Plazma start ++ */ + implementation(common.bundles.asm) + + compileOnly(api.findbugs) ++ compileOnly(api.annotations) + compileOnly(common.bundles.maven) + -+ compileOnly(api.annotations) + compileOnlyApi(api.checkerqual) -+ testCompileOnly(api.bundles.annotations) + + testImplementation(common.asm.tree) + testImplementation(common.bundles.test) + testImplementation(common.commons.lang3) + ++ testCompileOnly(api.bundles.annotations) ++ + api(api.bundles.api) + api(common.snakeyaml) + api(common.log4j.api) + api(common.maven.provider) -+ apiAndDocs(platform(common.adventure.bom)) ++ + apiAndDocs(common.bundles.adventure) -+ /* ++ apiAndDocs(platform(common.adventure.bom)) ++ ++ api(api.jsonsimple) { + // Plazma end + isTransitive = false // includes junit + } ++ /* // Plazma - Use libs.versions.toml api("it.unimi.dsi:fastutil:8.5.6") apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion")) apiAndDocs("net.kyori:adventure-api") -@@ -73,6 +99,7 @@ dependencies { +@@ -76,6 +105,7 @@ dependencies { testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.mockito:mockito-core:5.5.0") testImplementation("org.ow2.asm:asm-tree:9.5") @@ -71,7 +75,7 @@ index 41d7b75e904b94073dfcd12b776a7759a963b66f..c37b8a63b050dcc2ad2b33955017df48 } // Paper start -@@ -133,25 +160,27 @@ tasks.withType { +@@ -136,25 +166,27 @@ tasks.withType { options.use() options.isDocFilesSubDirs = true options.links( @@ -108,7 +112,7 @@ index 41d7b75e904b94073dfcd12b776a7759a963b66f..c37b8a63b050dcc2ad2b33955017df48 + "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/${common.log4j.api.orNull?.version}/", // Paper end - "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3", // Paper -+ "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/${common.maven.transport.orNull?.version}", // Paper ++ "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/${common.maven.connector.orNull?.version}", // Paper + // Plazma end ) options.tags("apiNote:a:API Note:") diff --git a/patches/api/0004-Plazma-Configurations.patch b/patches/api/0004-Plazma-Configurations.patch index 87f6199..35ec470 100644 --- a/patches/api/0004-Plazma-Configurations.patch +++ b/patches/api/0004-Plazma-Configurations.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Plazma Configurations diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index dd99f53e3d559685a4b3a454a9e607c310fc6aff..3a3713573ba37530449f9254c0a7205530c9737a 100644 +index 529fb1beadefc79ce6bf5755d5223301b9933152..c78eb34b20ed1a7bf793cfd4594219923c33f66f 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2202,6 +2202,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2210,6 +2210,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Purpur end diff --git a/patches/api/0006-Implement-No-Chat-Reports.patch b/patches/api/0006-Implement-No-Chat-Reports.patch index b21fe38..9f07ae6 100644 --- a/patches/api/0006-Implement-No-Chat-Reports.patch +++ b/patches/api/0006-Implement-No-Chat-Reports.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement No Chat Reports diff --git a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java -index 2eb13c049fa917d41fa9ad17fdec9ec4c33701a8..5d50f83a76affc74f989870ca1bc8d7a75f3b2ba 100644 +index f7f864a2b46129e4d61bc87f3e23c343417aa094..eb3cc41388a210f000bf637bfae135081bee51e9 100644 --- a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java +++ b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java -@@ -215,6 +215,8 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable { +@@ -216,6 +216,8 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable { * Fallback cause */ UNKNOWN, diff --git a/patches/generated-api/0001-Purpur-Generated-API-Changes.patch b/patches/generated-api/0001-Purpur-Generated-API-Changes.patch new file mode 100644 index 0000000..772dcdc --- /dev/null +++ b/patches/generated-api/0001-Purpur-Generated-API-Changes.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: granny +Date: Thu, 18 Jan 2024 21:01:12 +0900 +Subject: [PATCH] Purpur Generated API Changes + +PurpurMC +Copyright (C) 2024 PurpurMC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +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/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/com/destroystokyo/paper/entity/ai/VanillaGoal.java +index 069f2668f5229b0368b796e65eef1648fba0a097..9b991201a2f6cc9feccccf7f4e7bcded64117764 100644 +--- a/com/destroystokyo/paper/entity/ai/VanillaGoal.java ++++ b/com/destroystokyo/paper/entity/ai/VanillaGoal.java +@@ -442,6 +442,18 @@ public interface VanillaGoal extends Goal { + + GoalKey ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); + ++ // Purpur start ++ GoalKey MOB_HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider")); ++ GoalKey HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider")); ++ GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider")); ++ GoalKey FIND_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal")); ++ GoalKey ORBIT_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal")); ++ GoalKey DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager")); ++ GoalKey ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager")); ++ GoalKey AVOID_RABID_WOLF = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolf")); ++ GoalKey RECEIVE_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("receive_flower")); ++ // Purpur end ++ + /** + * Removed in 1.20.2 + */ diff --git a/patches/server/0001-Pufferfish-Server-Changes.patch b/patches/server/0001-Pufferfish-Server-Changes.patch index ed2b980..f225b9b 100644 --- a/patches/server/0001-Pufferfish-Server-Changes.patch +++ b/patches/server/0001-Pufferfish-Server-Changes.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Kevin Raneri -Date: Sat, 25 Nov 2023 11:51:41 +0000 +Date: Thu, 18 Jan 2024 22:51:22 +0900 Subject: [PATCH] Pufferfish Server Changes -Original: Kevin Raneri -Copyright (C) 2023 Pufferfish Studios LLC +Pufferfish +Copyright (C) 2024 Pufferfish Studios LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ 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 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f97416864115f75ed5 100644 +index 444ff797c70b0e285d4272ea2ce3d72453c9bda5..fd785a79b1708aadd760f5b62d49d4d4e55e9938 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { @@ -38,9 +38,9 @@ index 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f974168641 // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -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") +@@ -50,6 +54,13 @@ dependencies { + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") + // Pufferfish start + implementation("org.yaml:snakeyaml:1.32") @@ -52,10 +52,10 @@ index 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f974168641 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") -@@ -58,6 +69,14 @@ dependencies { +@@ -57,6 +68,14 @@ dependencies { } - val craftbukkitPackageVersion = "1_20_R2" // Paper + val craftbukkitPackageVersion = "1_20_R3" // Paper + +// Pufferfish Start +tasks.withType { @@ -67,7 +67,7 @@ index 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f974168641 tasks.jar { archiveClassifier.set("dev") -@@ -70,7 +89,7 @@ tasks.jar { +@@ -69,7 +88,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -76,7 +76,7 @@ index 64479f0a892d6847f987d844efe282a6080d607b..9525f76103136dfc900c70f974168641 "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -210,7 +229,5 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> +@@ -209,7 +228,5 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> } tasks.registerRunTask("runDev") { description = "Spin up a non-relocated Mojang-mapped test server" @@ -625,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..cc66657cb4f978aa2df3ca1be6c683759952cc7a +index 0000000000000000000000000000000000000000..61f21c0bf6658326a15b735c22001b4028b98800 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -@@ -0,0 +1,294 @@ +@@ -0,0 +1,315 @@ +package gg.pufferfish.pufferfish; + +import gg.pufferfish.pufferfish.simd.SIMDDetection; @@ -811,6 +811,28 @@ index 0000000000000000000000000000000000000000..cc66657cb4f978aa2df3ca1be6c68375 + "disabling this option.", + "This can be overridden per-player with the permission pufferfish.usebooks"); + } ++ ++ public static boolean tpsCatchup; ++ private static void tpsCatchup() { ++ tpsCatchup = getBoolean("tps-catchup", true, ++ "If this setting is true, the server will run faster after a lag spike in", ++ "an attempt to maintain 20 TPS. This option (defaults to true per", ++ "spigot/paper) can cause mobs to move fast after a lag spike."); ++ } ++ ++ public static boolean enableAsyncWorldSaving; ++ public static boolean asyncWorldSavingInitialized; ++ private static void asyncWorldSaving() { ++ boolean temp = getBoolean("enable-async-world-saving", false, ++ "Save world changes asynchronously. This is disabled by default as it is not", ++ "100% confident that this will not cause world corruption issues."); ++ ++ // This prevents us from changing the value during a reload. ++ if (!asyncWorldSavingInitialized) { ++ asyncWorldSavingInitialized = true; ++ enableAsyncWorldSaving = temp; ++ } ++ } + + public static boolean enableSuffocationOptimization; + private static void suffocationOptimization() { @@ -913,7 +935,6 @@ index 0000000000000000000000000000000000000000..cc66657cb4f978aa2df3ca1be6c68375 + "the ender dragon whenever a player places an end crystal."); + } + -+ + public static boolean disableMethodProfiler; + public static boolean disableOutOfOrderChat; + private static void miscSettings() { @@ -1464,10 +1485,10 @@ index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f549 + } +} diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 8240bb085b619f257f8c0a25775e0b15068e440f..6d9668d993bb922ae9d2b76a4d766903cc3f98a4 100644 +index 200ed770b57e1a9240abf0473968d4b85cbefe3c..0acc7cfc0fb0264dd76a58f7582e79d83fa040eb 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 { +@@ -212,7 +212,7 @@ public final class MCUtil { } public static long getCoordinateKey(final Entity entity) { @@ -1476,11 +1497,24 @@ index 8240bb085b619f257f8c0a25775e0b15068e440f..6d9668d993bb922ae9d2b76a4d766903 } public static long getCoordinateKey(final ChunkPos pair) { +diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +index 85a8a687b1568a56e3e646b37ef78b562c1b8a82..69971b2c59e541ac4100b84c84e2972de1b44ca9 100644 +--- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java ++++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +@@ -38,7 +38,7 @@ public class SignedMessageChain { + throw new SignedMessageChain.DecodeException(Component.translatable("chat.disabled.chain_broken"), false); // Paper - diff on change (if disconnects, need a new kick event cause) + } else if (playerPublicKey.data().hasExpired()) { + throw new SignedMessageChain.DecodeException(Component.translatable("chat.disabled.expiredProfileKey", org.bukkit.event.player.PlayerKickEvent.Cause.EXPIRED_PROFILE_PUBLIC_KEY), false); // Paper - kick event causes +- } else if (body.timeStamp().isBefore(this.lastTimeStamp)) { ++ } else if (!gg.pufferfish.pufferfish.PufferfishConfig.disableOutOfOrderChat && body.timeStamp().isBefore(this.lastTimeStamp)) { // Pufferfish + throw new SignedMessageChain.DecodeException(Component.translatable("multiplayer.disconnect.out_of_order_chat", org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT), true); // Paper - kick event causes + } else { + this.lastTimeStamp = body.timeStamp(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90 100644 +index 016b7628b289fb882f3ec15dd5b0cb4e0af72edc..1343649cd77a42dd502747581050b401840a6efe 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -308,6 +308,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1697,7 +1699,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop needsChangeBroadcasting = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); @@ -1540,7 +1587,7 @@ index caa73632aee15583c6b6ed12a668c8f49b794708..3abec84383a445d3ad0d3b5f613246b6 // 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) { -@@ -1464,8 +1464,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1458,8 +1458,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return ChunkMap.this.level.getServer().getScaledTrackingDistance(initialDistance); } @@ -1569,7 +1616,7 @@ index caa73632aee15583c6b6ed12a668c8f49b794708..3abec84383a445d3ad0d3b5f613246b6 Iterator iterator = this.entity.getIndirectPassengers().iterator(); while (iterator.hasNext()) { -@@ -1477,6 +1497,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1471,6 +1491,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider i = j; } } @@ -1580,10 +1627,10 @@ index caa73632aee15583c6b6ed12a668c8f49b794708..3abec84383a445d3ad0d3b5f613246b6 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 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..5d26364c0f4ed03bd9994077683c93b9883e5327 100644 +index 44ada45d9bf2d9b48e5de1c3cb1a855902f3884b..5cf74fe0214191d42e74fc104eba150a95894e0f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -75,6 +75,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -73,6 +73,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]; @@ -1594,77 +1641,57 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..5d26364c0f4ed03bd9994077683c93b9 private static int getChunkCacheKey(int x, int z) { return x & 3 | ((z & 3) << 2); @@ -521,6 +524,7 @@ public class ServerChunkCache extends ChunkSource { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - gameprofilerfiller.push("pollingChunks"); + // Paper - optimise chunk tick iteration + + 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 -- // re-set mob counts -- for (ServerPlayer player : this.level.players) { -- // Paper start - per player mob spawning backoff -- for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { -- player.mobCounts[ii] = 0; -- -- int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? -- if (newBackoff < 0) { -- newBackoff = 0; -+ // Pufferfish start - moved down when async processing -+ if (!gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) { -+ // re-set mob counts -+ for (ServerPlayer player : this.level.players) { -+ // Paper start - per player mob spawning backoff -+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { -+ player.mobCounts[ii] = 0; -+ -+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? -+ if (newBackoff < 0) { -+ newBackoff = 0; -+ } -+ player.mobBackoffCounts[ii] = newBackoff; + if (this.level.getServer().tickRateManager().runsNormally()) { + gameprofilerfiller.popPush("naturalSpawnCount"); + this.level.timings.countNaturalMobs.startTiming(); // Paper - timings +@@ -529,6 +533,7 @@ public class ServerChunkCache extends ChunkSource { + int naturalSpawnChunkCount = k; + 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 ++ if (!gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) { // Pufferfish - moved down when async processing + // re-set mob counts + for (ServerPlayer player : this.level.players) { + // Paper start - per player mob spawning backoff +@@ -543,14 +548,18 @@ public class ServerChunkCache extends ChunkSource { } -- player.mobBackoffCounts[ii] = newBackoff; -+ // Paper end - per player mob spawning backoff + // Paper end - per player mob spawning backoff } -- // Paper end - per player mob spawning backoff -+ lastSpawnState = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, null, true); +- spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); ++ lastSpawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); // Pufferfish - async mob spawning ++ } // Pufferfish - (endif) moved down when async processing + } else { +- spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); ++ // Pufferfish start - async mob spawning ++ lastSpawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); ++ _pufferfish_spawnCountsReady.set(true); ++ // Pufferfish end } -- spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, null, true); -+ // 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 -+ 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 - } - // Paper end - this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings + // Paper end + this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings -- this.lastSpawnState = spawnercreature_d; -+ //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously - gameprofilerfiller.popPush("filteringLoadedChunks"); - // Paper - optimise chunk tick iteration - // Paper - optimise chunk tick iteration -@@ -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); -- if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration -- NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); -+ if (spawn && flag2 && (!gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning || _pufferfish_spawnCountsReady.get()) && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration // Pufferfish -+ NaturalSpawner.spawnForChunk(this.level, chunk1, lastSpawnState, this.spawnFriendlies, this.spawnEnemies, flag1); // Pufferfish - } +- this.lastSpawnState = spawnercreature_d; ++ // this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously + gameprofilerfiller.popPush("spawnAndTick"); + boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit - if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration -@@ -691,6 +702,40 @@ public class ServerChunkCache extends ChunkSource { +@@ -640,8 +649,8 @@ public class ServerChunkCache extends ChunkSource { + if (tick && chunk1.chunkStatus.isOrAfter(net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING)) { + // Paper end - optimise chunk tick iteration + chunk1.incrementInhabitedTime(j); +- if (spawn && flag && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration +- NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); ++ if (spawn && flag && (!gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning || _pufferfish_spawnCountsReady.get()) && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration // Pufferfish ++ NaturalSpawner.spawnForChunk(this.level, chunk1, lastSpawnState, this.spawnFriendlies, this.spawnEnemies, flag1); // Pufferfish + } + + if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration +@@ -688,6 +697,40 @@ public class ServerChunkCache extends ChunkSource { + gameprofilerfiller.pop(); gameprofilerfiller.pop(); - this.chunkMap.tick(); } + + // Pufferfish start - optimize mob spawning @@ -1704,7 +1731,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..5d26364c0f4ed03bd9994077683c93b9 private void getFullChunk(long pos, Consumer chunkConsumer) { diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 35674f92a67f93382103c2766df4b678ba5c862f..d46e61640b241d32df05240dedd2c23f138725e6 100644 +index b6e5a2fa247bdee2f681739a26630dff3fc6c51a..e385a62058204ba3b01ce594e7c180f9cc6cf664 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -177,7 +177,8 @@ public class ServerEntity { @@ -1726,10 +1753,10 @@ 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 c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b68f6d494f 100644 +index e0dae41eb94da08649cba607975798dc2ac328ad..f7215d0a67e9e024af0c040c796ebcbb4f76e885 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 { +@@ -899,6 +899,7 @@ public class ServerLevel extends Level implements WorldGenLevel { org.spigotmc.ActivationRange.activateEntities(this); // Spigot this.timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { @@ -1737,7 +1764,7 @@ index c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b6 if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); -@@ -897,7 +898,20 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -918,7 +919,20 @@ public class ServerLevel extends Level implements WorldGenLevel { } gameprofilerfiller.push("tick"); @@ -1759,7 +1786,7 @@ index c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b6 gameprofilerfiller.pop(); } } -@@ -962,9 +976,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -983,9 +997,11 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); @@ -1772,7 +1799,7 @@ index c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b6 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 { +@@ -996,7 +1012,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 @@ -1781,11 +1808,44 @@ index c88d5b9125f6ee43bf2be60fd1745d836f271b78..945783d090e44ebed1d4968c1d1ec0b6 blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper if (this.isRainingAt(blockposition)) { +@@ -1491,7 +1507,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + + try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { + if (doFull) { +- this.saveLevelData(); ++ this.saveLevelData(true); // Pufferfish + } + + this.timings.worldSaveChunks.startTiming(); // Paper +@@ -1527,7 +1543,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); + } + +- this.saveLevelData(); ++ this.saveLevelData(!close); // Pufferfish + if (progressListener != null) { + progressListener.progressStage(Component.translatable("menu.savingChunks")); + } +@@ -1550,12 +1566,12 @@ public class ServerLevel extends Level implements WorldGenLevel { + // CraftBukkit end + } + +- private void saveLevelData() { ++ private void saveLevelData(boolean async) { // Pufferfish + if (this.dragonFight != null) { + this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit + } + +- this.getChunkSource().getDataStorage().save(); ++ this.getChunkSource().getDataStorage().save(async); // Pufferfish + } + + public List getEntities(EntityTypeTest filter, Predicate predicate) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 65bb221993147a558995b36fb835f7b82e0eb4bd..6cc9271ba058f4af759eae34e2f6e9f892b4f6da 100644 +index 8568de90c39838e1627f286c5c3ca4b0f19002cb..04b0eb391bb524dd7af14b862d89c0f2494a8206 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1119,6 +1119,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1124,6 +1124,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleEditBook(ServerboundEditBookPacket packet) { @@ -1793,14 +1853,19 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..6cc9271ba058f4af759eae34e2f6e9f8 // Paper start if (!this.cserver.isPrimaryThread()) { List pageList = packet.getPages(); -@@ -2274,6 +2275,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } +diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +index f2a7cb6ebed7a4b4019a09af2a025f624f6fe9c9..47636aad5fa20d1c28d3520beb0729df9b30cf6c 100644 +--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java ++++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +@@ -224,7 +224,7 @@ public class WorldUpgrader { + } + } - private boolean updateChatOrder(Instant timestamp) { -+ if (gg.pufferfish.pufferfish.PufferfishConfig.disableOutOfOrderChat) return true; - Instant instant1; - - do { +- this.overworldDataStorage.save(); ++ this.overworldDataStorage.save(false); // Pufferfish + i = Util.getMillis() - i; + WorldUpgrader.LOGGER.info("World optimizaton finished after {} ms", i); + this.finished = true; 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 @@ -1914,10 +1979,10 @@ index d6cbe98e67fdbf8db46338a88ab1356dd63b50a3..20dd3a63b2f955b05a75eb240e33ae4c 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 fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0bf55da454 100644 +index 14fbaef2215f7de4acb5303ad6f677b348f855d8..a8d8d261daed2ebbbea3f4f356434942997ba541 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -306,7 +306,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -309,7 +309,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public double yo; public double zo; private Vec3 position; @@ -1926,7 +1991,7 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b private ChunkPos chunkPosition; private Vec3 deltaMovement; private float yRot; -@@ -434,6 +434,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -440,6 +440,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return this.originWorld; } // Paper end @@ -1939,7 +2004,7 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b public float getBukkitYaw() { return this.yRot; } -@@ -798,6 +804,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -808,6 +814,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } public void tick() { @@ -1952,7 +2017,7 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b this.baseTick(); } -@@ -4362,16 +4374,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4410,16 +4422,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { @@ -1978,7 +2043,7 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b double d1 = 0.0D; boolean flag = this.isPushedByFluid(); boolean flag1 = false; -@@ -4379,14 +4393,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4427,14 +4441,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S int k1 = 0; BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); @@ -2046,7 +2111,7 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b if (d2 >= axisalignedbb.minY) { flag1 = true; -@@ -4408,9 +4469,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4456,9 +4517,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // CraftBukkit end } } @@ -2060,10 +2125,10 @@ index fece91254b10b59474056aa730fd420f90cd7bec..80c9a523e94704f73e833e2255af6b0b if (vec3d.length() > 0.0D) { if (k1 > 0) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 73871f456a85bda1e51f54986d0e61fb629822e8..2561e74ffdf595a9b6ae13dcd738662c772db442 100644 +index 081937597a8984b52a1e92d4c6032c04c942116e..0ffd377dba738bd651b0c7f5ca0a0d61aaa1d82c 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -301,6 +301,8 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -305,6 +305,8 @@ public class EntityType implements FeatureElement, EntityTypeT private final boolean canSpawnFarFromPlayer; private final int clientTrackingRange; private final int updateInterval; @@ -2073,7 +2138,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 15e1d8c09fad181406a6acb8b3f177cd5e6c0f52..3b9ee3324a084271862ed790e8fc0d469e877ec1 100644 +index 4cbb1f5d904191e59395df0177e76e94faae764c..9b7e786d5ae6bdeeb96df6e9c4d1b24e1e856e58 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; @@ -2084,7 +2149,7 @@ index 15e1d8c09fad181406a6acb8b3f177cd5e6c0f52..3b9ee3324a084271862ed790e8fc0d46 public abstract class LivingEntity extends Entity implements Attackable { -@@ -414,7 +413,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -413,7 +412,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = this instanceof net.minecraft.world.entity.player.Player; if (!this.level().isClientSide) { @@ -2113,7 +2178,7 @@ index 15e1d8c09fad181406a6acb8b3f177cd5e6c0f52..3b9ee3324a084271862ed790e8fc0d46 @Override public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { -@@ -2004,6 +2016,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2002,6 +2014,20 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.lastClimbablePos; } @@ -2135,10 +2200,10 @@ index 15e1d8c09fad181406a6acb8b3f177cd5e6c0f52..3b9ee3324a084271862ed790e8fc0d46 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 956d05e2ae59978ea9623ca0e167c0afe0b87306..944c22ea172796492a683d2f2bddfb0938d7a8c9 100644 +index 0b5334004b9d0489e8465824870662b467ce321b..2f3dc569ff9cdead48aa831c96c027cc7255d609 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 { +@@ -221,14 +221,16 @@ public abstract class Mob extends LivingEntity implements Targeting { return this.lookControl; } @@ -2157,7 +2222,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..944c22ea172796492a683d2f2bddfb09 this.targetSelector.tick(); } } -@@ -911,16 +913,20 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -912,16 +914,20 @@ public abstract class Mob extends LivingEntity implements Targeting { if (i % 2 != 0 && this.tickCount > 1) { this.level().getProfiler().push("targetSelector"); @@ -2245,7 +2310,7 @@ index b738ee2d3801fadfd09313f05ae24593e56b0ec6..1635818fc4b1788c0d397085239df6dd public boolean hasTasks() { for (WrappedGoal task : this.availableGoals) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -index 34f319ad09276c6f68dde449c79351de0d7d86f5..a719af0b512d9ef243d0d54f3b744b1b1a5f2772 100644 +index 4bbc36404b396500df0d9db380cf223b5897662e..382e9d18b81bcbeb20cb3b828b66260f07a845e6 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java @@ -119,6 +119,7 @@ public abstract class MoveToBlockGoal extends Goal { @@ -2282,10 +2347,10 @@ index c157309ac78e7af084d3acb6e8b2bcd469a39d5e..ac5e5676b194a2a99e5cf53eb89c1152 return false; } diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index 5beaa849a250ea005733250ad3edfa8382224667..2c91fe46355c9a201507de5577f693ed4f5fb974 100644 +index 6b614818b14ecfc8fc82b523eeb7e21fdf9bf1ba..8820905ac733a8915cc1697259b2bef14d97e471 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -237,13 +237,22 @@ public class Bat extends AmbientCreature { +@@ -241,13 +241,22 @@ public class Bat extends AmbientCreature { } } @@ -2326,10 +2391,10 @@ 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 d5b97d4316390028f54aa9bb9fa52b0b003e32a0..b4793b88688bd568a428aa520e880f0038de45a7 100644 +index 387006271c246362b0df1bfcadca7b7096660003..9158c5a507904c46a8fe2fdad9a0b6ba3a9b2460 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 { - return true; +@@ -159,9 +159,11 @@ public class Frog extends Animal implements VariantHolder { + } + private int behaviorTick = 0; // Pufferfish @@ -2390,7 +2455,7 @@ index 111a244087e24f25ba8524a46a228da10cd9498a..ff12ba2b79cb2e7e0bfd0e3b58ff6cb9 this.level().getProfiler().pop(); this.level().getProfiler().push("goatActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index c9a4feb4a52c0eb621b120e5b8c18d0a74dae0cd..256598e058db1fd34d36390e45ab9903768343cb 100644 +index 68ecf0203e23cb6360d05bec18d9c1c413d84650..1f7f6e5995c00725bf66723c75620ec416e24f87 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java @@ -150,6 +150,13 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @@ -2408,7 +2473,7 @@ index c9a4feb4a52c0eb621b120e5b8c18d0a74dae0cd..256598e058db1fd34d36390e45ab9903 protected SoundEvent getAmbientSound() { return SoundEvents.WITHER_AMBIENT; 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 bd5996eef2d946e9d7765b6b315bc5951158810e..0d51f435f18f3f9d59a3241a0b7fa1c4af841b72 100644 +index 30627f330536b5c89b52452981f0a960b61e4268..ebbd0031da656c4b12debbf76a347da2865d50d1 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java @@ -333,11 +333,17 @@ public class EnderMan extends Monster implements NeutralMob { @@ -2464,10 +2529,10 @@ index 6407ddef8442fce4f310ac4babf3e3de0dd5fc9a..cfdc1650783d6855e0d4f33ec68aab48 this.level().getProfiler().pop(); PiglinAi.updateActivity(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -index b2bc3a832c310448046ccde37a04918aa6d63197..5e43912708f9074dee1bb351efa737a7e6796fc3 100644 +index 9f1b7c629644931074293151ed58a523ca6d488c..58a7e61e02b7d72326ed4d57ee514adb63b3873c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -@@ -272,11 +272,13 @@ public class Warden extends Monster implements VibrationSystem { +@@ -273,11 +273,13 @@ public class Warden extends Monster implements VibrationSystem { } @@ -2482,7 +2547,7 @@ index b2bc3a832c310448046ccde37a04918aa6d63197..5e43912708f9074dee1bb351efa737a7 this.level().getProfiler().pop(); super.customServerAiStep(); 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 cbe2a37f74f4fb2abd0b3297699e54335aaed64f..2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f 100644 +index e12f1f11386fa723f62b51ed0cc5715c1812d2bf..1e6d61673b0e3252129c04edcfa1d7d436e8ecbe 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 @@ -2516,7 +2581,7 @@ index cbe2a37f74f4fb2abd0b3297699e54335aaed64f..2460768aaa7b8e6d183c03c1f0f2ccd6 if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index 96d664c28738d6090f7067761c2978dd1aa0fd0e..b1c24a02b87aca7b180a6efbce177f2300db49c1 100644 +index 309acf7bd07e38043aa81e0e686edba1136bd04c..deabb3400ee2406a8ec179a96d8cfd86f8edbbd6 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java @@ -687,6 +687,8 @@ public class Inventory implements Container, Nameable { @@ -2548,10 +2613,10 @@ index 96d664c28738d6090f7067761c2978dd1aa0fd0e..b1c24a02b87aca7b180a6efbce177f23 return false; } diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index a90317100d32974e481e14476843f66997a2cf3a..cd0629581bae5f805842157af36c2d838e01bee3 100644 +index 5b6d5c799cc8e601a01b6967917e15ba1e2db721..f0a6251cc8f612b898231e505c47fd5b2bbb4973 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -44,6 +44,36 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -45,6 +45,36 @@ public abstract class Projectile extends Entity implements TraceableEntity { super(type, world); } @@ -2589,7 +2654,7 @@ index a90317100d32974e481e14476843f66997a2cf3a..cd0629581bae5f805842157af36c2d83 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 +index 6d23c39e4eadf23616080d6d08672e13b5d3c37d..e7115f1635821e0aab32e8aeea6914388dc24639 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; @@ -2636,7 +2701,7 @@ index 00187fbbeddfc17e1b6887f8bf0f50da23938470..f64edfdb03f99624daf1e05b5dc86d84 } 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 +index e1696f6b77df4c8fceaece64701d4db78b0a4c42..faa3f62d22266a3c32d6c95c3ffebd4aa3880739 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java +++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -55,7 +55,7 @@ public class EndCrystalItem extends Item { @@ -2645,11 +2710,11 @@ index 5a19875cbc603acea95193d969d2e1dc1e0bfd78..3688e9f8c6c6d1239095e3a87060ccca - if (enderdragonbattle != null) { + if (enderdragonbattle != null && gg.pufferfish.pufferfish.PufferfishConfig.allowEndCrystalRespawn) { // Pufferfish - enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - pass placed end crystal position to pre-check proximity to portal + enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup } } 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..252fc22844682c0f67dc02a87478e01e49b6430d 100644 +index 27b0a79f7a7c47047216aae42944bac2a2151181..a097cfc528f709c80575f35483b6878314ea2717 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,13 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo @@ -2696,19 +2761,19 @@ index 38f7d1ece27ec1a3deda21fb6a6f0e788c8ed718..252fc22844682c0f67dc02a87478e01e 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 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..99e1c645871be28d130319b65700a1b8db093de4 100644 +index b05e11e6b091c7616df5a9bbef867b06cafe3dc3..2902c29cd7f0b99b84cff3664fc4ec15a383e41b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -210,6 +210,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -212,6 +212,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Paper end 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 + + 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 - create paper world config; 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 { +@@ -1318,13 +1320,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick @@ -2724,7 +2789,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..99e1c645871be28d130319b65700a1b8 // Paper end } } -@@ -1779,6 +1781,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1798,6 +1800,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { @@ -2733,7 +2798,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..99e1c645871be28d130319b65700a1b8 } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 3cdddda9c0618e95288b81b975d499c8dd30c05f..9c2d62feff1816f5729060c6192269a5b2d34153 100644 +index dc211c6aedc178ac50b7d05aab3662c422211cbd..3fb96de68b93e8d33bd5ab9137e5d4facc94d788 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 { @@ -2754,7 +2819,7 @@ index 3cdddda9c0618e95288b81b975d499c8dd30c05f..9c2d62feff1816f5729060c6192269a5 return new BlockPos(i, l, j); } 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 65012a12e1430956ef55ced56773e6354ac26444..ed439b7e94646141c93a7dd3704d1cdeb5c27e16 100644 +index 4f9187d9d640618c40a2fa528f36b845017b4777..efca73d4de33028cf9df944f36e51b7b50f7a4c5 100644 --- a/src/main/java/net/minecraft/world/level/biome/Biome.java +++ b/src/main/java/net/minecraft/world/level/biome/Biome.java @@ -66,14 +66,20 @@ public final class Biome { @@ -2881,7 +2946,7 @@ index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f @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 +index df1c1c27b7c0065f8179d59bdb9de01dde22befa..1ddae39df4e7cb36db412ebdec8ca9d2818450a9 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 @@ -2940,23 +3005,22 @@ index d4dcf7fe26474ae07374e7761d823bc5c8b54f97..1d13fabb3f34023b4fbb1be9ad02ebc6 private static boolean isFullContainer(Container inventory, Direction direction) { + if (true) return inventory.isCompletelyFull(direction); // Pufferfish - use bitsets - // Paper start - optimize hoppers + // Paper start - Perf: Optimize Hoppers if (inventory instanceof WorldlyContainer worldlyContainer) { for (final int slot : worldlyContainer.getSlotsForFace(direction)) { -@@ -513,7 +540,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -513,7 +540,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } private static boolean isEmptyContainer(Container inv, Direction facing) { -- return allMatch(inv, facing, IS_EMPTY_TEST); -+ // Paper start +- return allMatch(inv, facing, IS_EMPTY_TEST); // Paper - Perf: Optimize Hoppers + // Pufferfish start - use bitsets -+ //return allMatch(inv, facing, IS_EMPTY_TEST); ++ //return allMatch(inv, facing, IS_EMPTY_TEST); // Paper - Perf: Optimize Hoppers + return inv.isCompletelyEmpty(facing); + // Pufferfish end } public static boolean suckInItems(Level world, Hopper hopper) { -@@ -713,7 +744,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -713,7 +743,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (HopperBlockEntity.canPlaceItemInContainer(to, stack, slot, side)) { boolean flag = false; @@ -2965,7 +3029,7 @@ index d4dcf7fe26474ae07374e7761d823bc5c8b54f97..1d13fabb3f34023b4fbb1be9ad02ebc6 if (itemstack1.isEmpty()) { // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem -@@ -908,7 +939,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -908,7 +938,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @Override protected void setItems(NonNullList list) { @@ -2978,13 +3042,13 @@ index d4dcf7fe26474ae07374e7761d823bc5c8b54f97..1d13fabb3f34023b4fbb1be9ad02ebc6 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 +index a94300a457b25f0e33a8eeabba6dd5720ca9ab1e..b41635dd0569ff7df909df492d3e850aef7214be 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 +@@ -94,12 +94,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc public boolean isEmpty() { this.unpackLootTable((Player)null); - // Paper start + // Paper start - Perf: Optimize Hoppers - for (final ItemStack itemStack : this.getItems()) { - if (!itemStack.isEmpty()) { - return false; @@ -2992,11 +3056,11 @@ index 3e638f12956e57548f76c7e2403ba370f7baa249..02364a148b347e3669275553004391e3 - } - return true; + return this.isCompletelyEmpty(null); // Pufferfish - use super - // Paper end + // Paper end - Perf: Optimize Hoppers } 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 +index 27e8ee4507460b1cc72de692b41562b9f4f13929..1afac69b5bc7055d2adb07aea4755b87b246275c 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 { @@ -3028,7 +3092,7 @@ index fa170cc1ce7011d201295b89718292d696c7fc24..7fd68d4aba72b15b2e21e5c88b44e677 // 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 +index 9da74764a91bea7822c0444b48623b23e038d3f2..37228dc74463dddcc55301489c41aa253017f2d4 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -25,6 +25,7 @@ public class LevelChunkSection { @@ -3165,6 +3229,57 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af return flag; } +diff --git a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java +index 697df9a9f050c0130246ce2b08a859965bddf184..6df6a6bd89979bcd728e2f5bec948437d6ff9498 100644 +--- a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java ++++ b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java +@@ -29,17 +29,28 @@ public abstract class SavedData { + return this.dirty; + } + +- public void save(File file) { ++ public void save(File file) { save(file, false); } // Pufferfish ++ public void save(File file, boolean async) { // Pufferfish + if (this.isDirty()) { + CompoundTag compoundTag = new CompoundTag(); + compoundTag.put("data", this.save(new CompoundTag())); + NbtUtils.addCurrentDataVersion(compoundTag); + ++ // Pufferfish start ++ Runnable writeRunnable = () -> { + try { + NbtIo.writeCompressed(compoundTag, file.toPath()); + } catch (IOException var4) { + LOGGER.error("Could not save data {}", this, var4); + } ++ }; ++ ++ if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncWorldSaving && async) { ++ net.minecraft.Util.ioPool().execute(writeRunnable); ++ } else { ++ writeRunnable.run(); ++ } ++ // Pufferfish end + + this.setDirty(false); + } +diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +index d051e8c1db6b5c42b8df0be54d9d48ba0e7b0077..6488a61bb05b0f2af23c77bc6df7c3014042ec5e 100644 +--- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java ++++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +@@ -118,10 +118,10 @@ public class DimensionDataStorage { + return bl; + } + +- public void save() { ++ public void save(boolean async) { // Pufferfish + this.cache.forEach((id, state) -> { + if (state != null) { +- state.save(this.getDataFile(id)); ++ state.save(this.getDataFile(id), async); // Pufferfish + } + + }); diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java b/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java index e43d07ccdd36f0c9f5b8e9c74cf0d87e17eec66a..8e441f7c2b2d911a0c0111aaa231fc6adae08730 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java @@ -3269,10 +3384,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 356107688a5d40d1c462b164f61af82f4dfd3926..2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2 100644 +index 9ef8f911632598fd589368cedde268c8abcad3b6..cfc41926305441cb36ed67a8cb7e327cd80ff301 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -269,7 +269,7 @@ import javax.annotation.Nullable; // Paper +@@ -264,7 +264,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -3281,7 +3396,7 @@ index 356107688a5d40d1c462b164f61af82f4dfd3926..2ecb8bfd98c141e9f5e7f4e441c8df91 private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -1124,6 +1124,11 @@ public final class CraftServer implements Server { +@@ -1120,6 +1120,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." )); @@ -3306,10 +3421,10 @@ index 96d772eb02f79f8c478f5e6f065e387aa7665b18..c5ce412f321b8b4f31cc042893659e21 } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 548c77592a3520e8053483644eba805079a14f1a..397c10f64db3a4d7296fe18585b56851bc3a1f01 100644 +index ec2396f0e5d62b10450eaa7239a8c5479638b3c3..c909efd2060dc95bd3ecb8c9fec36a1e69a642ff 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -485,7 +485,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -482,7 +482,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { @@ -3332,7 +3447,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 59103744ac6beeb12719fdefcda54eeff498229e..c0333ba8e57cd284bb8ab15181da6b39d55872f9 100644 +index 2d31752478636bd21bbff5b430e5acb76b5d91c2..651063863b451d24ffe39f0a4d8db296e58ff585 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; @@ -3391,8 +3506,8 @@ index 59103744ac6beeb12719fdefcda54eeff498229e..c0333ba8e57cd284bb8ab15181da6b39 if ( entity instanceof LivingEntity ) { LivingEntity living = (LivingEntity) entity; -- if ( living.onClimbable() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper -+ if ( living.onClimableCached() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper // Pufferfish - use cached +- if ( living.onClimbable() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 || living.isFreezing()) // Paper ++ if ( living.onClimableCached() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 || living.isFreezing() ) // Paper // Pufferfish - use cached { return 1; // Paper } diff --git a/patches/server/0002-Purpur-Server-Changes.patch b/patches/server/0002-Purpur-Server-Changes.patch index 475cf3d..039c552 100644 --- a/patches/server/0002-Purpur-Server-Changes.patch +++ b/patches/server/0002-Purpur-Server-Changes.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 25 Nov 2023 11:56:59 +0000 +From: granny +Date: Thu, 18 Jan 2024 22:51:23 +0900 Subject: [PATCH] Purpur Server Changes -Original: PurpurMC -Copyright (C) 2023 PurpurMC +PurpurMC +Copyright (C) 2024 PurpurMC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -25,7 +25,7 @@ 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 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888fbdc9bf3c 100644 +index fd785a79b1708aadd760f5b62d49d4d4e55e9938..5b8a28969451b12c4fc66976afd052ffa5805932 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,12 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { @@ -45,7 +45,7 @@ index 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888f // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -62,6 +62,10 @@ dependencies { +@@ -61,6 +61,10 @@ dependencies { } // Pufferfish end @@ -56,7 +56,7 @@ index 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888f 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") -@@ -89,7 +93,7 @@ tasks.jar { +@@ -88,7 +92,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -65,7 +65,7 @@ index 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888f "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -173,7 +177,7 @@ fun TaskContainer.registerRunTask( +@@ -172,7 +176,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -74,7 +74,7 @@ index 9525f76103136dfc900c70f97416864115f75ed5..f083d422678f5fd21825439944af888f mainClass.set("org.bukkit.craftbukkit.Main") standardInput = System.`in` workingDir = rootProject.layout.projectDirectory -@@ -229,5 +233,7 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> +@@ -228,5 +232,7 @@ val runtimeClasspathForRunDev = sourceSets.main.flatMap { src -> } tasks.registerRunTask("runDev") { description = "Spin up a non-relocated Mojang-mapped test server" @@ -314,10 +314,10 @@ index c5d5648f4ca603ef2b1df723b58f9caf4dd3c722..3cb56595822799926a8141e60a42f5d1 .completer(new ConsoleCommandCompleter(this.server)) .option(LineReader.Option.COMPLETE_IN_WORD, true); diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -index a08c00b8c0488d18be5e182f7892e5ab71d12247..338f693d098b6ab507c30f6411c9a952c34ba8e3 100644 +index cfe6a6f6bcfd7a3b29ab25f5a6745d31c18f338d..c168658d4d4ec1ddd80425e786d4435fd6576637 100644 --- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -@@ -136,6 +136,10 @@ public class MobGoalHelper { +@@ -137,6 +137,10 @@ public class MobGoalHelper { static { // TODO these kinda should be checked on each release, in case obfuscation changes deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee"); @@ -329,7 +329,7 @@ index a08c00b8c0488d18be5e182f7892e5ab71d12247..338f693d098b6ab507c30f6411c9a952 ignored.add("goal_selector_1"); ignored.add("goal_selector_2"); diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java -index fa56cd09102a89692b42f1d14257990508c5c720..f9251183df72ddc56662fd3f02acf21641a2200c 100644 +index 066b9e4c4f0e7773548eda045cdd1ca8445221d2..92eaba96135ccddb7d682dab7e82cde9318a48ef 100644 --- a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java +++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java @@ -58,7 +58,7 @@ public class RAMDetails extends JList { @@ -344,14 +344,14 @@ index fa56cd09102a89692b42f1d14257990508c5c720..f9251183df72ddc56662fd3f02acf216 @@ -67,7 +67,7 @@ public class RAMDetails extends JList { vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)"); vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb"); - vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.tickTimes)) + " ms"); + vector.add("Avg tick: " + DECIMAL_FORMAT.format(this.getAverage(server.getTickTimesNanos())) + " ms"); - vector.add("TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg)); + vector.add("TPS from last 5s, 1m, 5m, 15m: " + String.join(", ", tpsAvg)); // Purpur setListData(vector); } diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -index cc66657cb4f978aa2df3ca1be6c683759952cc7a..9ca1494497ae53e56b1f81fda51b0b8bd02a6d03 100644 +index 61f21c0bf6658326a15b735c22001b4028b98800..43397712cb13df5be3081c05eaa1a57c57f12c60 100644 --- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java @@ -28,6 +28,7 @@ public class PufferfishConfig { @@ -371,7 +371,7 @@ index cc66657cb4f978aa2df3ca1be6c683759952cc7a..9ca1494497ae53e56b1f81fda51b0b8b if (configFile.exists()) { try { -@@ -224,7 +225,7 @@ public class PufferfishConfig { +@@ -246,7 +247,7 @@ public class PufferfishConfig { public static int activationDistanceMod; private static void dynamicActivationOfBrains() throws IOException { @@ -380,7 +380,7 @@ index cc66657cb4f978aa2df3ca1be6c683759952cc7a..9ca1494497ae53e56b1f81fda51b0b8b 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."); -@@ -268,7 +269,7 @@ public class PufferfishConfig { +@@ -290,7 +291,7 @@ public class PufferfishConfig { public static boolean throttleInactiveGoalSelectorTick; private static void inactiveGoalSelectorThrottle() { @@ -390,10 +390,10 @@ index cc66657cb4f978aa2df3ca1be6c683759952cc7a..9ca1494497ae53e56b1f81fda51b0b8b "This can improve performance by a few percent, but has minor gameplay implications."); } diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index abd0217cf0bff183c8e262edc173a53403797c1a..2519ad2884b6c09b312432b933c31476b369e599 100644 +index 6bc7c6f16a1649fc9e24e7cf90fca401e5bd4875..e1ffd62f4ebceecb9bc5471df3da406cffea0483 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -1315,9 +1315,9 @@ public final class ChunkHolderManager { +@@ -1316,9 +1316,9 @@ public final class ChunkHolderManager { } public boolean processTicketUpdates() { @@ -687,10 +687,10 @@ index 0000000000000000000000000000000000000000..a7d1ae53eac94bc2dcf8bc78ef1da0d3 + } +} diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java -index 1d714d3eff11ed14f218656008190017494d4830..ed3527612315e6e0649182ce4e1ae2834b0918a9 100644 +index e047dee632022abfe05865d1e71838be8d5d053a..888e31a0454888c36cb27602a28619f1f6dbf2c0 100644 --- a/src/main/java/net/minecraft/CrashReport.java +++ b/src/main/java/net/minecraft/CrashReport.java -@@ -123,6 +123,10 @@ public class CrashReport { +@@ -125,6 +125,10 @@ public class CrashReport { StringBuilder stringbuilder = new StringBuilder(); stringbuilder.append("---- Minecraft Crash Report ----\n"); @@ -702,10 +702,10 @@ index 1d714d3eff11ed14f218656008190017494d4830..ed3527612315e6e0649182ce4e1ae283 stringbuilder.append(CrashReport.getErrorComment()); stringbuilder.append("\n\n"); diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 56ae02aab93b9a698e9d2f07a0448aa4767169d9..106b27d507b16297a0a88b3b5beaaf3d0ef7e2c6 100644 +index ec4152f7372ddad216039a489fb5d72f963b4f18..7b20d0bfc54f93f0538275d89ae84d0f186db5a5 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -223,6 +223,19 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy +@@ -230,6 +230,19 @@ public class CommandSourceStack implements ExecutionCommandSource parseresults, String s, String label) { // CraftBukkit +@@ -326,9 +334,9 @@ public class Commands { + public void performCommand(ParseResults parseresults, String s, String label) { // CraftBukkit CommandSourceStack commandlistenerwrapper = (CommandSourceStack) parseresults.getContext().getSource(); - commandlistenerwrapper.getServer().getProfiler().push(() -> { @@ -793,19 +793,19 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..2fd376789bb24b14101e289733631a9a return "/" + s; - }); + });*/ // Purpur + ContextChain contextchain = this.finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit // Paper - make finishParsing not static - byte b0; - -@@ -402,7 +410,7 @@ public class Commands { - b0 = 0; + try { +@@ -357,7 +365,7 @@ public class Commands { + Commands.LOGGER.error("'/{}' threw an exception", s, exception); } } finally { - commandlistenerwrapper.getServer().getProfiler().pop(); + //commandlistenerwrapper.getServer().getProfiler().pop(); // Purpur } - return b0; -@@ -462,6 +470,7 @@ public class Commands { + } +@@ -507,6 +515,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { // Paper end - Async command map building new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper @@ -813,7 +813,7 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..2fd376789bb24b14101e289733631a9a PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -472,6 +481,7 @@ public class Commands { +@@ -517,6 +526,7 @@ public class Commands { } } // CraftBukkit end @@ -822,7 +822,7 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..2fd376789bb24b14101e289733631a9a } diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java -index 73c15a0c56a103ba4e62f0a51af8d42566b07245..d630c5a1aed706265d1e077da540c0bf723b838d 100644 +index 676a1499747b071515479130875157263d3a8352..fc1bba350030c076405711716e9830f8ae7f3953 100644 --- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java +++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java @@ -200,10 +200,10 @@ public class EntitySelector { @@ -875,8 +875,65 @@ index 73c15a0c56a103ba4e62f0a51af8d42566b07245..d630c5a1aed706265d1e077da540c0bf + } + // Purpur end } +diff --git a/src/main/java/net/minecraft/commands/execution/tasks/BuildContexts.java b/src/main/java/net/minecraft/commands/execution/tasks/BuildContexts.java +index 89f0f68b3e2be64bcbf8b173a51d56ea3a3fb4ea..d1c7effca3592a234925657136f750717d696873 100644 +--- a/src/main/java/net/minecraft/commands/execution/tasks/BuildContexts.java ++++ b/src/main/java/net/minecraft/commands/execution/tasks/BuildContexts.java +@@ -43,9 +43,9 @@ public class BuildContexts> { + ChainModifiers chainModifiers = flags; + List list = sources; + if (contextChain.getStage() != Stage.EXECUTE) { +- context.profiler().push(() -> { ++ /*context.profiler().push(() -> { // Purpur + return "prepare " + this.commandInput; +- }); ++ });*/ // Purpur + + try { + for(int i = context.forkLimit(); contextChain.getStage() != Stage.EXECUTE; contextChain = contextChain.nextStage()) { +@@ -88,13 +88,13 @@ public class BuildContexts> { + } + } + } finally { +- context.profiler().pop(); ++ // context.profiler().pop(); // Purpur + } + } + + if (list.isEmpty()) { + if (chainModifiers.isReturn()) { +- context.queueNext(new CommandQueueEntry<>(frame, FallthroughTask.instance())); ++ context.queueNext(new CommandQueueEntry<>(frame, (EntryAction) FallthroughTask.instance())); // Purpur - decompile error + } + + } else { +diff --git a/src/main/java/net/minecraft/commands/execution/tasks/ExecuteCommand.java b/src/main/java/net/minecraft/commands/execution/tasks/ExecuteCommand.java +index 821dc4aeaf48460000682604fba51b340b9738e7..3aa2ce6a2a3d3cdfc372a60419a09f49002339da 100644 +--- a/src/main/java/net/minecraft/commands/execution/tasks/ExecuteCommand.java ++++ b/src/main/java/net/minecraft/commands/execution/tasks/ExecuteCommand.java +@@ -23,9 +23,9 @@ public class ExecuteCommand> implements Unbo + + @Override + public void execute(T executionCommandSource, ExecutionContext executionContext, Frame frame) { +- executionContext.profiler().push(() -> { ++ /*executionContext.profiler().push(() -> { // Purpur + return "execute " + this.commandInput; +- }); ++ });*/ // Purpur + + try { + executionContext.incrementCost(); +@@ -37,7 +37,7 @@ public class ExecuteCommand> implements Unbo + } catch (CommandSyntaxException var9) { + executionCommandSource.handleError(var9, this.modifiers.isForked(), executionContext.tracer()); + } finally { +- executionContext.profiler().pop(); ++ // executionContext.profiler().pop(); // Purpur + } + + } diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 83cab746d1d6fe25c043c8aee28c39412b90c127..ec6b58dae525c81bbb1c0e2d96fbded6f00a45b5 100644 +index c47aa87db42dea74a2e07ffe6015257fa337da23..fb672028548fbc3c026c3823024249e4e804be01 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -48,6 +48,12 @@ public class BlockPos extends Vec3i { @@ -923,10 +980,10 @@ index 392406722b0a040c1d41fdc1154d75d39f6e9c86..b805e57d5a67d77d226cd8154e970050 throw new IllegalStateException("Unable to get CCW facing of " + this); } diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index a0c7c6208314d981e8577ad69ef1c5193290a085..603eac94296c32d87dccf2c6b5fd7183864346f2 100644 +index 8e13c661a06aa2f7b5f558d39fb9e989a8145904..316fc3f81a1aee1cf67e14422d0d0557b3019b78 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -1188,6 +1188,23 @@ public interface DispenseItemBehavior { +@@ -1194,6 +1194,23 @@ public interface DispenseItemBehavior { } } }); @@ -951,20 +1008,20 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..603eac94296c32d87dccf2c6b5fd7183 static Vec3 getEntityPokingOutOfBlockPos(BlockSource pointer, EntityType entityType, Direction direction) { diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index e17090003988ad2c890d48666c2234b14d511345..433f1f11b8b92c7d48352416f79ab5a394c33287 100644 +index 8d65cdb013706a932c2c73231108b2810b99e1c7..5b1938fc849db743e65cd7eed0f83ba059b9525e 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -@@ -107,7 +107,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { +@@ -104,7 +104,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { + if (ishearable.readyForShearing()) { + // CraftBukkit start + // Paper start - Add drops to shear events +- org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops()); ++ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, CraftItemStack.asNMSCopy(craftItem)))); // Purpur + if (event.isCancelled()) { + // Paper end - Add drops to shear events continue; - } - // CraftBukkit end -- ishearable.shear(SoundSource.BLOCKS); -+ ishearable.shear(SoundSource.BLOCKS, net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, CraftItemStack.asNMSCopy(craftItem))); // Purpur - worldserver.gameEvent((Entity) null, GameEvent.SHEAR, blockposition); - return true; - } diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index c0ea20dcee8bb293df96bc6ee019e50ad6b383fd..ff99d6fa919391d43b7737a2819cf9ebb7e134da 100644 +index 2ae08b21c63490bbf8cd870f9585d82ed131f815..b7a6c7e737e7aba0324a5c3c61bbfbcc3b39ac43 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -569,11 +569,20 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -989,10 +1046,10 @@ index c0ea20dcee8bb293df96bc6ee019e50ad6b383fd..ff99d6fa919391d43b7737a2819cf9eb } // Paper end diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -index 2e395962b555bef0ce1a98e1d768e7738f011535..40f51062624161892c780ddae05e22859e2cd021 100644 +index b863249ff7e13cf4939c8961601f0564c62fd661..bdcfd80f937c34956911373905d66424bbff8e1d 100644 --- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java +++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -@@ -94,6 +94,8 @@ public class FriendlyByteBuf extends ByteBuf { +@@ -95,6 +95,8 @@ public class FriendlyByteBuf extends ByteBuf { private static final int MAX_PUBLIC_KEY_LENGTH = 512; private static final Gson GSON = new Gson(); @@ -1001,7 +1058,7 @@ index 2e395962b555bef0ce1a98e1d768e7738f011535..40f51062624161892c780ddae05e2285 public FriendlyByteBuf(ByteBuf parent) { this.source = parent; } -@@ -632,6 +634,17 @@ public class FriendlyByteBuf extends ByteBuf { +@@ -640,6 +642,17 @@ public class FriendlyByteBuf extends ByteBuf { this.writeBoolean(false); } else { this.writeBoolean(true); @@ -1020,10 +1077,10 @@ index 2e395962b555bef0ce1a98e1d768e7738f011535..40f51062624161892c780ddae05e2285 this.writeId(BuiltInRegistries.ITEM, item); diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 9a49f5271ec1d9de17632bfffe8309cb1ba0d8b1..0be239c5c78432a6377cd7828cd49f61f8f0ac8f 100644 +index 3e2d5dcd62775b6ed7c0ce0ba51a71b635b1d644..166cd0f8e72189d10e56cd7bc095409aa919840e 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -49,7 +49,7 @@ public class PacketUtils { +@@ -50,7 +50,7 @@ public class PacketUtils { if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerCommonPacketListenerImpl && ((ServerCommonPacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 if (listener.shouldHandleMessage(packet)) { co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings @@ -1031,7 +1088,7 @@ index 9a49f5271ec1d9de17632bfffe8309cb1ba0d8b1..0be239c5c78432a6377cd7828cd49f61 + try { // Paper - timings // Purpur packet.handle(listener); } catch (Exception exception) { - if (exception instanceof ReportedException) { + label25: diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java index 9ec6145fe04ec64bbee8ec6a837719caebdbc6f5..358d610ad020cada1bb83e393deeeaaec05a2791 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java @@ -1046,10 +1103,10 @@ 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 58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90..b61c4d1ebb9c15a7ecd7bec5eb864851c053fb7e 100644 +index 1343649cd77a42dd502747581050b401840a6efe..6f94f01da0a2294f6fdc564653dde1fdbf508153 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 processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; -@@ -297,10 +298,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + return false; + } : this::haveTime); - this.profiler.popPush("nextTickWait"); + //this.profiler.popPush("nextTickWait"); // Purpur this.mayHaveDelayedTasks = true; -- this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); -+ // Purpur start - tps catchup -+ if (org.purpurmc.purpur.PurpurConfig.tpsCatchup) { -+ this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); -+ } else { -+ this.delayedTasksMaxNextTickTime = this.nextTickTime = curTime / 1000000L + 50L; -+ } -+ // Purpur end - tps catchup + this.delayedTasksMaxNextTickTimeNanos = Math.max(Util.getNanos() + i, this.nextTickTimeNanos); + // Pufferfish start - tps catchup +- if (!gg.pufferfish.pufferfish.PufferfishConfig.tpsCatchup) { ++ if (!org.purpurmc.purpur.PurpurConfig.tpsCatchup || !gg.pufferfish.pufferfish.PufferfishConfig.tpsCatchup) { + this.nextTickTimeNanos = curTime + i; + this.delayedTasksMaxNextTickTimeNanos = nextTickTimeNanos; + } + // Pufferfish end ++ // Purpur start - tps catchup ++ //if (org.purpurmc.purpur.PurpurConfig.tpsCatchup) { ++ // this.delayedTasksMaxNextTickTimeNanos = Math.max(Util.getNanos() + i, this.nextTickTimeNanos); ++ //} else { ++ // this.delayedTasksMaxNextTickTimeNanos = this.nextTickTimeNanos = curTime + i; ++ //} ++ // Purpur end - tps catchup this.waitUntilNextTick(); + if (flag) { + this.tickRateManager.endTickWork(); + } + - this.profiler.pop(); - this.endMetricsRecordingTick(); + //this.profiler.pop(); // Purpur + //this.endMetricsRecordingTick(); // Purpur this.isReady = true; - JvmProfiler.INSTANCE.onServerTick(this.averageTickTime); + JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis); } -@@ -1322,7 +1347,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.tickCount % autosavePeriod == 0; try { this.isSaving = true; -@@ -1404,20 +1429,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -1285,7 +1375,7 @@ index 58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90..b61c4d1ebb9c15a7ecd7bec5eb864851 // Paper start - Folia scheduler API ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); getAllLevels().forEach(level -> { -@@ -1486,22 +1511,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 + net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers 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 @@ -1372,9 +1462,9 @@ index 58d076e2a8fa1cf56c4c8d15a502e85fcf48aa90..b61c4d1ebb9c15a7ecd7bec5eb864851 - worldserver.timings.doTick.stopTiming(); // Spigot + //worldserver.timings.doTick.stopTiming(); // Spigot // Purpur } catch (Throwable throwable) { - // Spigot Start - CrashReport crashreport; -@@ -1569,33 +1596,33 @@ 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) { -@@ -2274,7 +2301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.executeBlocking(() -> { this.saveDebugReport(path.resolve("server")); -@@ -2524,40 +2551,40 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { final io.papermc.paper.adventure.ChatDecorationProcessor processor = new io.papermc.paper.adventure.ChatDecorationProcessor(this, sender, commandSourceStack, message); -@@ -2782,7 +2818,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { // Paper start - Add Adventure message to PlayerAdvancementDoneEvent if (event.message() != null && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { @@ -1601,13 +1673,13 @@ index e38e2e5a7ddba9c140f362021b6be0b0974f7cd1..533a348acb53c8e7590f3d81c19e53a6 // Paper end } diff --git a/src/main/java/net/minecraft/server/ServerFunctionManager.java b/src/main/java/net/minecraft/server/ServerFunctionManager.java -index d10abd28c522612934aada8124e5bb67a9b4e9da..097ac55028d66ef9ab430ff5dd103db6e3b99fc7 100644 +index df0c15f6b5b2224d53e4f8fad42b9a1e5f33dc25..5dd0dcb47211cec69189115bf4eab1dffc3ca8cf 100644 --- a/src/main/java/net/minecraft/server/ServerFunctionManager.java +++ b/src/main/java/net/minecraft/server/ServerFunctionManager.java -@@ -60,10 +60,10 @@ public class ServerFunctionManager { +@@ -53,10 +53,10 @@ public class ServerFunctionManager { } - private void executeTagFunctions(Collection functions, ResourceLocation label) { + private void executeTagFunctions(Collection> functions, ResourceLocation label) { - ProfilerFiller gameprofilerfiller = this.server.getProfiler(); + //ProfilerFiller gameprofilerfiller = this.server.getProfiler(); // Purpur @@ -1617,48 +1689,37 @@ index d10abd28c522612934aada8124e5bb67a9b4e9da..097ac55028d66ef9ab430ff5dd103db6 Iterator iterator = functions.iterator(); while (iterator.hasNext()) { -@@ -72,7 +72,7 @@ public class ServerFunctionManager { - this.execute(customfunction, this.getGameLoopSender()); +@@ -65,15 +65,15 @@ public class ServerFunctionManager { + this.execute(commandfunction, this.getGameLoopSender()); } - this.server.getProfiler().pop(); + //this.server.getProfiler().pop(); // Purpur } - public int execute(CommandFunction function, CommandSourceStack source) { -@@ -97,7 +97,7 @@ public class ServerFunctionManager { - } else { - int i; + public void execute(CommandFunction function, CommandSourceStack source) { +- ProfilerFiller gameprofilerfiller = this.server.getProfiler(); ++ // ProfilerFiller gameprofilerfiller = this.server.getProfiler(); // Purpur -- try (co.aikar.timings.Timing timing = function.getTiming().startTiming()) { // Paper -+ try /*(co.aikar.timings.Timing timing = function.getTiming().startTiming())*/ { // Paper // Purpur - this.context = new ServerFunctionManager.ExecutionContext(tracer); - i = this.context.runTopCommand(customfunction1, source); - } finally { -@@ -195,10 +195,10 @@ public class ServerFunctionManager { +- gameprofilerfiller.push(() -> { ++ /*gameprofilerfiller.push(() -> { // Purpur + return "function " + function.id(); +- }); ++ });*/ // Purpur - try { - ServerFunctionManager.QueuedCommand customfunctiondata_queuedcommand = (ServerFunctionManager.QueuedCommand) this.commandQueue.removeFirst(); -- ProfilerFiller gameprofilerfiller = ServerFunctionManager.this.server.getProfiler(); -+ //ProfilerFiller gameprofilerfiller = ServerFunctionManager.this.server.getProfiler(); // Purpur + try { + InstantiatedFunction instantiatedfunction = function.instantiate((CompoundTag) null, this.getDispatcher(), source); +@@ -86,7 +86,7 @@ public class ServerFunctionManager { + } catch (Exception exception) { + ServerFunctionManager.LOGGER.warn("Failed to execute function {}", function.id(), exception); + } finally { +- gameprofilerfiller.pop(); ++ // gameprofilerfiller.pop(); // Purpur + } - Objects.requireNonNull(customfunctiondata_queuedcommand); -- gameprofilerfiller.push(customfunctiondata_queuedcommand::toString); -+ //gameprofilerfiller.push(customfunctiondata_queuedcommand::toString); // Purpur - this.depth = customfunctiondata_queuedcommand.depth; - customfunctiondata_queuedcommand.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer); - if (this.abortCurrentDepth) { -@@ -217,7 +217,7 @@ public class ServerFunctionManager { - - this.nestedCalls.clear(); - } finally { -- ServerFunctionManager.this.server.getProfiler().pop(); -+ //ServerFunctionManager.this.server.getProfiler().pop(); // Purpur - } - - ++j; + } diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index 664cbce2e06fcb95d3d3d6c5302fc9119f938925..bc9778c705d23acd84fa1cdeff6b403b4cda3686 100644 +index 37d9c354af887c474094b1a364782007a5f2035d..ec86231077f6a1e03068507555539c5b550ddf31 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -48,7 +48,7 @@ public class EnchantCommand { @@ -1703,7 +1764,7 @@ index 5cb15e2209d7b315904a1fc6d650ce1e75584271..7e21db60f3ace2a19686d6ea04b994ec for(ServerPlayer serverPlayer : targets) { diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java -index d601d287e94a59ff93b8a83a44dac02544d211df..0ff3b06a98b2f4514b2d861b92dd70fe678ae86c 100644 +index 1b459a8ee8a6bc039e742d65796bc76660a1c765..599172b994d75484f7c7e0ce6d3d3d771c1c44d0 100644 --- a/src/main/java/net/minecraft/server/commands/GiveCommand.java +++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java @@ -59,6 +59,7 @@ public class GiveCommand { @@ -1713,9 +1774,9 @@ index d601d287e94a59ff93b8a83a44dac02544d211df..0ff3b06a98b2f4514b2d861b92dd70fe + if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping if (flag && itemstack1.isEmpty()) { itemstack1.setCount(1); - entityitem = entityplayer.drop(itemstack1, false, false, false); // SPIGOT-2942: Add boolean to call event + entityitem = entityplayer.drop(itemstack1, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index e5c955e7e99bc07199feabfe9f0301016ad38b84..5c6027a3ab7c52087dfebb1e21468a511ec09fa1 100644 +index 80e1dcef1eeb33f553c7d771a00d463e99e3f147..7cc19060c24ad191b7dca779a18fbfbb65763189 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -99,6 +99,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -1726,10 +1787,10 @@ index e5c955e7e99bc07199feabfe9f0301016ad38b84..5c6027a3ab7c52087dfebb1e21468a51 new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); /* jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader; -@@ -218,9 +219,19 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -219,8 +220,18 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface thread.start(); // Paper - start console thread after MinecraftServer.console & PaperConfig are initialized - io.papermc.paper.command.PaperCommands.registerCommands(this); - com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); + io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command + com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics + // Purpur start + try { + org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings")); @@ -1739,9 +1800,8 @@ index e5c955e7e99bc07199feabfe9f0301016ad38b84..5c6027a3ab7c52087dfebb1e21468a51 + } + org.purpurmc.purpur.PurpurConfig.registerCommands(); + // Purpur end - com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now - io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider - // Paper end + com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now + io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // Paper - init PaperBrigadierProvider + gg.pufferfish.pufferfish.PufferfishConfig.pufferfishFile = (java.io.File) options.valueOf("pufferfish-settings"); // Purpur gg.pufferfish.pufferfish.PufferfishConfig.load(); // Pufferfish gg.pufferfish.pufferfish.PufferfishCommand.init(); // Pufferfish @@ -1805,10 +1865,10 @@ index e5c955e7e99bc07199feabfe9f0301016ad38b84..5c6027a3ab7c52087dfebb1e21468a51 @Override diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index c5598adb8cbcbcf7277c2fd4dd72c243d44d9700..cda4544ae96a4fcb5c6c4483df67a59f1b53fd27 100644 +index 1643186bcb2caf5d29fd551afd35830726dbb80a..d53e0b67d847dfec2f4b118b5ca3f0ed1dc29ad6 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -@@ -58,6 +58,7 @@ public class DedicatedServerProperties extends Settings list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -2024,7 +2084,7 @@ index 3abec84383a445d3ad0d3b5f613246b6ac7ee741..3771caa73b0b41428f3d629aca1f562d ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1213,17 +1213,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1212,17 +1212,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -2046,10 +2106,19 @@ index 3abec84383a445d3ad0d3b5f613246b6ac7ee741..3771caa73b0b41428f3d629aca1f562d } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93b1959ffc 100644 +index 5cf74fe0214191d42e74fc104eba150a95894e0f..c3c47857515a7f75d69c718f352d8bae4b2c1d26 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -279,16 +279,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -73,7 +73,7 @@ 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 + +@@ -277,16 +277,16 @@ public class ServerChunkCache extends ChunkSource { return ifLoaded; } // Paper end @@ -2069,7 +2138,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 CompletableFuture> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; -@@ -298,10 +298,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -296,10 +296,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 @@ -2082,7 +2151,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; -@@ -450,17 +450,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -448,17 +448,17 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -2104,7 +2173,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 } // Paper end -@@ -477,36 +477,36 @@ public class ServerChunkCache extends ChunkSource { +@@ -475,37 +475,37 @@ 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 @@ -2140,6 +2209,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings + //this.level.timings.chunks.stopTiming(); // Paper - timings // Purpur + this.chunkMap.tick(); } - this.level.timings.doChunkUnload.startTiming(); // Spigot @@ -2154,62 +2224,61 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 this.clearCache(); } -@@ -521,15 +521,15 @@ public class ServerChunkCache extends ChunkSource { - this.chunkMap.tick(); - } else { - LevelData worlddata = this.level.getLevelData(); +@@ -515,19 +515,19 @@ public class ServerChunkCache extends ChunkSource { + + this.lastInhabitedUpdate = i; + if (!this.level.isDebug()) { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); + //ProfilerFiller gameprofilerfiller = this.level.getProfiler(); // Purpur - gameprofilerfiller.push("pollingChunks"); +- gameprofilerfiller.push("filteringLoadedChunks"); + //gameprofilerfiller.push("pollingChunks"); // Purpur ++ //gameprofilerfiller.push("filteringLoadedChunks"); // Purpur + // Paper - optimise chunk tick iteration +- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper ++ //if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper // Purpur + + // Paper - optimise chunk tick iteration + 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 - -- gameprofilerfiller.push("naturalSpawnCount"); -- this.level.timings.countNaturalMobs.startTiming(); // Paper - timings -+ //gameprofilerfiller.push("naturalSpawnCount"); // Purpur -+ //this.level.timings.countNaturalMobs.startTiming(); // Paper - timings // Purpur - int l = this.distanceManager.getNaturalSpawnChunkCount(); - // Paper start - per player mob spawning - NaturalSpawner.SpawnState spawnercreature_d; // moved down -@@ -560,17 +560,17 @@ public class ServerChunkCache extends ChunkSource { - // Pufferfish end - } - // Paper end -- this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings -+ //this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings // Purpur - - //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously -- gameprofilerfiller.popPush("filteringLoadedChunks"); -+ //gameprofilerfiller.popPush("filteringLoadedChunks"); // Purpur - // Paper - optimise chunk tick iteration - // Paper - optimise chunk tick iteration -- this.level.timings.chunkTicks.startTiming(); // Paper -+ //this.level.timings.chunkTicks.startTiming(); // Paper // Purpur - - // Paper - optimise chunk tick iteration - -- gameprofilerfiller.popPush("spawnAndTick"); -+ //gameprofilerfiller.popPush("spawnAndTick"); // Purpur - boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit - - // Paper start - optimise chunk tick iteration -@@ -672,17 +672,17 @@ public class ServerChunkCache extends ChunkSource { + if (this.level.getServer().tickRateManager().runsNormally()) { +- gameprofilerfiller.popPush("naturalSpawnCount"); +- this.level.timings.countNaturalMobs.startTiming(); // Paper - timings ++ // gameprofilerfiller.popPush("naturalSpawnCount"); // Purpur ++ //this.level.timings.countNaturalMobs.startTiming(); // Paper - timings // Purpur + int k = this.distanceManager.getNaturalSpawnChunkCount(); + // Paper start - per player mob spawning + int naturalSpawnChunkCount = k; +@@ -557,10 +557,10 @@ public class ServerChunkCache extends ChunkSource { + // Pufferfish end + } + // Paper end +- this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings ++ // this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings // Purpur + + // this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously +- gameprofilerfiller.popPush("spawnAndTick"); ++ //gameprofilerfiller.popPush("spawnAndTick"); // Purpur + boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit + + // Paper start - optimise chunk tick iteration +@@ -666,19 +666,19 @@ public class ServerChunkCache extends ChunkSource { + } + } + // Paper end - optimise chunk tick iteration +- this.level.timings.chunkTicks.stopTiming(); // Paper ++ // this.level.timings.chunkTicks.stopTiming(); // Paper // Purpur + +- gameprofilerfiller.popPush("customSpawners"); ++ //gameprofilerfiller.popPush("customSpawners"); // Purpur + if (flag) { +- try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings ++ //try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings // Purpur + this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); +- } // Paper - timings ++ //} // Paper - timings // Purpur } - } - // Paper end - optimise chunk tick iteration -- this.level.timings.chunkTicks.stopTiming(); // Paper -- gameprofilerfiller.popPush("customSpawners"); -+ //this.level.timings.chunkTicks.stopTiming(); // Paper // Purpur -+ //gameprofilerfiller.popPush("customSpawners"); // Purpur - if (flag2) { -- try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings -+ //try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings // Purpur - this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); -- } // Paper - timings -+ //} // Paper - timings // Purpur } - gameprofilerfiller.popPush("broadcast"); @@ -2220,7 +2289,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 // Paper start - optimise chunk tick iteration if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -@@ -696,10 +696,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -692,12 +692,12 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -2231,10 +2300,13 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 - gameprofilerfiller.pop(); + //gameprofilerfiller.pop(); // Purpur + //gameprofilerfiller.pop(); // Purpur - this.chunkMap.tick(); } - -@@ -906,7 +906,7 @@ public class ServerChunkCache extends ChunkSource { +- ++ + // Pufferfish start - optimize mob spawning + if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) { + for (ServerPlayer player : this.level.players) { +@@ -901,7 +901,7 @@ public class ServerChunkCache extends ChunkSource { @Override protected void doRunTask(Runnable task) { @@ -2244,7 +2316,7 @@ index 5d26364c0f4ed03bd9994077683c93b9883e5327..43a46feb5fb4bf23d71bc4f6c08caa93 } diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index d46e61640b241d32df05240dedd2c23f138725e6..c6ef510d335b8baea58c4491853414a52a06b66b 100644 +index e385a62058204ba3b01ce594e7c180f9cc6cf664..92ca330bee2f58bde93c8da12a8f5c14e29de540 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -73,7 +73,7 @@ public class ServerEntity { @@ -2257,10 +2329,10 @@ 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 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442b7a6df83 100644 +index f7215d0a67e9e024af0c040c796ebcbb4f76e885..1309c9e63095a0484ee0fa119a41c29ef1da3a01 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 { +@@ -215,6 +215,8 @@ public class ServerLevel extends Level implements WorldGenLevel { private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; @@ -2269,7 +2341,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 private final RandomSequences randomSequences; public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick -@@ -223,6 +225,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -224,6 +226,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean hasPhysicsEvent = true; // Paper public boolean hasEntityMoveEvent = false; // Paper private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) @@ -2277,7 +2349,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 public static Throwable getAddToWorldStackTrace(Entity entity) { final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(thr); -@@ -706,7 +709,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -712,7 +715,24 @@ public class ServerLevel extends Level implements WorldGenLevel { this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; @@ -2303,7 +2375,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 this.serverLevelData = iworlddataserver; ChunkGenerator chunkgenerator = worlddimension.generator(); // CraftBukkit start -@@ -768,6 +788,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -774,6 +794,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system @@ -2311,7 +2383,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 } // Paper start -@@ -802,17 +823,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -808,23 +829,23 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void tick(BooleanSupplier shouldKeepTicking) { @@ -2319,12 +2391,18 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 + //ProfilerFiller gameprofilerfiller = this.getProfiler(); // Purpur this.handlingTick = true; -- gameprofilerfiller.push("world border"); -+ //gameprofilerfiller.push("world border"); // Purpur - this.getWorldBorder().tick(); -- gameprofilerfiller.popPush("weather"); -+ //gameprofilerfiller.popPush("weather"); // Purpur - this.advanceWeatherCycle(); + TickRateManager tickratemanager = this.tickRateManager(); + boolean flag = tickratemanager.runsNormally(); + + if (flag) { +- gameprofilerfiller.push("world border"); ++ // gameprofilerfiller.push("world border"); // Purpur + this.getWorldBorder().tick(); +- gameprofilerfiller.popPush("weather"); ++ // gameprofilerfiller.popPush("weather"); // Purpur + this.advanceWeatherCycle(); + } + int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); long j; @@ -2333,15 +2411,15 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // CraftBukkit start j = this.levelData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime()); -@@ -834,32 +855,32 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -849,38 +870,38 @@ public class ServerLevel extends Level implements WorldGenLevel { + this.tickTime(); + } - this.updateSkyBrightness(); - this.tickTime(); - gameprofilerfiller.popPush("tickPending"); - this.timings.scheduledBlocks.startTiming(); // Paper + //gameprofilerfiller.popPush("tickPending"); // Purpur + //this.timings.scheduledBlocks.startTiming(); // Paper // Purpur - if (!this.isDebug()) { + if (!this.isDebug() && flag) { j = this.getGameTime(); - gameprofilerfiller.push("blockTicks"); + //gameprofilerfiller.push("blockTicks"); // Purpur @@ -2356,41 +2434,47 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 + //this.timings.scheduledBlocks.stopTiming(); // Paper // Purpur - gameprofilerfiller.popPush("raid"); -- this.timings.raids.startTiming(); // Paper - timings + //gameprofilerfiller.popPush("raid"); // Purpur -+ //this.timings.raids.startTiming(); // Paper - timings // Purpur - this.raids.tick(); -- this.timings.raids.stopTiming(); // Paper - timings + if (flag) { +- this.timings.raids.startTiming(); // Paper - timings ++ // this.timings.raids.startTiming(); // Paper - timings // Purpur + this.raids.tick(); +- this.timings.raids.stopTiming(); // Paper - timings ++ // this.timings.raids.stopTiming(); // Paper - timings // Purpur + } + - gameprofilerfiller.popPush("chunkSource"); - this.timings.chunkProviderTick.startTiming(); // Paper - timings -+ //this.timings.raids.stopTiming(); // Paper - timings // Purpur + //gameprofilerfiller.popPush("chunkSource"); // Purpur + //this.timings.chunkProviderTick.startTiming(); // Paper - timings // Purpur this.getChunkSource().tick(shouldKeepTicking, true); - this.timings.chunkProviderTick.stopTiming(); // Paper - timings - gameprofilerfiller.popPush("blockEvents"); -- this.timings.doSounds.startTiming(); // Spigot + //this.timings.chunkProviderTick.stopTiming(); // Paper - timings // Purpur + //gameprofilerfiller.popPush("blockEvents"); // Purpur -+ //this.timings.doSounds.startTiming(); // Spigot // Purpur - this.runBlockEvents(); -- this.timings.doSounds.stopTiming(); // Spigot -+ //this.timings.doSounds.stopTiming(); // Spigot // Purpur + if (flag) { +- this.timings.doSounds.startTiming(); // Spigot ++ // this.timings.doSounds.startTiming(); // Spigot // Purpur + this.runBlockEvents(); +- this.timings.doSounds.stopTiming(); // Spigot ++ // this.timings.doSounds.stopTiming(); // Spigot // Purpur + } + this.handlingTick = false; - gameprofilerfiller.pop(); + //gameprofilerfiller.pop(); // Purpur - boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + boolean flag1 = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players - if (flag) { -@@ -867,25 +888,25 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (flag1) { +@@ -888,25 +909,25 @@ public class ServerLevel extends Level implements WorldGenLevel { } - if (flag || this.emptyTime++ < 300) { + if (flag1 || this.emptyTime++ < 300) { - gameprofilerfiller.push("entities"); - this.timings.tickEntities.startTiming(); // Spigot + //gameprofilerfiller.push("entities"); // Purpur + //this.timings.tickEntities.startTiming(); // Spigot // Purpur - if (this.dragonFight != null) { + if (this.dragonFight != null && flag) { - gameprofilerfiller.push("dragonFight"); + //gameprofilerfiller.push("dragonFight"); // Purpur this.dragonFight.tick(); @@ -2406,7 +2490,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); - } else { + } else if (!tickratemanager.isEntityFrozen(entity)) { - gameprofilerfiller.push("checkDespawn"); + //gameprofilerfiller.push("checkDespawn"); // Purpur entity.checkDespawn(); @@ -2415,7 +2499,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list Entity entity1 = entity.getVehicle(); -@@ -897,7 +918,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -918,7 +939,7 @@ public class ServerLevel extends Level implements WorldGenLevel { entity.stopRiding(); } @@ -2424,7 +2508,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // Pufferfish start - copied from this.guardEntityTick try { this.tickNonPassenger(entity); // Pufferfish - changed -@@ -912,20 +933,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -933,20 +954,19 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper end } // Pufferfish end @@ -2450,7 +2534,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 } @Override -@@ -943,6 +963,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -964,6 +984,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)) { @@ -2464,7 +2548,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -951,7 +978,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -972,7 +999,21 @@ public class ServerLevel extends Level implements WorldGenLevel { public void setDayTime(long timeOfDay) { this.serverLevelData.setDayTime(timeOfDay); @@ -2486,7 +2570,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { Iterator iterator = this.customSpawners.iterator(); -@@ -976,7 +1017,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -997,7 +1038,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); @@ -2495,7 +2579,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // 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 { +@@ -1007,9 +1048,9 @@ public class ServerLevel extends Level implements WorldGenLevel { boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); int k = chunkcoordintpair.getMinBlockZ(); @@ -2507,7 +2591,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 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 &&*/ chunk.shouldDoLightning(this.random)) { // Spigot // Paper - disable thunder // Pufferfish - replace random with shouldDoLightning -@@ -999,10 +1040,18 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1020,10 +1061,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) { @@ -2528,7 +2612,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 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 -@@ -1019,7 +1068,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1040,7 +1089,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } } @@ -2537,18 +2621,18 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 if (!this.paperConfig().environment.disableIceAndSnow) { // Paper for (int l = 0; l < randomTickSpeed; ++l) { -@@ -1031,8 +1080,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1053,8 +1102,8 @@ public class ServerLevel extends Level implements WorldGenLevel { + } } // Paper - // Paper start - optimise random block ticking - gameprofilerfiller.popPush("tickBlocks"); - timings.chunkTicksBlocks.startTiming(); // Paper + //gameprofilerfiller.popPush("tickBlocks"); // Purpur + //timings.chunkTicksBlocks.startTiming(); // Paper // Purpur if (randomTickSpeed > 0) { + // Paper start - optimize random block ticking LevelChunkSection[] sections = chunk.getSections(); - final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this); -@@ -1065,8 +1114,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1088,8 +1137,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper end - optimise random block ticking @@ -2558,8 +2642,8 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 + //gameprofilerfiller.pop(); // Purpur } - private void tickIceAndSnow(boolean raining, BlockPos.MutableBlockPos blockposition1, final LevelChunk chunk) { // Paper - optimise chunk ticking -@@ -1120,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + @VisibleForTesting +@@ -1147,7 +1196,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; @@ -2568,7 +2652,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 return optional.map((blockposition1) -> { return blockposition1.above(1); -@@ -1169,11 +1218,27 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1196,11 +1245,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); @@ -2597,15 +2681,15 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); } -@@ -1312,6 +1377,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - - private void resetWeatherCycle() { +@@ -1340,6 +1405,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + @VisibleForTesting + public void resetWeatherCycle() { // CraftBukkit start + if (this.purpurConfig.rainStopsAfterSleep) // Purpur 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.... -@@ -1319,6 +1385,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1347,6 +1413,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setRainTime(0); } // CraftBukkit end @@ -2613,7 +2697,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 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. -@@ -1386,24 +1453,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1414,24 +1481,24 @@ public class ServerLevel extends Level implements WorldGenLevel { // Spigot end // Paper start- timings final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); @@ -2646,7 +2730,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1426,17 +1493,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1454,17 +1521,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); @@ -2670,7 +2754,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // Paper start - EAR 2 if (isActive) { passenger.rideTick(); -@@ -1448,7 +1515,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1476,7 +1543,7 @@ public class ServerLevel extends Level implements WorldGenLevel { vehicle.positionRider(passenger); } // Paper end - EAR 2 @@ -2679,7 +2763,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 Iterator iterator = passenger.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1457,7 +1524,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1485,7 +1552,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(passenger, entity2); } @@ -2688,14 +2772,14 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 } } else { passenger.stopRiding(); -@@ -1477,14 +1544,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1505,14 +1572,14 @@ public class ServerLevel extends Level implements WorldGenLevel { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); } - try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { + //try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { // Purpur if (doFull) { - this.saveLevelData(); + this.saveLevelData(true); // Pufferfish } - this.timings.worldSaveChunks.startTiming(); // Paper @@ -2706,7 +2790,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // Copied from save() // CraftBukkit start - moved from MinecraftServer.saveChunks -@@ -1496,7 +1563,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1524,7 +1591,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); } // CraftBukkit end @@ -2715,7 +2799,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 } // Paper end -@@ -1510,7 +1577,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1538,7 +1605,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit @@ -2724,7 +2808,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1520,11 +1587,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1548,11 +1615,11 @@ public class ServerLevel extends Level implements WorldGenLevel { progressListener.progressStage(Component.translatable("menu.savingChunks")); } @@ -2739,7 +2823,7 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 // Paper - rewrite chunk system - entity saving moved into ChunkHolder } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system -@@ -2810,7 +2877,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2861,7 +2928,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 @@ -2749,11 +2833,11 @@ index 945783d090e44ebed1d4968c1d1ec0b68f6d494f..1c8724fb56e790922c7e8fc73bc97442 } // 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 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc75ef9eeb7 100644 +index 0a1977905de97522cf3311f59a2cdc6c0a5f98f9..d5a5406284bf764c9f7a31a4ad85bbcda18f4df8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -274,6 +274,10 @@ public class ServerPlayer extends Player { - public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper +@@ -281,6 +281,10 @@ public class ServerPlayer extends Player { + public com.destroystokyo.paper.event.entity.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 @@ -2763,7 +2847,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 // 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)); -@@ -561,6 +565,9 @@ public class ServerPlayer extends Player { +@@ -568,6 +572,9 @@ public class ServerPlayer extends Player { } } @@ -2773,7 +2857,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 } @Override -@@ -627,6 +634,9 @@ public class ServerPlayer extends Player { +@@ -634,6 +641,9 @@ public class ServerPlayer extends Player { } this.getBukkitEntity().setExtraData(nbt); // CraftBukkit @@ -2783,7 +2867,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 } // CraftBukkit start - World fallback code, either respawn location or global spawn -@@ -755,6 +765,15 @@ public class ServerPlayer extends Player { +@@ -762,6 +772,15 @@ public class ServerPlayer extends Player { this.trackStartFallingPosition(); this.trackEnteredOrExitedLavaOnVehicle(); this.advancements.flushDirty(this); @@ -2799,15 +2883,15 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 } public void doTick() { -@@ -991,6 +1010,7 @@ public class ServerPlayer extends Player { +@@ -999,6 +1018,7 @@ public class ServerPlayer extends Player { })); - Team scoreboardteambase = this.getTeam(); + PlayerTeam scoreboardteam = this.getTeam(); + if (org.purpurmc.purpur.PurpurConfig.deathMessageOnlyBroadcastToAffectedPlayer) this.sendSystemMessage(ichatbasecomponent); else // Purpur - if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { - if (scoreboardteambase.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { + if (scoreboardteam != null && scoreboardteam.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { + if (scoreboardteam.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent); -@@ -1097,6 +1117,16 @@ public class ServerPlayer extends Player { +@@ -1102,6 +1122,16 @@ public class ServerPlayer extends Player { if (this.isInvulnerableTo(source)) { return false; } else { @@ -2824,7 +2908,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL); if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { -@@ -1208,7 +1238,7 @@ public class ServerPlayer extends Player { +@@ -1213,7 +1243,7 @@ public class ServerPlayer extends Player { PortalInfo shapedetectorshape = this.findDimensionEntryPoint(worldserver); if (shapedetectorshape != null) { @@ -2833,7 +2917,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 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 -@@ -1231,8 +1261,8 @@ public class ServerPlayer extends Player { +@@ -1236,8 +1266,8 @@ public class ServerPlayer extends Player { worldserver = ((CraftWorld) exit.getWorld()).getHandle(); // CraftBukkit end @@ -2844,7 +2928,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 if (true) { // CraftBukkit this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds -@@ -1243,13 +1273,14 @@ public class ServerPlayer extends Player { +@@ -1248,13 +1278,14 @@ public class ServerPlayer extends Player { playerlist.sendPlayerPermissionLevel(this); worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); @@ -2860,7 +2944,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 this.triggerDimensionChangeTriggers(worldserver1); this.connection.send(new ClientboundPlayerAbilitiesPacket(this.getAbilities())); playerlist.sendLevelInfo(this, worldserver); -@@ -1399,7 +1430,7 @@ public class ServerPlayer extends Player { +@@ -1404,7 +1435,7 @@ public class ServerPlayer extends Player { return entitymonster.isPreventingPlayerRest(this); }); @@ -2869,7 +2953,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1439,7 +1470,19 @@ public class ServerPlayer extends Player { +@@ -1444,7 +1475,19 @@ public class ServerPlayer extends Player { }); if (!this.serverLevel().canSleepThroughNights()) { @@ -2890,7 +2974,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 } ((ServerLevel) this.level()).updateSleepingPlayerList(); -@@ -1536,6 +1579,7 @@ public class ServerPlayer extends Player { +@@ -1549,6 +1592,7 @@ public class ServerPlayer extends Player { @Override public void openTextEdit(SignBlockEntity sign, boolean front) { @@ -2898,7 +2982,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); } -@@ -1781,6 +1825,26 @@ public class ServerPlayer extends Player { +@@ -1883,6 +1927,26 @@ public class ServerPlayer extends Player { this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -2925,7 +3009,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2102,8 +2166,68 @@ public class ServerPlayer extends Player { +@@ -2204,8 +2268,68 @@ public class ServerPlayer extends Player { public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -2994,7 +3078,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 public ServerStatsCounter getStats() { return this.stats; } -@@ -2654,4 +2778,50 @@ public class ServerPlayer extends Player { +@@ -2757,4 +2881,50 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -3046,7 +3130,7 @@ index 907c8f15f5247f9972c6677ff0f9e1aa22764a04..7b72be8dcaf3fc5c7151c847faa2dfc7 + // 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 3706e94108f68a16fea63e734f3e3b6871dcb0b8..6f8d990cbc15c3fa11acdf59fc1ec1fa583f60ec 100644 +index 3c567a9ea921a6ae36f4dc5e16a8394ab62460a8..5e18507e6d799e51f555ffc0a5f14cb76959023d 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java @@ -397,6 +397,7 @@ public class ServerPlayerGameMode { @@ -3057,15 +3141,6 @@ index 3706e94108f68a16fea63e734f3e3b6871dcb0b8..6f8d990cbc15c3fa11acdf59fc1ec1fa } // CraftBukkit end -@@ -427,7 +428,7 @@ public class ServerPlayerGameMode { - - ItemStack mainHandStack = null; // Paper - boolean isCorrectTool = false; // Paper -- if (this.isCreative()) { -+ if (this.isCreative() || (this.level.purpurConfig.shulkerBoxAllowOversizedStacks && block instanceof net.minecraft.world.level.block.ShulkerBoxBlock)) { // Purpur - // return true; // CraftBukkit - } else { - ItemStack itemstack = this.player.getMainHandItem(); @@ -516,6 +517,7 @@ public class ServerPlayerGameMode { public InteractionHand interactHand; public ItemStack interactItemStack; @@ -3103,7 +3178,7 @@ index 3706e94108f68a16fea63e734f3e3b6871dcb0b8..6f8d990cbc15c3fa11acdf59fc1ec1fa + // 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 50ed7cfe1ecef6d075ba484804827cec83ba2bf2..54f9cd80ac925aa95ff4fdb4d52cbcc2b04263a5 100644 +index 277c8e429481ca9763ddac9e700735d25aba78e9..3632957dfd39dc5dcb288fb86c0cadc37f1b4d27 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -318,6 +318,7 @@ public class WorldGenRegion implements WorldGenLevel { @@ -3115,23 +3190,24 @@ index 50ed7cfe1ecef6d075ba484804827cec83ba2bf2..54f9cd80ac925aa95ff4fdb4d52cbcc2 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 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fef3456f09 100644 +index d28d0ef6105ddeb562ddf31ae9088739856941fc..da499e0b21eba40d24d95047e3a9220567d4bae7 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -51,10 +51,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -51,11 +51,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private long keepAliveTime = Util.getMillis(); // Paper private boolean keepAlivePending; private long keepAliveChallenge; + private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur private int latency; private volatile boolean suspendFlushingOnServerThread = false; + public final java.util.Map packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit 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; -@@ -90,6 +92,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -91,6 +93,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { @@ -3148,7 +3224,7 @@ index 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fe //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); -@@ -137,6 +149,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -138,6 +150,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 } @@ -3162,7 +3238,7 @@ index 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fe } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { try { String channels = payload.toString(com.google.common.base.Charsets.UTF_8); -@@ -190,12 +209,27 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -203,12 +222,27 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } protected void keepConnectionAlive() { @@ -3191,7 +3267,7 @@ index 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fe 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 -@@ -211,7 +245,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -224,7 +258,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } // Paper end @@ -3201,11 +3277,11 @@ index 598f807f0d0caac98b81e0e2991f1bd497c4534e..b19c59a87d4136da583a0b687f6b27fe 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 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f019072006a3ef31f 100644 +index 04b0eb391bb524dd7af14b862d89c0f2494a8206..0b37acd48517d28efec716b93c33da6aa97c54f2 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 - private boolean hasMoved; // Spigot +@@ -325,6 +325,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private boolean justTeleported = false; // CraftBukkit end + // Purpur start @@ -3225,7 +3301,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 @Override public void tick() { if (this.ackBlockChangesUpTo > -1) { -@@ -390,6 +404,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -392,6 +406,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits. @@ -3238,16 +3314,16 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } -@@ -638,6 +658,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -642,6 +662,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); + if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetLastActionTime(); // Purpur + - // Skip the first time we do this - if (true) { // Spigot - don't skip any move events - Location oldTo = to.clone(); -@@ -714,6 +736,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + Location oldTo = to.clone(); + PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); + this.cserver.getPluginManager().callEvent(event); +@@ -715,6 +737,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause @@ -3255,7 +3331,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 return; } -@@ -1127,10 +1150,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1132,10 +1155,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; @@ -3271,7 +3347,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1154,6 +1182,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1159,6 +1187,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()); @@ -3279,7 +3355,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1207,13 +1236,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1212,13 +1241,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl itemstack1.setTag(nbttagcompound.copy()); } @@ -3299,7 +3375,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 this.updateBookPages(pages, (s) -> { return Component.Serializer.toJson(Component.literal(s)); -@@ -1225,10 +1257,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1230,10 +1262,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void updateBookPages(List list, UnaryOperator unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit ListTag nbttaglist = new ListTag(); @@ -3315,7 +3391,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 Objects.requireNonNull(nbttaglist); stream.forEach(nbttaglist::add); -@@ -1238,11 +1273,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1243,11 +1278,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl for (int j = list.size(); i < j; ++i) { FilteredText filteredtext = (FilteredText) list.get(i); @@ -3329,7 +3405,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 } } -@@ -1255,6 +1290,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1260,6 +1295,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) } @@ -3346,7 +3422,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 @Override public void handleEntityTagQuery(ServerboundEntityTagQuery packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -@@ -1284,8 +1329,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1309,8 +1354,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -3364,25 +3440,25 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 } else { ServerLevel worldserver = this.player.serverLevel(); -@@ -1468,7 +1521,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1496,7 +1549,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!event.isAllowed()) { flag2 = true; // Paper - diff on change, this should be moved wrongly if (event.getLogWarning()) - ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); + ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), d11); // Purpur } - // Paper end + // Paper end - Add fail move event } -@@ -1530,6 +1583,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1566,6 +1619,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); + if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetLastActionTime(); // Purpur + - // Skip the first time we do this - if (from.getX() != Double.MAX_VALUE) { - Location oldTo = to.clone(); -@@ -1568,6 +1623,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + Location oldTo = to.clone(); + PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); + this.cserver.getPluginManager().callEvent(event); +@@ -1601,6 +1656,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetFallDistance(); } @@ -3396,7 +3472,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 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(); -@@ -1619,6 +1681,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1652,6 +1714,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return false; } // Paper end - optimise out extra getCubes @@ -3410,7 +3486,16 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 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)); -@@ -1964,6 +2033,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1662,7 +1731,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + + do { + if (!iterator.hasNext()) { +- return false; ++ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur + } + + voxelshape1 = (VoxelShape) iterator.next(); +@@ -1997,6 +2066,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean cancelled; if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) { @@ -3418,16 +3503,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2281,7 +2351,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - do { - instant1 = (Instant) this.lastChatTimeStamp.get(); - if (timestamp.isBefore(instant1)) { -- return false; -+ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur - } - } while (!this.lastChatTimeStamp.compareAndSet(instant1, timestamp)); - -@@ -2391,7 +2461,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2401,7 +2471,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 @@ -3436,7 +3512,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2401,7 +2471,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2411,7 +2481,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -3445,7 +3521,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 return; } -@@ -2414,7 +2484,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2424,7 +2494,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { @@ -3454,7 +3530,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 } } // CraftBukkit end -@@ -2701,6 +2771,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2711,6 +2781,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = entity.getBoundingBox(); if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < ServerGamePacketListenerImpl.MAX_INTERACTION_DISTANCE) { @@ -3462,7 +3538,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); -@@ -2714,6 +2785,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2724,6 +2795,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); @@ -3471,7 +3547,7 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 // 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. -@@ -3299,6 +3372,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3309,6 +3382,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } } @@ -3485,19 +3561,10 @@ index 6cc9271ba058f4af759eae34e2f6e9f892b4f6da..a7e82f95db5c6c054175192f01907200 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 1c4f272219e68373eaae93fc5ea9af7d8f3fd6f9..3dcccca8ede9b203c24ba29b2020a583297b895c 100644 +index b9117be53b8b8b37af54621f54480f275546f0fd..cbcb16a6ccab1681dea22407f859f86dc1b9fe22 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -141,6 +141,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, - return false; - } - -+ if (true) return org.purpurmc.purpur.PurpurConfig.usernameValidCharactersPattern.matcher(in).matches(); // Purpur -+ - for (int i = 0, len = in.length(); i < len; ++i) { - char c = in.charAt(i); - -@@ -296,7 +298,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -270,7 +270,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 { @@ -3539,10 +3606,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 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a4584de7a 100644 +index ed11fec21b0c3a60fe8c14e699eb3a3823044d66..92717b7aa7ac94a2b1d11b5ba46522057903f981 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -488,6 +488,7 @@ public abstract class PlayerList { +@@ -486,6 +486,7 @@ public abstract class PlayerList { scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end @@ -3550,7 +3617,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a // 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()); } -@@ -601,6 +602,7 @@ public abstract class PlayerList { +@@ -599,6 +600,7 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) { // Paper end @@ -3558,7 +3625,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -755,7 +757,7 @@ public abstract class PlayerList { +@@ -753,7 +755,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; @@ -3567,7 +3634,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -1060,6 +1062,20 @@ public abstract class PlayerList { +@@ -1064,6 +1066,20 @@ public abstract class PlayerList { } // CraftBukkit end @@ -3588,7 +3655,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -1163,6 +1179,7 @@ public abstract class PlayerList { +@@ -1167,6 +1183,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + permissionLevel); } @@ -3596,7 +3663,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a player.connection.send(new ClientboundEntityEventPacket(player, b0)); } -@@ -1171,6 +1188,27 @@ public abstract class PlayerList { +@@ -1175,6 +1192,27 @@ public abstract class PlayerList { player.getBukkitEntity().recalculatePermissions(); // CraftBukkit this.server.getCommands().sendCommands(player); } // Paper @@ -3624,7 +3691,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a } public boolean isWhiteListed(GameProfile profile) { -@@ -1232,7 +1270,7 @@ public abstract class PlayerList { +@@ -1236,7 +1274,7 @@ public abstract class PlayerList { public void saveAll(int interval) { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main @@ -3633,7 +3700,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..182acaad79e14e5e120094916a0d295a int numSaved = 0; long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1243,7 +1281,7 @@ public abstract class PlayerList { +@@ -1247,7 +1285,7 @@ public abstract class PlayerList { } // Paper end } @@ -3943,7 +4010,7 @@ index 25a5a3b949a0eb632611355e74ccd4865be108ca..c8860f20956a2819da001e9393824945 return this.type().msgId(); } diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java -index 4604f8b38460e9113e966889a679d4547f24aff6..4a5d2e263d2bbee96bde7012d3385fa33860bc1b 100644 +index f339475185645f7be30963e4f980ce81a6f7e536..530a180a607636265c1b1244f05a772f7adfe7b6 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java @@ -267,4 +267,17 @@ public class DamageSources { @@ -3978,31 +4045,23 @@ index 3aad6bd0a1fb7bb3f9b7dab2c10c875864900750..31bd845130e363dd11c225dfd1e9dd89 } diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java -index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6c5b7ed91 100644 +index bf304db1f9506d3e83d16cd632b9155c39346634..d94497083f3da89dbef6479ef8f70591e630e3e7 100644 --- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java +++ b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java -@@ -16,6 +16,7 @@ import net.minecraft.util.ExtraCodecs; - import net.minecraft.util.Mth; - import net.minecraft.world.entity.LivingEntity; - import org.slf4j.Logger; -+import org.bukkit.NamespacedKey; - - public class MobEffectInstance implements Comparable { - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -35,6 +36,7 @@ public class MobEffectInstance implements Comparable { - private boolean visible; +@@ -36,6 +36,7 @@ public class MobEffectInstance implements Comparable { private boolean showIcon; @Nullable -+ private NamespacedKey key; // Purpur - add key - private MobEffectInstance hiddenEffect; + public MobEffectInstance hiddenEffect; ++ private org.bukkit.NamespacedKey key; // Purpur - add key private final Optional factorData; -@@ -54,17 +56,36 @@ public class MobEffectInstance implements Comparable { + public MobEffectInstance(MobEffect type) { +@@ -54,17 +55,36 @@ public class MobEffectInstance implements Comparable { this(type, duration, amplifier, ambient, visible, visible); } + // Purpur start -+ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean visible, @Nullable NamespacedKey key) { ++ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean visible, @Nullable org.bukkit.NamespacedKey key) { + this(type, duration, amplifier, ambient, visible, visible, key); + } + // Purpur end @@ -4010,20 +4069,20 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon) { - this(type, duration, amplifier, ambient, showParticles, showIcon, (MobEffectInstance)null, type.createFactorData()); + // Purpur start -+ this(type, duration, amplifier, ambient, showParticles, showIcon, (MobEffectInstance)null, type.createFactorData(), (NamespacedKey)null); ++ this(type, duration, amplifier, ambient, showParticles, showIcon, (MobEffectInstance)null, type.createFactorData(), (org.bukkit.NamespacedKey)null); + } + -+ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable NamespacedKey key) { ++ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable org.bukkit.NamespacedKey key) { + this(type, duration, amplifier, ambient, showParticles, showIcon, (MobEffectInstance)null, type.createFactorData(), key); + // Purpur end } public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable MobEffectInstance hiddenEffect, Optional factorCalculationData) { + // Purpur start -+ this(type, duration, amplifier, ambient, showParticles, showIcon, hiddenEffect, factorCalculationData, (NamespacedKey) null); ++ this(type, duration, amplifier, ambient, showParticles, showIcon, hiddenEffect, factorCalculationData, (org.bukkit.NamespacedKey) null); + } + -+ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable MobEffectInstance hiddenEffect, Optional factorCalculationData, @Nullable NamespacedKey key) { ++ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable MobEffectInstance hiddenEffect, Optional factorCalculationData, @Nullable org.bukkit.NamespacedKey key) { + // Purpur end this.effect = type; this.duration = duration; @@ -4035,7 +4094,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 this.hiddenEffect = hiddenEffect; this.factorData = factorCalculationData; } -@@ -85,6 +106,7 @@ public class MobEffectInstance implements Comparable { +@@ -85,6 +105,7 @@ public class MobEffectInstance implements Comparable { this.ambient = that.ambient; this.visible = that.visible; this.showIcon = that.showIcon; @@ -4043,7 +4102,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 } public boolean update(MobEffectInstance that) { -@@ -129,6 +151,13 @@ public class MobEffectInstance implements Comparable { +@@ -129,6 +150,13 @@ public class MobEffectInstance implements Comparable { bl = true; } @@ -4057,7 +4116,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 return bl; } -@@ -172,6 +201,17 @@ public class MobEffectInstance implements Comparable { +@@ -172,6 +200,17 @@ public class MobEffectInstance implements Comparable { return this.showIcon; } @@ -4067,7 +4126,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 + } + + @Nullable -+ public NamespacedKey getKey() { ++ public org.bukkit.NamespacedKey getKey() { + return this.key; + } + // Purpur end @@ -4075,7 +4134,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 public boolean tick(LivingEntity entity, Runnable overwriteCallback) { if (this.hasRemainingDuration()) { int i = this.isInfiniteDuration() ? entity.tickCount : this.duration; -@@ -232,6 +272,12 @@ public class MobEffectInstance implements Comparable { +@@ -232,6 +271,12 @@ public class MobEffectInstance implements Comparable { string = string + ", Show Icon: false"; } @@ -4088,7 +4147,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 return string; } -@@ -247,7 +293,7 @@ public class MobEffectInstance implements Comparable { +@@ -247,7 +292,7 @@ public class MobEffectInstance implements Comparable { return false; } else { MobEffectInstance mobEffectInstance = (MobEffectInstance)object; @@ -4097,7 +4156,7 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 } } -@@ -272,6 +318,11 @@ public class MobEffectInstance implements Comparable { +@@ -272,6 +317,11 @@ public class MobEffectInstance implements Comparable { nbt.putBoolean("ambient", this.isAmbient()); nbt.putBoolean("show_particles", this.isVisible()); nbt.putBoolean("show_icon", this.showIcon()); @@ -4109,21 +4168,21 @@ index 68e1b8271475996020af50b3b2cf04cd25aa6c85..4f2fcbcf90d6f5ee89e35c993a65cae6 if (this.hiddenEffect != null) { CompoundTag compoundTag = new CompoundTag(); this.hiddenEffect.save(compoundTag); -@@ -306,6 +357,13 @@ public class MobEffectInstance implements Comparable { +@@ -306,6 +356,13 @@ public class MobEffectInstance implements Comparable { bl3 = nbt.getBoolean("show_icon"); } + // Purpur start -+ NamespacedKey key = null; ++ org.bukkit.NamespacedKey key = null; + if (nbt.contains("key")) { -+ key = NamespacedKey.fromString(nbt.getString("key")); ++ key = org.bukkit.NamespacedKey.fromString(nbt.getString("key")); + } + // Purpur end + MobEffectInstance mobEffectInstance = null; if (nbt.contains("hidden_effect", 10)) { mobEffectInstance = loadSpecifiedEffect(type, nbt.getCompound("hidden_effect")); -@@ -318,7 +376,7 @@ public class MobEffectInstance implements Comparable { +@@ -318,7 +375,7 @@ public class MobEffectInstance implements Comparable { optional = Optional.empty(); } @@ -4187,19 +4246,19 @@ 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 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48082750ef 100644 +index a8d8d261daed2ebbbea3f4f356434942997ba541..93e558e1cfcdee33abf6f1c57e4cf47c7f53f750 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -156,7 +156,7 @@ import org.bukkit.plugin.PluginManager; +@@ -159,7 +159,7 @@ import org.bukkit.plugin.PluginManager; // CraftBukkit end - public abstract class Entity implements Nameable, EntityAccess, CommandSource { + public abstract class Entity implements Nameable, EntityAccess, CommandSource, ScoreHolder { - + public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur // CraftBukkit start private static final int CURRENT_LEVEL = 2; public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation -@@ -334,7 +334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -337,7 +337,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public double xOld; public double yOld; public double zOld; @@ -4208,7 +4267,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 public boolean noPhysics; public final RandomSource random; public int tickCount; -@@ -376,7 +376,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -379,7 +379,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S private final Set tags; private final double[] pistonDeltas; private long pistonDeltasGameTime; @@ -4217,15 +4276,15 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; -@@ -418,6 +418,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -424,6 +424,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + private UUID originWorld; public boolean freezeLocked = false; // Paper - Freeze Tick Lock API - public boolean collidingWithWorldBorder; // Paper - public boolean fixedPose = false; // Paper + public boolean fixedPose = false; // Paper - Expand Pose API + public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -493,6 +494,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -499,6 +500,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return false; } @@ -4251,7 +4310,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 public final boolean hardCollides() { return this.hardCollides; } -@@ -575,7 +595,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -581,7 +601,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -4260,7 +4319,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -823,7 +843,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -833,7 +853,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // CraftBukkit end public void baseTick() { @@ -4269,7 +4328,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 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()) { -@@ -884,7 +904,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -894,7 +914,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } this.firstTick = false; @@ -4278,7 +4337,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } public void setSharedFlagOnFire(boolean onFire) { -@@ -893,10 +913,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -903,10 +923,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public void checkBelowWorld() { // Paper start - Configurable nether ceiling damage @@ -4291,7 +4350,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 this.onBelowWorld(); } -@@ -1103,7 +1124,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1113,7 +1134,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } } @@ -4300,7 +4359,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { movement = movement.multiply(this.stuckSpeedMultiplier); this.stuckSpeedMultiplier = Vec3.ZERO; -@@ -1112,7 +1133,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1122,7 +1143,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // 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); @@ -4309,7 +4368,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 return; } // Paper end -@@ -1133,8 +1154,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1143,8 +1164,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.setPos(this.getX() + vec3d1.x, this.getY() + vec3d1.y, this.getZ() + vec3d1.z); } @@ -4320,7 +4379,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 boolean flag = !Mth.equal(movement.x, vec3d1.x); boolean flag1 = !Mth.equal(movement.z, vec3d1.z); -@@ -1153,7 +1174,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1163,7 +1184,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.checkFallDamage(vec3d1.y, this.onGround(), iblockdata, blockposition); if (this.isRemoved()) { @@ -4329,7 +4388,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } else { if (this.horizontalCollision) { Vec3 vec3d2 = this.getDeltaMovement(); -@@ -1291,7 +1312,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1301,7 +1322,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.setRemainingFireTicks(-this.getFireImmuneTicks()); } @@ -4338,7 +4397,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } } // Paper start - detailed watchdog information -@@ -1793,7 +1814,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1799,7 +1820,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } public boolean fireImmune() { @@ -4347,7 +4406,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { -@@ -1866,7 +1887,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1872,7 +1893,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return this.isInWater() || flag; } @@ -4356,32 +4415,31 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 Entity entity = this.getVehicle(); if (entity instanceof Boat) { -@@ -2467,6 +2488,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - nbt.putBoolean("Paper.FreezeLock", true); +@@ -2491,6 +2512,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + nbttagcompound.putBoolean("Paper.FreezeLock", true); } // Paper end + // Purpur start + if (immuneToFire != null) { -+ nbt.putBoolean("Purpur.FireImmune", immuneToFire); ++ nbttagcompound.putBoolean("Purpur.FireImmune", immuneToFire); + } + // Purpur end - return nbt; + return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2614,7 +2640,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2638,6 +2664,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S 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"); - CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); -@@ -2984,6 +3014,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3013,6 +3044,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.passengers = ImmutableList.copyOf(list); } @@ -4395,20 +4453,22 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3024,6 +3061,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3052,6 +3090,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return false; } - // Spigot end + // CraftBukkit end ++ + // Purpur start + if (this.rider != null && this.passengers.get(0) == this.rider) { + onDismount(this.rider); + this.rider = null; + } + // Purpur end ++ if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -3103,12 +3146,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3131,12 +3177,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return Vec3.directionFromRotation(this.getRotationVector()); } @@ -4425,7 +4485,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } this.isInsidePortal = true; -@@ -3126,7 +3172,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3154,7 +3203,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S ServerLevel worldserver1 = minecraftserver.getLevel(resourcekey); if (true && !this.isPassenger() && this.portalTime++ >= i) { // CraftBukkit @@ -4434,7 +4494,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 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); -@@ -3144,7 +3190,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3172,7 +3221,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } } // Paper // CraftBukkit end @@ -4443,15 +4503,16 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } this.isInsidePortal = false; -@@ -3159,6 +3205,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3187,7 +3236,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } this.processPortalCooldown(); -+ if (this.level().purpurConfig.endPortalSafeTeleporting) // Purpur - this.tickEndPortal(); // Paper - make end portalling safe +- this.tickEndPortal(); // Paper - make end portalling safe ++ if (this.level().purpurConfig.endPortalSafeTeleporting) this.tickEndPortal(); // Paper - make end portalling safe // Purpur } } -@@ -3349,7 +3396,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + +@@ -3377,7 +3426,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } public int getMaxAirSupply() { @@ -4460,7 +4521,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } public int getAirSupply() { -@@ -3619,14 +3666,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3647,14 +3696,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } // Paper end if (this.level() instanceof ServerLevel && !this.isRemoved()) { @@ -4477,7 +4538,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 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) { -@@ -3665,7 +3712,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3693,7 +3742,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.unRide(); // CraftBukkit end @@ -4486,7 +4547,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 // Paper start - Change lead drop timing to prevent dupe if (this instanceof Mob) { ((Mob) this).dropLeash(true, true); // Paper drop lead -@@ -3688,10 +3735,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3720,10 +3769,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } this.removeAfterChangingDimensions(); @@ -4499,7 +4560,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 return entity; } } else { -@@ -3811,7 +3858,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3843,7 +3892,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } public boolean canChangeDimensions() { @@ -4508,7 +4569,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 } public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { -@@ -4104,6 +4151,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4141,6 +4190,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return SlotAccess.NULL; } @@ -4529,7 +4590,7 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 @Override public void sendSystemMessage(Component message) {} -@@ -4373,6 +4434,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4421,6 +4484,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.yRotO = this.getYRot(); } @@ -4542,11 +4603,10 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 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; -@@ -4938,4 +5005,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4986,4 +5055,44 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end -+ + // Purpur start + @Nullable + private Player rider = null; @@ -4589,22 +4649,22 @@ index 80c9a523e94704f73e833e2255af6b0bf55da454..a13e6d41584a55e3e17d55d568b23f48 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 3ff999734d14e2b6e7828e117f5ee32a60c26bc1..cfa9607241c3e69777ffc317206996c2f783437a 100644 +index dbbce471c35849ea7d7ad07e9db9b7d8d85690df..5eb63d857fea0f1c4dc1e6e4c7af8ea653dc7963 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -39,6 +39,7 @@ public final class EntitySelector { +@@ -40,6 +40,7 @@ public final class EntitySelector { return net.minecraft.util.Mth.clamp(serverPlayer.getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= playerInsomniaTicks; }; - // Paper end + // Paper end - Ability to control player's insomnia and phantoms + public static Predicate notAfk = (player) -> !player.isAfk(); // Purpur private EntitySelector() {} // Paper start diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 2561e74ffdf595a9b6ae13dcd738662c772db442..5930e45bae5aa86b3cedb811c4c9bb92099bc1b5 100644 +index 0ffd377dba738bd651b0c7f5ca0a0d61aaa1d82c..bf4338521cfb3527164f83baf0c6c7065215771d 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -309,13 +309,24 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -313,13 +313,24 @@ public class EntityType implements FeatureElement, EntityTypeT private Component description; @Nullable private ResourceLocation lootTable; @@ -4630,7 +4690,7 @@ index 2561e74ffdf595a9b6ae13dcd738662c772db442..5930e45bae5aa86b3cedb811c4c9bb92 public static ResourceLocation getKey(EntityType type) { return BuiltInRegistries.ENTITY_TYPE.getKey(type); } -@@ -531,6 +542,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -535,6 +546,16 @@ public class EntityType implements FeatureElement, EntityTypeT return this.category; } @@ -4647,7 +4707,7 @@ index 2561e74ffdf595a9b6ae13dcd738662c772db442..5930e45bae5aa86b3cedb811c4c9bb92 public String getDescriptionId() { if (this.descriptionId == null) { this.descriptionId = Util.makeDescriptionId("entity", BuiltInRegistries.ENTITY_TYPE.getKey(this)); -@@ -592,6 +613,12 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -602,6 +623,12 @@ public class EntityType implements FeatureElement, EntityTypeT entity.load(nbt); }, () -> { EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); @@ -4661,7 +4721,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 6dac7cd4c9abfbde299f5d279acc2739195fc312..2bcbfe5516e30a150aa133cf8c1561b784443778 100644 +index b37e13c5de1a0a22a3713d04b203afc6c03ccbac..798cd8e0aae377122995155f4031d186ac4e35f7 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 { @@ -4745,10 +4805,10 @@ 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 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b26bfd5947 100644 +index 9b7e786d5ae6bdeeb96df6e9c4d1b24e1e856e58..3b1c09f8afe1a008df4b75b605a796bfb1bf3899 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 { +@@ -217,9 +217,9 @@ public abstract class LivingEntity extends Entity implements Attackable { protected int deathScore; public float lastHurt; public boolean jumping; @@ -4761,23 +4821,23 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 protected int lerpSteps; protected double lerpX; protected double lerpY; -@@ -253,6 +253,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - private boolean skipDropExperience; +@@ -252,6 +252,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + protected boolean skipDropExperience; // CraftBukkit start public int expToDrop; + public float safeFallDistance = 3.0F; // Purpur public boolean forceDrops; - public ArrayList drops = new ArrayList<>(); // Paper + public ArrayList drops = new ArrayList<>(); // Paper - Restore vanilla drops behavior public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; -@@ -262,6 +263,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -261,6 +262,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 public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event - public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API + protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur @Override public float getBukkitYaw() { -@@ -286,7 +288,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -285,7 +287,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.effectsDirty = true; this.useItem = ItemStack.EMPTY; this.lastClimbablePos = Optional.empty(); @@ -4787,7 +4847,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.craftAttributes = new CraftAttributeMap(this.attributes); // CraftBukkit // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor this.entityData.set(LivingEntity.DATA_HEALTH_ID, (float) this.getAttribute(Attributes.MAX_HEALTH).getValue()); -@@ -302,6 +305,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -301,6 +304,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.brain = this.makeBrain(new Dynamic(dynamicopsnbt, (Tag) dynamicopsnbt.createMap((Map) ImmutableMap.of(dynamicopsnbt.createString("memories"), (Tag) dynamicopsnbt.emptyMap())))); } @@ -4796,7 +4856,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 public Brain getBrain() { return this.brain; } -@@ -337,6 +342,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -336,6 +341,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public static AttributeSupplier.Builder createLivingAttributes() { return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION); } @@ -4804,7 +4864,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 @Override protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { -@@ -349,7 +355,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -348,7 +354,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.tryAddSoulSpeed(); } @@ -4813,7 +4873,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 double d1 = this.getX(); double d2 = this.getY(); double d3 = this.getZ(); -@@ -364,7 +370,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -363,7 +369,7 @@ public abstract class LivingEntity extends Entity implements Attackable { d3 = (double) landedPosition.getZ() + 0.5D + d5 / d6 * 0.5D; } @@ -4822,7 +4882,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 double d7 = Math.min((double) (0.2F + f / 15.0F), 2.5D); int i = (int) (150.0D * d7); -@@ -404,7 +410,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -403,7 +409,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } super.baseTick(); @@ -4831,7 +4891,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 if (this.fireImmune() || this.level().isClientSide) { this.clearFire(); } -@@ -422,6 +428,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -421,6 +427,7 @@ public abstract class LivingEntity extends Entity implements Attackable { double d1 = this.level().getWorldBorder().getDamagePerBlock(); if (d1 > 0.0D) { @@ -4839,7 +4899,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.hurt(this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d0 * d1))); } } -@@ -433,7 +440,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -432,7 +439,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (flag1) { this.setAirSupply(this.decreaseAirSupply(this.getAirSupply())); @@ -4848,7 +4908,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.setAirSupply(0); Vec3 vec3d = this.getDeltaMovement(); -@@ -445,7 +452,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -444,7 +451,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.level().addParticle(ParticleTypes.BUBBLE, this.getX() + d2, this.getY() + d3, this.getZ() + d4, vec3d.x, vec3d.y, vec3d.z); } @@ -4857,7 +4917,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } } -@@ -506,7 +513,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -505,7 +512,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.yHeadRotO = this.yHeadRot; this.yRotO = this.getYRot(); this.xRotO = this.getXRot(); @@ -4866,7 +4926,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } public boolean canSpawnSoulSpeedParticle() { -@@ -798,6 +805,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -797,6 +804,7 @@ public abstract class LivingEntity extends Entity implements Attackable { dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { nbt.put("Brain", nbtbase); }); @@ -4886,7 +4946,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } // CraftBukkit start -@@ -1027,9 +1040,29 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1027,9 +1040,31 @@ public abstract class LivingEntity extends Entity implements Attackable { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); EntityType entitytypes = entity.getType(); @@ -4905,7 +4965,9 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 + 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(); @@ -4918,7 +4980,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } return d0; -@@ -1089,6 +1122,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1089,6 +1124,7 @@ public abstract class LivingEntity extends Entity implements Attackable { for (flag = false; iterator.hasNext(); flag = true) { // CraftBukkit start MobEffectInstance effect = (MobEffectInstance) iterator.next(); @@ -4926,7 +4988,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); if (event.isCancelled()) { continue; -@@ -1511,13 +1545,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1511,13 +1547,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; @@ -4942,7 +5004,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 LivingEntity entityliving2 = entitywolf.getOwner(); if (entityliving2 instanceof net.minecraft.world.entity.player.Player) { -@@ -1625,6 +1659,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1625,6 +1661,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -4961,7 +5023,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 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); -@@ -1792,7 +1838,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1790,7 +1838,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = false; if (this.dead && adversary instanceof WitherBoss) { // Paper @@ -4970,7 +5032,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1838,6 +1884,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1836,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)) { @@ -4978,7 +5040,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.dropFromLootTable(source, flag); // Paper start final boolean prev = this.clearEquipmentSlots; -@@ -1846,6 +1893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1844,6 +1893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper end this.dropCustomDeathLoot(source, i, flag); this.clearEquipmentSlots = prev; // Paper @@ -4986,7 +5048,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } // 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, () -> { -@@ -2093,7 +2141,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2091,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); @@ -4995,28 +5057,28 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } } -@@ -2316,6 +2364,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2314,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. -@@ -2536,7 +2598,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2534,7 +2598,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override protected void onBelowWorld() { @@ -5025,7 +5087,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } protected void updateSwingTime() { -@@ -2730,7 +2792,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2728,7 +2792,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected long lastJumpTime = 0L; // Paper @@ -5034,7 +5096,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 Vec3 vec3d = this.getDeltaMovement(); // Paper start long time = System.nanoTime(); -@@ -2882,6 +2944,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2880,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); @@ -5042,7 +5104,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.hurt(this.damageSources().flyIntoWall(), f3); } } -@@ -3103,10 +3166,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3101,10 +3166,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.run += (f3 - this.run) * 0.3F; @@ -5056,7 +5118,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 // Paper start - stop large pitch and yaw changes from crashing the server this.yRotO += Math.round((this.getYRot() - this.yRotO) / 360.0F) * 360.0F; -@@ -3118,7 +3181,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3116,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 @@ -5065,7 +5127,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.animStep += f2; if (this.isFallFlying()) { ++this.fallFlyTicks; -@@ -3408,19 +3471,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3411,19 +3476,19 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.setDeltaMovement(d0, d1, d2); @@ -5090,7 +5152,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 if (this.jumping && this.isAffectedByFluids()) { double d3; -@@ -3447,8 +3510,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3450,8 +3515,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.noJumpDelay = 0; } @@ -5101,7 +5163,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 this.xxa *= 0.98F; this.zza *= 0.98F; this.updateFallFlying(); -@@ -3475,8 +3538,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3478,8 +3543,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.travel(vec3d1); } @@ -5109,10 +5171,10 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 - this.level().getProfiler().push("freezing"); + //this.level().getProfiler().pop(); // Purpur + //this.level().getProfiler().push("freezing"); // Purpur - if (!this.level().isClientSide && !this.isDeadOrDying() && !freezeLocked) { // Paper - Freeze Tick Lock API + if (!this.level().isClientSide && !this.isDeadOrDying() && !this.freezeLocked) { // Paper - Freeze Tick Lock API int i = this.getTicksFrozen(); -@@ -3493,18 +3556,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3496,18 +3561,20 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurt(this.damageSources().freeze(), 1.0F); } @@ -5138,7 +5200,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 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()); -@@ -3514,12 +3579,48 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3517,12 +3584,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()); } } @@ -5187,7 +5249,7 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 } public boolean isSensitiveToWater() { -@@ -3540,7 +3641,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3543,7 +3646,16 @@ public abstract class LivingEntity extends Entity implements Attackable { int j = i / 10; if (j % 2 == 0) { @@ -5206,10 +5268,10 @@ index 3b9ee3324a084271862ed790e8fc0d469e877ec1..7fdb4d5eb1ab6c45c88ca18112d5b1b2 }); } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c57a05fd4 100644 +index 2f3dc569ff9cdead48aa831c96c027cc7255d609..4c0d710d20e074ad4a0fdd1cd4c0c3d3383b68a5 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; +@@ -66,6 +66,7 @@ import net.minecraft.world.item.ProjectileWeaponItem; import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.SwordItem; import net.minecraft.world.item.enchantment.EnchantmentHelper; @@ -5217,7 +5279,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c import net.minecraft.world.level.GameRules; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.Level; -@@ -134,6 +135,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -135,6 +136,7 @@ public abstract class Mob extends LivingEntity implements Targeting { private BlockPos restrictCenter; private float restrictRadius; @@ -5225,7 +5287,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c public boolean aware = true; // CraftBukkit protected Mob(EntityType type, Level world) { -@@ -147,8 +149,8 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -148,8 +150,8 @@ public abstract class Mob extends LivingEntity implements Targeting { this.restrictRadius = -1.0F; this.goalSelector = new GoalSelector(world.getProfilerSupplier()); this.targetSelector = new GoalSelector(world.getProfilerSupplier()); @@ -5236,7 +5298,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c this.jumpControl = new JumpControl(this); this.bodyRotationControl = this.createBodyControl(); this.navigation = this.createNavigation(world); -@@ -323,6 +325,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -324,6 +326,7 @@ public abstract class Mob extends LivingEntity implements Targeting { entityliving = null; } } @@ -5244,7 +5306,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c this.target = entityliving; return true; // CraftBukkit end -@@ -363,15 +366,35 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -364,15 +367,35 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void baseTick() { super.baseTick(); @@ -5282,7 +5344,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c @Override protected void playHurtSound(DamageSource source) { this.resetAmbientSoundTime(); -@@ -561,6 +584,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -562,6 +585,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit @@ -5290,7 +5352,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c } @Override -@@ -631,6 +655,11 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -632,6 +656,11 @@ public abstract class Mob extends LivingEntity implements Targeting { this.aware = nbt.getBoolean("Bukkit.Aware"); } // CraftBukkit end @@ -5302,7 +5364,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c } @Override -@@ -674,8 +703,8 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -675,8 +704,8 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void aiStep() { super.aiStep(); @@ -5313,7 +5375,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c Vec3i baseblockposition = this.getPickupReach(); List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ())); Iterator iterator = list.iterator(); -@@ -694,7 +723,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -695,7 +724,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } } @@ -5322,7 +5384,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c } protected Vec3i getPickupReach() { -@@ -906,46 +935,46 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -907,46 +936,46 @@ public abstract class Mob extends LivingEntity implements Targeting { return; } // Paper end @@ -5348,7 +5410,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c + //this.level().getProfiler().pop(); // Purpur } else { - this.level().getProfiler().push("targetSelector"); -+ //this.level().getProfiler().push("targetSelector"); ++ //this.level().getProfiler().push("targetSelector"); // Purpur if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); - this.level().getProfiler().pop(); @@ -5389,7 +5451,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c this.sendDebugPackets(); } -@@ -1174,6 +1203,12 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1175,6 +1204,12 @@ public abstract class Mob extends LivingEntity implements Targeting { } @@ -5402,7 +5464,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c @Nullable public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) { switch (equipmentSlot) { -@@ -1268,7 +1303,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1269,7 +1304,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)); @@ -5411,7 +5473,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c this.setLeftHanded(true); } else { this.setLeftHanded(false); -@@ -1316,6 +1351,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1317,6 +1352,7 @@ public abstract class Mob extends LivingEntity implements Targeting { if (!this.isAlive()) { return InteractionResult.PASS; } else if (this.getLeashHolder() == player) { @@ -5419,7 +5481,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c // CraftBukkit start - fire PlayerUnleashEntityEvent // Paper start - drop leash variable org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild); -@@ -1389,7 +1425,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1390,7 +1426,7 @@ public abstract class Mob extends LivingEntity implements Targeting { protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} protected InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -5428,7 +5490,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c } public boolean isWithinRestriction() { -@@ -1700,6 +1736,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1701,6 +1737,7 @@ public abstract class Mob extends LivingEntity implements Targeting { this.setLastHurtMob(target); } @@ -5436,7 +5498,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c return flag; } -@@ -1716,17 +1753,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1721,17 +1758,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } public boolean isSunBurnTick() { @@ -5455,7 +5517,7 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c } @Override -@@ -1773,4 +1800,56 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1779,4 +1806,56 @@ public abstract class Mob extends LivingEntity implements Targeting { return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg); } @@ -5513,24 +5575,18 @@ index 944c22ea172796492a683d2f2bddfb0938d7a8c9..80c03bd4e5d7e20bb8a4e14af5620f5c + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java -index 5e8cc5cfac8888628c6d513148f41be09ca65a2c..a089fc61ec09be6b7490375489178dc6ba5a644b 100644 +index 2ee48ac3b665db2b02bcb1a30ec972d43a3725b0..59e8f5431ce5026209e1428b5fa5b5485dcfebc7 100644 --- a/src/main/java/net/minecraft/world/entity/Shearable.java +++ b/src/main/java/net/minecraft/world/entity/Shearable.java -@@ -3,7 +3,13 @@ package net.minecraft.world.entity; - import net.minecraft.sounds.SoundSource; - - public interface Shearable { -- void shear(SoundSource shearedSoundCategory); -+ // Purpur start -+ default void shear(SoundSource shearedSoundCategory) { -+ shear(shearedSoundCategory, 0); -+ } -+ -+ void shear(SoundSource shearedSoundCategory, int looting); -+ // Purpur end +@@ -8,7 +8,7 @@ public interface Shearable { boolean readyForShearing(); - } + // Paper start - custom shear drops; ensure all implementing entities override this +- default java.util.List generateDefaultDrops() { ++ default java.util.List generateDefaultDrops(int looting) { // Purpur + return java.util.Collections.emptyList(); + } + // Paper end - custom shear drops 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 3087f8359b098682a345399c85395de8a15b6eed..6b0855cffb901dbc7dcc5fd44506275206bc9a2d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -5568,96 +5624,97 @@ index 3087f8359b098682a345399c85395de8a15b6eed..6b0855cffb901dbc7dcc5fd445062752 } diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java b/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java -index 8a720f9ae81d7ea856e28cb27a66adcf04bcb0eb..e0b70d9732a2b7d96999b7e4a497ffa1d8cf86a7 100644 +index 0a13e076b42bc8c0e7d4962379c207dea89f0435..2d7afaa67c762107717486cb9dbbf6f8f967396c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java -@@ -80,7 +80,88 @@ import org.slf4j.Logger; +@@ -81,7 +81,89 @@ import org.slf4j.Logger; public class DefaultAttributes { private static final Logger LOGGER = LogUtils.getLogger(); -- private static final Map, AttributeSupplier> SUPPLIERS = ImmutableMap., AttributeSupplier>builder().put(EntityType.ALLAY, Allay.createAttributes().build()).put(EntityType.ARMOR_STAND, LivingEntity.createLivingAttributes().build()).put(EntityType.AXOLOTL, Axolotl.createAttributes().build()).put(EntityType.BAT, Bat.createAttributes().build()).put(EntityType.BEE, Bee.createAttributes().build()).put(EntityType.BLAZE, Blaze.createAttributes().build()).put(EntityType.CAT, Cat.createAttributes().build()).put(EntityType.CAMEL, Camel.createAttributes().build()).put(EntityType.CAVE_SPIDER, CaveSpider.createCaveSpider().build()).put(EntityType.CHICKEN, Chicken.createAttributes().build()).put(EntityType.COD, AbstractFish.createAttributes().build()).put(EntityType.COW, Cow.createAttributes().build()).put(EntityType.CREEPER, Creeper.createAttributes().build()).put(EntityType.DOLPHIN, Dolphin.createAttributes().build()).put(EntityType.DONKEY, AbstractChestedHorse.createBaseChestedHorseAttributes().build()).put(EntityType.DROWNED, Zombie.createAttributes().build()).put(EntityType.ELDER_GUARDIAN, ElderGuardian.createAttributes().build()).put(EntityType.ENDERMAN, EnderMan.createAttributes().build()).put(EntityType.ENDERMITE, Endermite.createAttributes().build()).put(EntityType.ENDER_DRAGON, EnderDragon.createAttributes().build()).put(EntityType.EVOKER, Evoker.createAttributes().build()).put(EntityType.FOX, Fox.createAttributes().build()).put(EntityType.FROG, Frog.createAttributes().build()).put(EntityType.GHAST, Ghast.createAttributes().build()).put(EntityType.GIANT, Giant.createAttributes().build()).put(EntityType.GLOW_SQUID, GlowSquid.createAttributes().build()).put(EntityType.GOAT, Goat.createAttributes().build()).put(EntityType.GUARDIAN, Guardian.createAttributes().build()).put(EntityType.HOGLIN, Hoglin.createAttributes().build()).put(EntityType.HORSE, AbstractHorse.createBaseHorseAttributes().build()).put(EntityType.HUSK, Zombie.createAttributes().build()).put(EntityType.ILLUSIONER, Illusioner.createAttributes().build()).put(EntityType.IRON_GOLEM, IronGolem.createAttributes().build()).put(EntityType.LLAMA, Llama.createAttributes().build()).put(EntityType.MAGMA_CUBE, MagmaCube.createAttributes().build()).put(EntityType.MOOSHROOM, Cow.createAttributes().build()).put(EntityType.MULE, AbstractChestedHorse.createBaseChestedHorseAttributes().build()).put(EntityType.OCELOT, Ocelot.createAttributes().build()).put(EntityType.PANDA, Panda.createAttributes().build()).put(EntityType.PARROT, Parrot.createAttributes().build()).put(EntityType.PHANTOM, Monster.createMonsterAttributes().build()).put(EntityType.PIG, Pig.createAttributes().build()).put(EntityType.PIGLIN, Piglin.createAttributes().build()).put(EntityType.PIGLIN_BRUTE, PiglinBrute.createAttributes().build()).put(EntityType.PILLAGER, Pillager.createAttributes().build()).put(EntityType.PLAYER, Player.createAttributes().build()).put(EntityType.POLAR_BEAR, PolarBear.createAttributes().build()).put(EntityType.PUFFERFISH, AbstractFish.createAttributes().build()).put(EntityType.RABBIT, Rabbit.createAttributes().build()).put(EntityType.RAVAGER, Ravager.createAttributes().build()).put(EntityType.SALMON, AbstractFish.createAttributes().build()).put(EntityType.SHEEP, Sheep.createAttributes().build()).put(EntityType.SHULKER, Shulker.createAttributes().build()).put(EntityType.SILVERFISH, Silverfish.createAttributes().build()).put(EntityType.SKELETON, AbstractSkeleton.createAttributes().build()).put(EntityType.SKELETON_HORSE, SkeletonHorse.createAttributes().build()).put(EntityType.SLIME, Monster.createMonsterAttributes().build()).put(EntityType.SNIFFER, Sniffer.createAttributes().build()).put(EntityType.SNOW_GOLEM, SnowGolem.createAttributes().build()).put(EntityType.SPIDER, Spider.createAttributes().build()).put(EntityType.SQUID, Squid.createAttributes().build()).put(EntityType.STRAY, AbstractSkeleton.createAttributes().build()).put(EntityType.STRIDER, Strider.createAttributes().build()).put(EntityType.TADPOLE, Tadpole.createAttributes().build()).put(EntityType.TRADER_LLAMA, Llama.createAttributes().build()).put(EntityType.TROPICAL_FISH, AbstractFish.createAttributes().build()).put(EntityType.TURTLE, Turtle.createAttributes().build()).put(EntityType.VEX, Vex.createAttributes().build()).put(EntityType.VILLAGER, Villager.createAttributes().build()).put(EntityType.VINDICATOR, Vindicator.createAttributes().build()).put(EntityType.WARDEN, Warden.createAttributes().build()).put(EntityType.WANDERING_TRADER, Mob.createMobAttributes().build()).put(EntityType.WITCH, Witch.createAttributes().build()).put(EntityType.WITHER, WitherBoss.createAttributes().build()).put(EntityType.WITHER_SKELETON, AbstractSkeleton.createAttributes().build()).put(EntityType.WOLF, Wolf.createAttributes().build()).put(EntityType.ZOGLIN, Zoglin.createAttributes().build()).put(EntityType.ZOMBIE, Zombie.createAttributes().build()).put(EntityType.ZOMBIE_HORSE, ZombieHorse.createAttributes().build()).put(EntityType.ZOMBIE_VILLAGER, Zombie.createAttributes().build()).put(EntityType.ZOMBIFIED_PIGLIN, ZombifiedPiglin.createAttributes().build()).build(); +- private static final Map, AttributeSupplier> SUPPLIERS = ImmutableMap., AttributeSupplier>builder().put(EntityType.ALLAY, Allay.createAttributes().build()).put(EntityType.ARMOR_STAND, LivingEntity.createLivingAttributes().build()).put(EntityType.AXOLOTL, Axolotl.createAttributes().build()).put(EntityType.BAT, Bat.createAttributes().build()).put(EntityType.BEE, Bee.createAttributes().build()).put(EntityType.BLAZE, Blaze.createAttributes().build()).put(EntityType.CAT, Cat.createAttributes().build()).put(EntityType.CAMEL, Camel.createAttributes().build()).put(EntityType.CAVE_SPIDER, CaveSpider.createCaveSpider().build()).put(EntityType.CHICKEN, Chicken.createAttributes().build()).put(EntityType.COD, AbstractFish.createAttributes().build()).put(EntityType.COW, Cow.createAttributes().build()).put(EntityType.CREEPER, Creeper.createAttributes().build()).put(EntityType.DOLPHIN, Dolphin.createAttributes().build()).put(EntityType.DONKEY, AbstractChestedHorse.createBaseChestedHorseAttributes().build()).put(EntityType.DROWNED, Zombie.createAttributes().build()).put(EntityType.ELDER_GUARDIAN, ElderGuardian.createAttributes().build()).put(EntityType.ENDERMAN, EnderMan.createAttributes().build()).put(EntityType.ENDERMITE, Endermite.createAttributes().build()).put(EntityType.ENDER_DRAGON, EnderDragon.createAttributes().build()).put(EntityType.EVOKER, Evoker.createAttributes().build()).put(EntityType.BREEZE, Breeze.createAttributes().build()).put(EntityType.FOX, Fox.createAttributes().build()).put(EntityType.FROG, Frog.createAttributes().build()).put(EntityType.GHAST, Ghast.createAttributes().build()).put(EntityType.GIANT, Giant.createAttributes().build()).put(EntityType.GLOW_SQUID, GlowSquid.createAttributes().build()).put(EntityType.GOAT, Goat.createAttributes().build()).put(EntityType.GUARDIAN, Guardian.createAttributes().build()).put(EntityType.HOGLIN, Hoglin.createAttributes().build()).put(EntityType.HORSE, AbstractHorse.createBaseHorseAttributes().build()).put(EntityType.HUSK, Zombie.createAttributes().build()).put(EntityType.ILLUSIONER, Illusioner.createAttributes().build()).put(EntityType.IRON_GOLEM, IronGolem.createAttributes().build()).put(EntityType.LLAMA, Llama.createAttributes().build()).put(EntityType.MAGMA_CUBE, MagmaCube.createAttributes().build()).put(EntityType.MOOSHROOM, Cow.createAttributes().build()).put(EntityType.MULE, AbstractChestedHorse.createBaseChestedHorseAttributes().build()).put(EntityType.OCELOT, Ocelot.createAttributes().build()).put(EntityType.PANDA, Panda.createAttributes().build()).put(EntityType.PARROT, Parrot.createAttributes().build()).put(EntityType.PHANTOM, Monster.createMonsterAttributes().build()).put(EntityType.PIG, Pig.createAttributes().build()).put(EntityType.PIGLIN, Piglin.createAttributes().build()).put(EntityType.PIGLIN_BRUTE, PiglinBrute.createAttributes().build()).put(EntityType.PILLAGER, Pillager.createAttributes().build()).put(EntityType.PLAYER, Player.createAttributes().build()).put(EntityType.POLAR_BEAR, PolarBear.createAttributes().build()).put(EntityType.PUFFERFISH, AbstractFish.createAttributes().build()).put(EntityType.RABBIT, Rabbit.createAttributes().build()).put(EntityType.RAVAGER, Ravager.createAttributes().build()).put(EntityType.SALMON, AbstractFish.createAttributes().build()).put(EntityType.SHEEP, Sheep.createAttributes().build()).put(EntityType.SHULKER, Shulker.createAttributes().build()).put(EntityType.SILVERFISH, Silverfish.createAttributes().build()).put(EntityType.SKELETON, AbstractSkeleton.createAttributes().build()).put(EntityType.SKELETON_HORSE, SkeletonHorse.createAttributes().build()).put(EntityType.SLIME, Monster.createMonsterAttributes().build()).put(EntityType.SNIFFER, Sniffer.createAttributes().build()).put(EntityType.SNOW_GOLEM, SnowGolem.createAttributes().build()).put(EntityType.SPIDER, Spider.createAttributes().build()).put(EntityType.SQUID, Squid.createAttributes().build()).put(EntityType.STRAY, AbstractSkeleton.createAttributes().build()).put(EntityType.STRIDER, Strider.createAttributes().build()).put(EntityType.TADPOLE, Tadpole.createAttributes().build()).put(EntityType.TRADER_LLAMA, Llama.createAttributes().build()).put(EntityType.TROPICAL_FISH, AbstractFish.createAttributes().build()).put(EntityType.TURTLE, Turtle.createAttributes().build()).put(EntityType.VEX, Vex.createAttributes().build()).put(EntityType.VILLAGER, Villager.createAttributes().build()).put(EntityType.VINDICATOR, Vindicator.createAttributes().build()).put(EntityType.WARDEN, Warden.createAttributes().build()).put(EntityType.WANDERING_TRADER, Mob.createMobAttributes().build()).put(EntityType.WITCH, Witch.createAttributes().build()).put(EntityType.WITHER, WitherBoss.createAttributes().build()).put(EntityType.WITHER_SKELETON, AbstractSkeleton.createAttributes().build()).put(EntityType.WOLF, Wolf.createAttributes().build()).put(EntityType.ZOGLIN, Zoglin.createAttributes().build()).put(EntityType.ZOMBIE, Zombie.createAttributes().build()).put(EntityType.ZOMBIE_HORSE, ZombieHorse.createAttributes().build()).put(EntityType.ZOMBIE_VILLAGER, Zombie.createAttributes().build()).put(EntityType.ZOMBIFIED_PIGLIN, ZombifiedPiglin.createAttributes().build()).build(); + private static final Map, AttributeSupplier> SUPPLIERS = ImmutableMap., AttributeSupplier>builder() -+ .put(EntityType.ALLAY, Allay.createAttributes().build()) -+ .put(EntityType.ARMOR_STAND, LivingEntity.createLivingAttributes().build()) -+ .put(EntityType.AXOLOTL, Axolotl.createAttributes().build()) -+ .put(EntityType.BAT, Bat.createAttributes().build()) -+ .put(EntityType.BEE, Bee.createAttributes().build()) -+ .put(EntityType.BLAZE, Blaze.createAttributes().build()) -+ .put(EntityType.CAT, Cat.createAttributes().build()) -+ .put(EntityType.CAMEL, Camel.createAttributes().build()) -+ .put(EntityType.CAVE_SPIDER, CaveSpider.createCaveSpider().build()) -+ .put(EntityType.CHICKEN, Chicken.createAttributes().build()) -+ .put(EntityType.COD, AbstractFish.createAttributes().build()) -+ .put(EntityType.COW, Cow.createAttributes().build()) -+ .put(EntityType.CREEPER, Creeper.createAttributes().build()) -+ .put(EntityType.DOLPHIN, Dolphin.createAttributes().build()) -+ .put(EntityType.DONKEY, AbstractChestedHorse.createBaseChestedHorseAttributes().build()) -+ .put(EntityType.DROWNED, Zombie.createAttributes().build()) -+ .put(EntityType.ELDER_GUARDIAN, ElderGuardian.createAttributes().build()) -+ .put(EntityType.ENDERMAN, EnderMan.createAttributes().build()) -+ .put(EntityType.ENDERMITE, Endermite.createAttributes().build()) -+ .put(EntityType.ENDER_DRAGON, EnderDragon.createAttributes().build()) -+ .put(EntityType.EVOKER, Evoker.createAttributes().build()) -+ .put(EntityType.FOX, Fox.createAttributes().build()) -+ .put(EntityType.FROG, Frog.createAttributes().build()) -+ .put(EntityType.GHAST, Ghast.createAttributes().build()) -+ .put(EntityType.GIANT, Giant.createAttributes().build()) -+ .put(EntityType.GLOW_SQUID, GlowSquid.createAttributes().build()) -+ .put(EntityType.GOAT, Goat.createAttributes().build()) -+ .put(EntityType.GUARDIAN, Guardian.createAttributes().build()) -+ .put(EntityType.HOGLIN, Hoglin.createAttributes().build()) -+ .put(EntityType.HORSE, AbstractHorse.createBaseHorseAttributes().build()) -+ .put(EntityType.HUSK, Zombie.createAttributes().build()) -+ .put(EntityType.ILLUSIONER, Illusioner.createAttributes().build()) -+ .put(EntityType.IRON_GOLEM, IronGolem.createAttributes().build()) -+ .put(EntityType.LLAMA, Llama.createAttributes().build()) -+ .put(EntityType.MAGMA_CUBE, MagmaCube.createAttributes().build()) -+ .put(EntityType.MOOSHROOM, Cow.createAttributes().build()) -+ .put(EntityType.MULE, AbstractChestedHorse.createBaseChestedHorseAttributes().build()) -+ .put(EntityType.OCELOT, Ocelot.createAttributes().build()) -+ .put(EntityType.PANDA, Panda.createAttributes().build()) -+ .put(EntityType.PARROT, Parrot.createAttributes().build()) -+ .put(EntityType.PHANTOM, net.minecraft.world.entity.monster.Phantom.createAttributes().build()) // Purpur -+ .put(EntityType.PIG, Pig.createAttributes().build()) -+ .put(EntityType.PIGLIN, Piglin.createAttributes().build()) -+ .put(EntityType.PIGLIN_BRUTE, PiglinBrute.createAttributes().build()) -+ .put(EntityType.PILLAGER, Pillager.createAttributes().build()) -+ .put(EntityType.PLAYER, Player.createAttributes().build()) -+ .put(EntityType.POLAR_BEAR, PolarBear.createAttributes().build()) -+ .put(EntityType.PUFFERFISH, AbstractFish.createAttributes().build()) -+ .put(EntityType.RABBIT, Rabbit.createAttributes().build()) -+ .put(EntityType.RAVAGER, Ravager.createAttributes().build()) -+ .put(EntityType.SALMON, AbstractFish.createAttributes().build()) -+ .put(EntityType.SHEEP, Sheep.createAttributes().build()) -+ .put(EntityType.SHULKER, Shulker.createAttributes().build()) -+ .put(EntityType.SILVERFISH, Silverfish.createAttributes().build()) -+ .put(EntityType.SKELETON, AbstractSkeleton.createAttributes().build()) -+ .put(EntityType.SKELETON_HORSE, SkeletonHorse.createAttributes().build()) -+ .put(EntityType.SLIME, Monster.createMonsterAttributes().build()) -+ .put(EntityType.SNIFFER, Sniffer.createAttributes().build()) -+ .put(EntityType.SNOW_GOLEM, SnowGolem.createAttributes().build()) -+ .put(EntityType.SPIDER, Spider.createAttributes().build()) -+ .put(EntityType.SQUID, Squid.createAttributes().build()) -+ .put(EntityType.STRAY, AbstractSkeleton.createAttributes().build()) -+ .put(EntityType.STRIDER, Strider.createAttributes().build()) -+ .put(EntityType.TADPOLE, Tadpole.createAttributes().build()) -+ .put(EntityType.TRADER_LLAMA, Llama.createAttributes().build()) -+ .put(EntityType.TROPICAL_FISH, AbstractFish.createAttributes().build()) -+ .put(EntityType.TURTLE, Turtle.createAttributes().build()) -+ .put(EntityType.VEX, Vex.createAttributes().build()) -+ .put(EntityType.VILLAGER, Villager.createAttributes().build()) -+ .put(EntityType.VINDICATOR, Vindicator.createAttributes().build()) -+ .put(EntityType.WARDEN, Warden.createAttributes().build()) -+ .put(EntityType.WANDERING_TRADER, Mob.createMobAttributes().build()) -+ .put(EntityType.WITCH, Witch.createAttributes().build()) -+ .put(EntityType.WITHER, WitherBoss.createAttributes().build()) -+ .put(EntityType.WITHER_SKELETON, AbstractSkeleton.createAttributes().build()) -+ .put(EntityType.WOLF, Wolf.createAttributes().build()) -+ .put(EntityType.ZOGLIN, Zoglin.createAttributes().build()) -+ .put(EntityType.ZOMBIE, Zombie.createAttributes().build()) -+ .put(EntityType.ZOMBIE_HORSE, ZombieHorse.createAttributes().build()) -+ .put(EntityType.ZOMBIE_VILLAGER, Zombie.createAttributes().build()) -+ .put(EntityType.ZOMBIFIED_PIGLIN, ZombifiedPiglin.createAttributes().build()).build(); ++ .put(EntityType.ALLAY, Allay.createAttributes().build()) ++ .put(EntityType.ARMOR_STAND, LivingEntity.createLivingAttributes().build()) ++ .put(EntityType.AXOLOTL, Axolotl.createAttributes().build()) ++ .put(EntityType.BAT, Bat.createAttributes().build()) ++ .put(EntityType.BEE, Bee.createAttributes().build()) ++ .put(EntityType.BLAZE, Blaze.createAttributes().build()) ++ .put(EntityType.CAT, Cat.createAttributes().build()) ++ .put(EntityType.CAMEL, Camel.createAttributes().build()) ++ .put(EntityType.CAVE_SPIDER, CaveSpider.createCaveSpider().build()) ++ .put(EntityType.CHICKEN, Chicken.createAttributes().build()) ++ .put(EntityType.COD, AbstractFish.createAttributes().build()) ++ .put(EntityType.COW, Cow.createAttributes().build()) ++ .put(EntityType.CREEPER, Creeper.createAttributes().build()) ++ .put(EntityType.DOLPHIN, Dolphin.createAttributes().build()) ++ .put(EntityType.DONKEY, AbstractChestedHorse.createBaseChestedHorseAttributes().build()) ++ .put(EntityType.DROWNED, Zombie.createAttributes().build()) ++ .put(EntityType.ELDER_GUARDIAN, ElderGuardian.createAttributes().build()) ++ .put(EntityType.ENDERMAN, EnderMan.createAttributes().build()) ++ .put(EntityType.ENDERMITE, Endermite.createAttributes().build()) ++ .put(EntityType.ENDER_DRAGON, EnderDragon.createAttributes().build()) ++ .put(EntityType.EVOKER, Evoker.createAttributes().build()) ++ .put(EntityType.BREEZE, Breeze.createAttributes().build()) ++ .put(EntityType.FOX, Fox.createAttributes().build()) ++ .put(EntityType.FROG, Frog.createAttributes().build()) ++ .put(EntityType.GHAST, Ghast.createAttributes().build()) ++ .put(EntityType.GIANT, Giant.createAttributes().build()) ++ .put(EntityType.GLOW_SQUID, GlowSquid.createAttributes().build()) ++ .put(EntityType.GOAT, Goat.createAttributes().build()) ++ .put(EntityType.GUARDIAN, Guardian.createAttributes().build()) ++ .put(EntityType.HOGLIN, Hoglin.createAttributes().build()) ++ .put(EntityType.HORSE, AbstractHorse.createBaseHorseAttributes().build()) ++ .put(EntityType.HUSK, Zombie.createAttributes().build()) ++ .put(EntityType.ILLUSIONER, Illusioner.createAttributes().build()) ++ .put(EntityType.IRON_GOLEM, IronGolem.createAttributes().build()) ++ .put(EntityType.LLAMA, Llama.createAttributes().build()) ++ .put(EntityType.MAGMA_CUBE, MagmaCube.createAttributes().build()) ++ .put(EntityType.MOOSHROOM, Cow.createAttributes().build()) ++ .put(EntityType.MULE, AbstractChestedHorse.createBaseChestedHorseAttributes().build()) ++ .put(EntityType.OCELOT, Ocelot.createAttributes().build()) ++ .put(EntityType.PANDA, Panda.createAttributes().build()) ++ .put(EntityType.PARROT, Parrot.createAttributes().build()) ++ .put(EntityType.PHANTOM, net.minecraft.world.entity.monster.Phantom.createAttributes().build()) // Purpur ++ .put(EntityType.PIG, Pig.createAttributes().build()) ++ .put(EntityType.PIGLIN, Piglin.createAttributes().build()) ++ .put(EntityType.PIGLIN_BRUTE, PiglinBrute.createAttributes().build()) ++ .put(EntityType.PILLAGER, Pillager.createAttributes().build()) ++ .put(EntityType.PLAYER, Player.createAttributes().build()) ++ .put(EntityType.POLAR_BEAR, PolarBear.createAttributes().build()) ++ .put(EntityType.PUFFERFISH, AbstractFish.createAttributes().build()) ++ .put(EntityType.RABBIT, Rabbit.createAttributes().build()) ++ .put(EntityType.RAVAGER, Ravager.createAttributes().build()) ++ .put(EntityType.SALMON, AbstractFish.createAttributes().build()) ++ .put(EntityType.SHEEP, Sheep.createAttributes().build()) ++ .put(EntityType.SHULKER, Shulker.createAttributes().build()) ++ .put(EntityType.SILVERFISH, Silverfish.createAttributes().build()) ++ .put(EntityType.SKELETON, AbstractSkeleton.createAttributes().build()) ++ .put(EntityType.SKELETON_HORSE, SkeletonHorse.createAttributes().build()) ++ .put(EntityType.SLIME, Monster.createMonsterAttributes().build()) ++ .put(EntityType.SNIFFER, Sniffer.createAttributes().build()) ++ .put(EntityType.SNOW_GOLEM, SnowGolem.createAttributes().build()) ++ .put(EntityType.SPIDER, Spider.createAttributes().build()) ++ .put(EntityType.SQUID, Squid.createAttributes().build()) ++ .put(EntityType.STRAY, AbstractSkeleton.createAttributes().build()) ++ .put(EntityType.STRIDER, Strider.createAttributes().build()) ++ .put(EntityType.TADPOLE, Tadpole.createAttributes().build()) ++ .put(EntityType.TRADER_LLAMA, Llama.createAttributes().build()) ++ .put(EntityType.TROPICAL_FISH, AbstractFish.createAttributes().build()) ++ .put(EntityType.TURTLE, Turtle.createAttributes().build()) ++ .put(EntityType.VEX, Vex.createAttributes().build()) ++ .put(EntityType.VILLAGER, Villager.createAttributes().build()) ++ .put(EntityType.VINDICATOR, Vindicator.createAttributes().build()) ++ .put(EntityType.WARDEN, Warden.createAttributes().build()) ++ .put(EntityType.WANDERING_TRADER, Mob.createMobAttributes().build()) ++ .put(EntityType.WITCH, Witch.createAttributes().build()) ++ .put(EntityType.WITHER, WitherBoss.createAttributes().build()) ++ .put(EntityType.WITHER_SKELETON, AbstractSkeleton.createAttributes().build()) ++ .put(EntityType.WOLF, Wolf.createAttributes().build()) ++ .put(EntityType.ZOGLIN, Zoglin.createAttributes().build()) ++ .put(EntityType.ZOMBIE, Zombie.createAttributes().build()) ++ .put(EntityType.ZOMBIE_HORSE, ZombieHorse.createAttributes().build()) ++ .put(EntityType.ZOMBIE_VILLAGER, Zombie.createAttributes().build()) ++ .put(EntityType.ZOMBIFIED_PIGLIN, ZombifiedPiglin.createAttributes().build()).build(); public static AttributeSupplier getSupplier(EntityType type) { return SUPPLIERS.get(type); @@ -5929,7 +5986,7 @@ index a85885ee51df585fa11ae9f8fcd67ff2a71c5a18..d81509e08e70ec5b2f837c9dc66b1254 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java -index 93bbda61f0eb2dd52573602b1f9cc7b031d1fc5a..63f9e5e2490e5b2fec6f2395077e21e601804ca5 100644 +index 4e2c23ccdf4e4a4d65b291dbe20952bae1838bff..0da884a833f6c707fea512e826658c3bb73f7a77 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java @@ -74,7 +74,7 @@ public class EatBlockGoal extends Goal { @@ -6039,7 +6096,7 @@ index 87fb10096fc9dade33c663234b1cecc34d3d77bb..874c7b29a261b1b5ad6e86ca219ff935 if (this.mob.isUsingItem()) { if (!bl && this.seeTime < -60) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java -index 509317a26c79f453335df1c19dc4c9ec570046af..8e4d673e4f2d7f50ea5ed13794da08b1d20e6665 100644 +index 5580a396a56c6e0f364a5368985ee99b9e2be0a8..3facfd6eee17cb0b59425494c966e19833660dd2 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java @@ -40,7 +40,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal { @@ -6191,10 +6248,10 @@ index ac5e5676b194a2a99e5cf53eb89c1152cac963b8..872454743f6dedc27519a13566559195 if (baseEntity == null) { if (this.isCombat && (!targetEntity.canBeSeenAsEnemy() || targetEntity.level().getDifficulty() == Difficulty.PEACEFUL)) { diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea60cc7021c 100644 +index 8820905ac733a8915cc1697259b2bef14d97e471..bae3c516b0d13358603576d87a18602a0522a9ff 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -18,6 +18,7 @@ import net.minecraft.world.entity.EntityDimensions; +@@ -19,6 +19,7 @@ import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MobSpawnType; @@ -6202,7 +6259,7 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; -@@ -43,12 +44,59 @@ public class Bat extends AmbientCreature { +@@ -46,12 +47,59 @@ public class Bat extends AmbientCreature { public Bat(EntityType type, Level world) { super(type, world); @@ -6261,8 +6318,8 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 + @Override public boolean isFlapping() { - return !this.isResting() && this.tickCount % Bat.TICKS_PER_FLAP == 0; -@@ -98,7 +146,7 @@ public class Bat extends AmbientCreature { + return !this.isResting() && (float) this.tickCount % 10.0F == 0.0F; +@@ -101,7 +149,7 @@ public class Bat extends AmbientCreature { protected void pushEntities() {} public static AttributeSupplier.Builder createAttributes() { @@ -6271,7 +6328,7 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 } public boolean isResting() { -@@ -130,6 +178,14 @@ public class Bat extends AmbientCreature { +@@ -134,6 +182,14 @@ public class Bat extends AmbientCreature { @Override protected void customServerAiStep() { @@ -6286,7 +6343,7 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 super.customServerAiStep(); BlockPos blockposition = this.blockPosition(); BlockPos blockposition1 = blockposition.above(); -@@ -208,6 +264,28 @@ public class Bat extends AmbientCreature { +@@ -212,6 +268,28 @@ public class Bat extends AmbientCreature { } } @@ -6315,7 +6372,7 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 @Override public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); -@@ -227,7 +305,7 @@ public class Bat extends AmbientCreature { +@@ -231,7 +309,7 @@ public class Bat extends AmbientCreature { int i = world.getMaxLocalRawBrightness(pos); byte b0 = 4; @@ -6324,7 +6381,7 @@ index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea6 b0 = 7; } else if (random.nextBoolean()) { return false; -@@ -241,6 +319,7 @@ public class Bat extends AmbientCreature { +@@ -245,6 +323,7 @@ public class Bat extends AmbientCreature { private static boolean isSpookySeason = false; private static final int ONE_HOUR = 20 * 60 * 60; private static int lastSpookyCheck = -ONE_HOUR; @@ -6389,7 +6446,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 a836bfd2ea8af8098a20fb37ca25a5a613226f67..a434d91b8dfff30cff81df964ea8149caa8cb604 100644 +index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83c346eb85 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 { @@ -6400,16 +6457,16 @@ index a836bfd2ea8af8098a20fb37ca25a5a613226f67..a434d91b8dfff30cff81df964ea8149c protected Animal(EntityType type, Level world) { super(type, world); -@@ -149,7 +150,7 @@ public abstract class Animal extends AgeableMob { +@@ -151,7 +152,7 @@ public abstract class Animal extends AgeableMob { if (this.isFood(itemstack)) { int i = this.getAge(); - 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 + final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying this.usePlayerItem(player, hand, itemstack); - this.setInLove(player, breedCopy); // Paper -@@ -240,12 +241,20 @@ public abstract class Animal extends AgeableMob { + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying +@@ -242,12 +243,20 @@ public abstract class Animal extends AgeableMob { AgeableMob entityageable = this.getBreedOffspring(world, other); if (entityageable != null) { @@ -6433,7 +6490,7 @@ index a836bfd2ea8af8098a20fb37ca25a5a613226f67..a434d91b8dfff30cff81df964ea8149c 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()) { -@@ -273,8 +282,10 @@ public abstract class Animal extends AgeableMob { +@@ -275,8 +284,10 @@ public abstract class Animal extends AgeableMob { entityplayer.awardStat(Stats.ANIMALS_BRED); CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable); } // Paper @@ -6447,7 +6504,7 @@ index a836bfd2ea8af8098a20fb37ca25a5a613226f67..a434d91b8dfff30cff81df964ea8149c 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 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64bc7fffd0 100644 +index a87a34b0c4c8e5d0cf079025c230b1434c919b54..bdb78cc701543cfe91a6bafd1786fe2ea0bf1ddc 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; @@ -6553,7 +6610,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(new Class[0])); this.targetSelector.addGoal(2, new Bee.BeeBecomeAngryTargetGoal(this)); this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); -@@ -348,7 +399,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -355,7 +406,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { boolean wantsToEnterHive() { if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { @@ -6562,7 +6619,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 return flag && !this.isHiveNearFire(); } else { -@@ -388,6 +439,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -395,6 +446,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.hurt(this.damageSources().drown(), 1.0F); } @@ -6570,7 +6627,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 if (flag) { ++this.timeSinceSting; if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { -@@ -420,6 +472,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -427,6 +479,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -6597,7 +6654,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 @Override public int getRemainingPersistentAngerTime() { return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME); -@@ -735,6 +807,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -742,6 +814,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { if (optional.isPresent()) { Bee.this.savedFlowerPos = (BlockPos) optional.get(); Bee.this.navigation.moveTo((double) Bee.this.savedFlowerPos.getX() + 0.5D, (double) Bee.this.savedFlowerPos.getY() + 0.5D, (double) Bee.this.savedFlowerPos.getZ() + 0.5D, 1.2000000476837158D); @@ -6605,7 +6662,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 return true; } else { Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); -@@ -791,6 +864,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -798,6 +871,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.pollinating = false; Bee.this.navigation.stop(); Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; @@ -6613,7 +6670,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 } @Override -@@ -837,6 +911,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -844,6 +918,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setWantedPos(); } @@ -6621,7 +6678,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..38a3dcec138d9233a46e5d523bcc6d64 ++this.successfulPollinatingTicks; if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { this.lastSoundPlayedTick = this.successfulPollinatingTicks; -@@ -881,16 +956,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -888,16 +963,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -7058,7 +7115,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 c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd4df32a47 100644 +index e555fd8ca61e1ce7a52ecd475cc3ea11dedcab08..ed2769d8049bb304c1ee3b8e162046855951a624 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 { @@ -7167,7 +7224,7 @@ index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); } -@@ -164,17 +249,21 @@ public class Dolphin extends WaterAnimal { +@@ -159,17 +244,21 @@ public class Dolphin extends WaterAnimal { protected void registerGoals() { this.goalSelector.addGoal(0, new BreathAirGoal(this)); this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); @@ -7190,7 +7247,7 @@ index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd } public static AttributeSupplier.Builder createAttributes() { -@@ -225,7 +314,7 @@ public class Dolphin extends WaterAnimal { +@@ -220,7 +309,7 @@ public class Dolphin extends WaterAnimal { @Override protected boolean canRide(Entity entity) { @@ -7199,7 +7256,7 @@ index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd } @Override -@@ -260,6 +349,11 @@ public class Dolphin extends WaterAnimal { +@@ -255,6 +344,11 @@ public class Dolphin extends WaterAnimal { @Override public void tick() { super.tick(); @@ -7211,7 +7268,7 @@ index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd if (this.isNoAi()) { this.setAirSupply(this.getMaxAirSupply()); } else { -@@ -405,6 +499,7 @@ public class Dolphin extends WaterAnimal { +@@ -400,6 +494,7 @@ public class Dolphin extends WaterAnimal { @Override public boolean canUse() { @@ -7220,7 +7277,7 @@ index c528cb7c18650863eaf8e2c6c0d9276c02712cc9..1807c7bac6f5012da8130dd41edeb9dd } 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 9e2af80c6a87f5849710266149cbca8cabfad4f8..075554f28dab5809d0f2d346bad40efc16b38371 100644 +index 3d771b137dc29579614aa4c15d12bd456cdc608a..0f631ba08d255ce5a1e28f51b591a4d9ae1a68fe 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; @@ -7537,7 +7594,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 e42b0b19019ef74733fd19b08f882cccff920142..6ce116dc3173d17b19c4c03fe9cf494dd022f0d5 100644 +index 7a82ba6e29fde33841c049e8520300aa66608f34..3f00d40125b63a76ed549755d4c9d9a2ff2d4adf 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 drops = this.generateDefaultDrops(); ++ List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + if (event != null) { + if (event.isCancelled()) { +- return InteractionResult.PASS; ++ return tryRide(player, hand); // Purpur + } + drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); } - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur - this.gameEvent(GameEvent.SHEAR, player); - if (!this.level().isClientSide) { - itemstack.hurtAndBreak(1, player, (entityhuman1) -> { -@@ -144,7 +181,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder> optional = this.getEffectsFromItemStack(itemstack); if (optional.isEmpty()) { @@ -7606,16 +7664,24 @@ index e42b0b19019ef74733fd19b08f882cccff920142..6ce116dc3173d17b19c4c03fe9cf494d } if (!player.getAbilities().instabuild) { -@@ -166,7 +203,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder generateDefaultDrops() { ++ public List generateDefaultDrops(int looting) { // Purpur + List dropEntities = new java.util.ArrayList<>(5); +- for (int i = 0; i < 5; ++i) { ++ for (int i = 0; i < 5 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); ++i) { // Purpur + dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock())); + } + return dropEntities; +@@ -199,7 +236,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder type, Level world) { super(type, world); @@ -7938,7 +7995,7 @@ index 397264d31992fd43bd57736c25693ae001330b6d..d97ca9d567df224c34eba306b4c9b7df @Nullable @Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { -@@ -154,8 +230,11 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { -@@ -307,13 +387,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder { - entityhuman1.broadcastBreakEvent(hand); -@@ -272,14 +310,15 @@ public class Sheep extends Animal implements Shearable { +@@ -254,7 +292,7 @@ public class Sheep extends Animal implements Shearable { + if (!this.level().isClientSide && this.readyForShearing()) { + // CraftBukkit start + // Paper start - custom shear drops +- java.util.List drops = this.generateDefaultDrops(); ++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + if (event != null) { + if (event.isCancelled()) { +@@ -281,12 +319,13 @@ public class Sheep extends Animal implements Shearable { + @Override + public void shear(SoundSource shearedSoundCategory) { + // Paper start - custom shear drops +- this.shear(shearedSoundCategory, this.generateDefaultDrops()); ++ this.shear(shearedSoundCategory, this.generateDefaultDrops(0)); // Purpur } @Override -- public void shear(SoundSource shearedSoundCategory) { -+ public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur - this.level().playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - this.setSheared(true); - int i = 1 + this.random.nextInt(3); -+ if (org.purpurmc.purpur.PurpurConfig.allowShearsLooting) i += looting; // Purpur - - for (int j = 0; j < i; ++j) { - this.forceDrops = true; // CraftBukkit -- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1); -+ ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.level().purpurConfig.sheepShearJebRandomColor && hasCustomName() && getCustomName().getString().equals("jeb_") ? DyeColor.random(this.level().random) : this.getColor()), 1); // Purpur - this.forceDrops = false; // CraftBukkit - - if (entityitem != null) { +- public java.util.List generateDefaultDrops() { ++ public java.util.List generateDefaultDrops(int looting) { // Purpur + int count = 1 + this.random.nextInt(3); ++ if (org.purpurmc.purpur.PurpurConfig.allowShearsLooting) count += looting; // Purpur + java.util.List dropEntities = new java.util.ArrayList<>(count); + for (int j = 0; j < count; ++j) { + dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor()))); diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java -index 8adcfc8f6772a32b5915e4a07100e8eb735f907a..8b364fe9f3a3d47ae6daa331b8f16941ca17432a 100644 +index b5d6857eaf2bed14adcb5f5e80d91b44eb8b0dcc..c30b00e5637d3def256c93cc227a15ddaf99bc56 100644 --- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java @@ -49,17 +49,56 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM @@ -8637,20 +8692,21 @@ index 8adcfc8f6772a32b5915e4a07100e8eb735f907a..8b364fe9f3a3d47ae6daa331b8f16941 BlockState iblockdata = Blocks.SNOW.defaultBlockState(); for (int i = 0; i < 4; ++i) { -@@ -154,10 +196,10 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -154,11 +196,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { // CraftBukkit start - if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { -- return InteractionResult.PASS; -+ return tryRide(player, hand); // Purpur + // Paper start - custom shear drops +- java.util.List drops = this.generateDefaultDrops(); ++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + if (event != null) { + if (event.isCancelled()) { +- return InteractionResult.PASS; ++ return tryRide(player, hand); // Purpur + } + drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); } - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur - this.gameEvent(GameEvent.SHEAR, player); - if (!this.level().isClientSide) { - itemstack.hurtAndBreak(1, player, (entityhuman1) -> { -@@ -166,17 +208,27 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -173,19 +215,36 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM } return InteractionResult.sidedSuccess(this.level().isClientSide); @@ -8669,17 +8725,27 @@ index 8adcfc8f6772a32b5915e4a07100e8eb735f907a..8b364fe9f3a3d47ae6daa331b8f16941 } @Override -- public void shear(SoundSource shearedSoundCategory) { -+ public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur - this.level().playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - if (!this.level().isClientSide()) { - this.setPumpkin(false); - this.forceDrops = true; // CraftBukkit -+ if (level().purpurConfig.snowGolemDropsPumpkin) // Purpur -+ for (int i = 0; i < 1 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); i++) // Purpur - this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), 1.7F); - this.forceDrops = false; // CraftBukkit - } + public void shear(SoundSource shearedSoundCategory) { + // Paper start - custom shear drops +- this.shear(shearedSoundCategory, this.generateDefaultDrops()); ++ this.shear(shearedSoundCategory, this.generateDefaultDrops(0)); // Purpur + } + + @Override +- public java.util.List generateDefaultDrops() { ++ // Purpur start ++ public java.util.List generateDefaultDrops(int looting) { ++ if (org.purpurmc.purpur.PurpurConfig.allowShearsLooting) { ++ java.util.ArrayList list = new java.util.ArrayList<>(); ++ for (int i = 0; i < 1 + looting; i++) { ++ list.add(new ItemStack(Items.CARVED_PUMPKIN)); ++ } ++ return java.util.Collections.unmodifiableList(list); ++ } ++ // Purpur end + return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN)); + } + diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java index f60c4cd0543fd5d50fa7e2c1a9e8381227adb540..dd7f2beabf0edad4143ac2365ac04a22edf1f75e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Squid.java @@ -8842,7 +8908,7 @@ index b05b560b7570e97bc234b75f26233909fcf575b3..87b6f6b10ba6e3d9c6a42298a2019a52 return "entity.minecraft.tropical_fish.predefined." + variant; } diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 490472bb618e9ac07da5883a71dff8920525b1e2..c8f3be5fd869f62472d5a248f9c02700dac0ac69 100644 +index d8056421249c8e75e96a55ec07dce84d2bba9c5c..8f891e9fd9fc0bf4a9c022a3415b371cea9b92fa 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -86,6 +86,43 @@ public class Turtle extends Animal { @@ -8897,7 +8963,7 @@ index 490472bb618e9ac07da5883a71dff8920525b1e2..c8f3be5fd869f62472d5a248f9c02700 this.goalSelector.addGoal(0, new Turtle.TurtlePanicGoal(this, 1.2D)); this.goalSelector.addGoal(1, new Turtle.TurtleBreedGoal(this, 1.0D)); this.goalSelector.addGoal(1, new Turtle.TurtleLayEggGoal(this, 1.0D)); -@@ -351,13 +389,15 @@ public class Turtle extends Animal { +@@ -346,13 +384,15 @@ public class Turtle extends Animal { return new Vector3f(0.0F, dimensions.height + (this.isBaby() ? 0.0F : 0.15625F) * scaleFactor, -0.25F * scaleFactor); } @@ -8914,27 +8980,16 @@ index 490472bb618e9ac07da5883a71dff8920525b1e2..c8f3be5fd869f62472d5a248f9c02700 } private void updateSpeed() { -@@ -376,8 +416,18 @@ public class Turtle extends Animal { - +@@ -372,7 +412,7 @@ public class Turtle extends Animal { } -+ // Purpur start -+ public void purpurTick(Player rider) { -+ if (turtle.isInWater()) { -+ waterController.purpurTick(rider); -+ } else { -+ super.purpurTick(rider); -+ } -+ } -+ // Purpur end -+ @Override - public void tick() { + public void vanillaTick() { // Purpur this.updateSpeed(); if (this.operation == MoveControl.Operation.MOVE_TO && !this.turtle.getNavigation().isDone()) { double d0 = this.wantedX - this.turtle.getX(); -@@ -393,7 +443,7 @@ public class Turtle extends Animal { +@@ -388,7 +428,7 @@ public class Turtle extends Animal { this.turtle.setYRot(this.rotlerp(this.turtle.getYRot(), f, 90.0F)); this.turtle.yBodyRot = this.turtle.getYRot(); @@ -8944,10 +8999,10 @@ index 490472bb618e9ac07da5883a71dff8920525b1e2..c8f3be5fd869f62472d5a248f9c02700 this.turtle.setSpeed(Mth.lerp(0.125F, this.turtle.getSpeed(), f1)); this.turtle.setDeltaMovement(this.turtle.getDeltaMovement().add(0.0D, (double) this.turtle.getSpeed() * d1 * 0.1D, 0.0D)); diff --git a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java -index cd2ce5bcb8c30e4657cd0e340d80544c7e805905..c8c6fed3f93903bb5c6145930538d415f6f59738 100644 +index 827912174ee08cd19249797d351887149b25c880..5b02848ea9f14060353014cada2d55397609e5ac 100644 --- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java +++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java -@@ -82,6 +82,6 @@ public abstract class WaterAnimal extends PathfinderMob { +@@ -77,6 +77,6 @@ public abstract class WaterAnimal extends PathfinderMob { i = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(i); j = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(j); // Paper end @@ -9323,7 +9378,7 @@ index d241ca4d0295f9fce39c11197bd435cfac7f6e54..c783ce59ea766e6c46a3313628b961f2 private boolean allayConsidersItemEqual(ItemStack stack, ItemStack stack2) { 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 b4793b88688bd568a428aa520e880f0038de45a7..7369290820f726c28c87bc63dba2a74f415bb126 100644 +index 9158c5a507904c46a8fe2fdad9a0b6ba3a9b2460..e4d529825e681bbc656113b1fd44894338e23d21 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 @@ -98,6 +98,43 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder getModelRotationValues() { return this.modelRotationValues; -@@ -283,13 +320,13 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder optional = this.getBrain().getMemory(MemoryModuleType.PLAY_DEAD_TICKS); -@@ -516,14 +553,22 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { @@ -9563,7 +9618,7 @@ index c8e3d47b3f2dc919cca8ad397095437f1da6c762..9417ce67cc231d5bfa6813f78ec27196 @Override protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -167,13 +220,13 @@ public class Frog extends Animal implements VariantHolder { +@@ -162,13 +215,13 @@ public class Frog extends Animal implements VariantHolder { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { @@ -9582,7 +9637,7 @@ index c8e3d47b3f2dc919cca8ad397095437f1da6c762..9417ce67cc231d5bfa6813f78ec27196 super.customServerAiStep(); } -@@ -354,7 +407,7 @@ public class Frog extends Animal implements VariantHolder { +@@ -349,7 +402,7 @@ public class Frog extends Animal implements VariantHolder { return world.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } @@ -9592,7 +9647,7 @@ index c8e3d47b3f2dc919cca8ad397095437f1da6c762..9417ce67cc231d5bfa6813f78ec27196 super(entity); } diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java -index 6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5..6b012bea26e8ef0c04571f43da67f6e108188830 100644 +index 6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5..14135dac80dec4224715e21cef6556d22e569026 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java @@ -45,13 +45,50 @@ public class Tadpole extends AbstractFish { @@ -9647,17 +9702,17 @@ index 6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5..6b012bea26e8ef0c04571f43da67f6e1 @Override protected PathNavigation createNavigation(Level world) { return new WaterBoundPathNavigation(this, world); -@@ -80,13 +117,13 @@ public class Tadpole extends AbstractFish { +@@ -80,13 +117,12 @@ public class Tadpole extends AbstractFish { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - this.level().getProfiler().push("tadpoleBrain"); - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ //this.level().getProfiler().push("tadpoleBrain"); // Purpur -+ 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.getBrain().tick((ServerLevel) this.level(), this); - this.level().getProfiler().pop(); - this.level().getProfiler().push("tadpoleActivityUpdate"); ++ //this.level().getProfiler().push("tadpoleBrain"); // Purpur ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider + //this.level().getProfiler().pop(); // Purpur + //this.level().getProfiler().push("tadpoleActivityUpdate"); // Purpur TadpoleAi.updateActivity(this); @@ -9737,7 +9792,7 @@ index ff12ba2b79cb2e7e0bfd0e3b58ff6cb9e770092b..5d7b20c30bc5e3be8511b300c318d12a brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position()); brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index a0628b9d74c29d02bfba583edf7ee6f2cde2cff6..bab9e413bd55d48e3e54bee66a6cd5be19a8f415 100644 +index d9539f5275c4cb63910ba79aa522d9569ad35a89..97684d00c79ab2e5712a3d44b7690b1bca15b4a7 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java @@ -149,12 +149,60 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, @@ -9818,7 +9873,7 @@ index a0628b9d74c29d02bfba583edf7ee6f2cde2cff6..bab9e413bd55d48e3e54bee66a6cd5be } protected int getInventorySize() { -@@ -1234,7 +1283,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -1231,7 +1280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, entityData = new AgeableMob.AgeableMobGroupData(0.2F); } @@ -9924,7 +9979,7 @@ index 5f5dc651d570989ec1294c31a14dcfede466b80a..3b1faa63e46a48e83ea672cf6da444a1 protected void randomizeAttributes(RandomSource random) { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue((double)generateMaxHealth(random::nextInt)); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -index 9120663b63fc0e365e8edb359892b0db1ee97875..b414572411e5b2b78fd66e860273656d53df9d9d 100644 +index 4863586b1c54192e0228342a0c36561348ebb3fb..0d0f0067d64de6ccf59b1d30ad0e77f530c5af6e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java @@ -75,9 +75,84 @@ public class Llama extends AbstractChestedHorse implements VariantHolder entitytypes, Level world) { super(EntityType.ENDER_DRAGON, world); -+ this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // Purpur - moved instantiation from field - this.fightOrigin = BlockPos.ZERO; - this.growlTime = 100; - this.nodes = new Node[24]; -@@ -128,7 +130,37 @@ public class EnderDragon extends Mob implements Enemy { - this.noPhysics = true; +@@ -129,6 +130,37 @@ public class EnderDragon extends Mob implements Enemy { this.noCulling = true; this.phaseManager = new EnderDragonPhaseManager(this); -- this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // CraftBukkit + this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE); // CraftBukkit + + // Purpur start + this.moveControl = new org.purpurmc.purpur.controller.FlyingMoveControllerWASD(this) { @@ -10671,7 +10721,7 @@ index a288180da1996103eb7dc3bb87b4615f86630bb8..7f3c914358a3d623b07dbb69abc23e13 short0 = 12000; } -@@ -1102,6 +1188,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -1103,6 +1189,7 @@ public class EnderDragon extends Mob implements Enemy { @Override protected boolean canRide(Entity entity) { @@ -10680,7 +10730,7 @@ index a288180da1996103eb7dc3bb87b4615f86630bb8..7f3c914358a3d623b07dbb69abc23e13 } diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3ec9289ee 100644 +index 1f7f6e5995c00725bf66723c75620ec416e24f87..d75f6032734ec76b498d32c952b15cb015f32674 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java @@ -84,20 +84,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @@ -10866,16 +10916,15 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 } @Override -@@ -141,7 +281,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -141,6 +281,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.hasCustomName()) { this.bossEvent.setName(this.getDisplayName()); } -- + if (nbt.contains("Purpur.Summoner")) setSummoner(nbt.getUUID("Purpur.Summoner")); // Purpur + } - @Override -@@ -263,6 +403,15 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -263,6 +404,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected void customServerAiStep() { @@ -10888,10 +10937,11 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 + shootCooldown--; + } + // Purpur end ++ int i; if (this.getInvulnerableTicks() > 0) { -@@ -279,7 +428,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -279,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } // CraftBukkit end @@ -10900,7 +10950,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 // 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 +452,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -304,7 +455,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob this.setInvulnerableTicks(i); if (this.tickCount % 10 == 0) { @@ -10909,7 +10959,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 } } else { -@@ -363,7 +512,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -364,7 +515,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.destroyBlocksTick > 0) { --this.destroyBlocksTick; @@ -10918,7 +10968,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 i = Mth.floor(this.getY()); j = Mth.floor(this.getX()); int i1 = Mth.floor(this.getZ()); -@@ -396,8 +545,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -397,8 +548,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } } @@ -10931,7 +10981,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -583,11 +734,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -584,11 +737,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } public int getAlternativeTarget(int headIndex) { @@ -10945,7 +10995,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 } @Override -@@ -602,6 +753,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -603,6 +756,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected boolean canRide(Entity entity) { @@ -10954,7 +11004,7 @@ index 256598e058db1fd34d36390e45ab9903768343cb..b300ebd589f2ce7393dd435cab5b80f3 } 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 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb15c630988 100644 +index a9c1f99ba2461333bd154ac16e812031f234f7a6..526943db39a61c6b281d44a1159ebbd8452b5798 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 { @@ -10978,7 +11028,7 @@ index 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb1 } public ArmorStand(Level world, double x, double y, double z) { -@@ -619,7 +622,7 @@ public class ArmorStand extends LivingEntity { +@@ -606,7 +609,7 @@ public class ArmorStand extends LivingEntity { private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper ItemStack itemstack = new ItemStack(Items.ARMOR_STAND); @@ -10987,7 +11037,7 @@ index 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb1 itemstack.setHoverName(this.getCustomName()); } -@@ -690,6 +693,7 @@ public class ArmorStand extends LivingEntity { +@@ -677,6 +680,7 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { @@ -10995,16 +11045,16 @@ index 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb1 // Paper start if (!this.canTick) { if (this.noTickPoseDirty) { -@@ -1024,4 +1028,18 @@ public class ArmorStand extends LivingEntity { +@@ -1004,4 +1008,18 @@ public class ArmorStand extends LivingEntity { + } } // Paper end - // Paper end + + // Purpur start + @Override + public void updateInWaterStateAndDoWaterCurrentPushing() { + if (this.level().purpurConfig.armorstandWaterMovement && -+ (this.level().purpurConfig.armorstandWaterFence || !(level().getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock))) ++ (this.level().purpurConfig.armorstandWaterFence || !(level().getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock))) + super.updateInWaterStateAndDoWaterCurrentPushing(); + } + @@ -11015,10 +11065,10 @@ index 523f14916073fb137578da777a23ba8265fd8af6..2b9b0acd20d2bf16d08ed89ba625dfb1 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..182faba889dc15a3500c5919cad8a5483a53033a 100644 +index c5ec729470aa2b17c6963605cd10b8f53bae5e59..fa94ffe6edf023dc16507d886e9d54ea58af0eec 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -273,7 +273,13 @@ public class ItemFrame extends HangingEntity { +@@ -268,7 +268,13 @@ public class ItemFrame extends HangingEntity { } if (alwaysDrop) { @@ -11062,7 +11112,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 e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..958e7684440fcc209fe33e882bf259d92a6814b1 100644 +index 45c07733f03b5c11f6d8e820f65dc950c70d9a67..8e9ab1335626493b8d74f71f643565c0e65af94c 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 { @@ -11084,13 +11134,13 @@ index e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..958e7684440fcc209fe33e882bf259d9 } // Paper end - fix sand duping diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..4f01fede54a3150798812d6e5116631bf897a29b 100644 +index c34c698d389da29c9cfaa56cb8023e30416a14ba..7844ee584b917485ce5e490ad040c2c1d732eb1d 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -56,6 +56,12 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -58,6 +58,12 @@ public class ItemEntity extends Entity implements TraceableEntity { public boolean canMobPickup = true; // Paper private int despawnRate = -1; // Paper - public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API + // Purpur start + public boolean immuneToCactus = false; + public boolean immuneToExplosion = false; @@ -11100,7 +11150,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..4f01fede54a3150798812d6e5116631b public ItemEntity(EntityType type, Level world) { super(type, world); -@@ -346,7 +352,16 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -364,7 +370,16 @@ public class ItemEntity extends Entity implements TraceableEntity { @Override public boolean hurt(DamageSource source, float amount) { @@ -11118,7 +11168,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..4f01fede54a3150798812d6e5116631b return false; } else if (!this.getItem().isEmpty() && this.getItem().is(Items.NETHER_STAR) && source.is(DamageTypeTags.IS_EXPLOSION)) { return false; -@@ -548,6 +563,12 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -567,6 +582,12 @@ public class ItemEntity extends Entity implements TraceableEntity { public void setItem(ItemStack stack) { this.getEntityData().set(ItemEntity.DATA_ITEM, stack); this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper @@ -11132,10 +11182,10 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..4f01fede54a3150798812d6e5116631b @Override diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..afc65b8bb7e7f7f70a25f2d869412ed325b658da 100644 +index c3e47426382296d650fa00ce0bc1a82bf23c7877..dfc3e9d2611ce418ac6f6cc5a23bb74415007713 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -175,4 +175,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -207,4 +207,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); } // Paper end @@ -11166,7 +11216,7 @@ index 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..afc65b8bb7e7f7f70a25f2d869412ed3 + // Purpur end - Shears can defuse TNT } diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -index b319021b22c5dceba6199ed27814b2dcf47b8d50..28eb98d383d6846a25c29f8cd8ff211c360a56dc 100644 +index a383c0c8b5c89ef1eef7d18edc3a09f749fdd310..68f45498405f5fd9a6f5525b9a59518a8b506aa8 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -66,16 +66,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @@ -11420,7 +11470,7 @@ index 70d25bb45ad603095a1f5812cc396dfc5f16a1e1..c9bd400473166999479f5eef1edad529 public boolean doHurtTarget(Entity target) { if (super.doHurtTarget(target)) { diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -index fd1b5a1beea7594fa65decfdcccfa15781fc005b..304ea7fdcd410a7c88ec61143364e14de8db0b0c 100644 +index 52eb3f6a73fa99d12d5fc75bab03e47a605c653a..64f6b5f44db4fd90e789032e3833da60cfcfbef1 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java @@ -59,21 +59,99 @@ public class Creeper extends Monster implements PowerableMob { @@ -11599,7 +11649,7 @@ index fd1b5a1beea7594fa65decfdcccfa15781fc005b..304ea7fdcd410a7c88ec61143364e14d } // Paper end diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java -index 991d728db2a3b64316fc2102cf3aee470327a62e..63a1cf5604c14025171d7be7434e2d6b64c98107 100644 +index 485d14d71fb26e6e0d00a43da040bf63d696b66a..034bb2d1292dde6276885c3ea71d886c3894311c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java @@ -29,6 +29,7 @@ import net.minecraft.world.entity.ai.goal.MoveToBlockGoal; @@ -11779,7 +11829,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 0d51f435f18f3f9d59a3241a0b7fa1c4af841b72..4c9ffa8e1ab97d8156ead0ed189c769ffd9b4aae 100644 +index ebbd0031da656c4b12debbf76a347da2865d50d1..a5fcc85334474b29c3575bccbaeceaadc06eea5c 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 { @@ -12006,10 +12056,10 @@ index 66b6c55f72aec7e4e9dfa5417a46ba68dbb16a83..20ca96baf8f73fd5835422c6551f515a @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/Evoker.java b/src/main/java/net/minecraft/world/entity/monster/Evoker.java -index 7f0fbca7638bf89465bafed9d106813b86f0149b..4095f03ccd1712335baffe858603618100aed99c 100644 +index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc72465702dfe 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java -@@ -50,10 +50,43 @@ public class Evoker extends SpellcasterIllager { +@@ -51,10 +51,43 @@ public class Evoker extends SpellcasterIllager { this.xpReward = 10; } @@ -12053,7 +12103,7 @@ index 7f0fbca7638bf89465bafed9d106813b86f0149b..4095f03ccd1712335baffe8586036181 this.goalSelector.addGoal(1, new Evoker.EvokerCastingSpellGoal()); this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 0.6D, 1.0D)); this.goalSelector.addGoal(4, new Evoker.EvokerSummonSpellGoal()); -@@ -62,6 +95,7 @@ public class Evoker extends SpellcasterIllager { +@@ -63,6 +96,7 @@ public class Evoker extends SpellcasterIllager { this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); @@ -12061,7 +12111,7 @@ index 7f0fbca7638bf89465bafed9d106813b86f0149b..4095f03ccd1712335baffe8586036181 this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300)); this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300)); -@@ -321,7 +355,7 @@ public class Evoker extends SpellcasterIllager { +@@ -327,7 +361,7 @@ public class Evoker extends SpellcasterIllager { return false; } else if (Evoker.this.tickCount < this.nextAttackTickCount) { return false; @@ -12308,7 +12358,7 @@ index 793c72bb7b86e404926085629121d6cad19a2740..d13eed85d5399cd6991b3ad90f05a580 } } diff --git a/src/main/java/net/minecraft/world/entity/monster/Guardian.java b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29d1a064d5 100644 +index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e7b7e724e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java @@ -70,15 +70,51 @@ public class Guardian extends Monster { @@ -12371,7 +12421,7 @@ index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 10, true, false, new Guardian.GuardianAttackSelector(this))); } -@@ -352,7 +389,7 @@ public class Guardian extends Monster { +@@ -347,7 +384,7 @@ public class Guardian extends Monster { @Override public void travel(Vec3 movementInput) { if (this.isControlledByLocalInstance() && this.isInWater()) { @@ -12380,7 +12430,7 @@ index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29 this.move(MoverType.SELF, this.getDeltaMovement()); this.setDeltaMovement(this.getDeltaMovement().scale(0.9D)); if (!this.isMoving() && this.getTarget() == null) { -@@ -369,7 +406,7 @@ public class Guardian extends Monster { +@@ -364,7 +401,7 @@ public class Guardian extends Monster { return new Vector3f(0.0F, dimensions.height + 0.125F * scaleFactor, 0.0F); } @@ -12389,7 +12439,7 @@ index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29 private final Guardian guardian; -@@ -378,8 +415,17 @@ public class Guardian extends Monster { +@@ -373,8 +410,17 @@ public class Guardian extends Monster { this.guardian = guardian; } @@ -12408,7 +12458,7 @@ index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29 if (this.operation == MoveControl.Operation.MOVE_TO && !this.guardian.getNavigation().isDone()) { Vec3 vec3d = new Vec3(this.wantedX - this.guardian.getX(), this.wantedY - this.guardian.getY(), this.wantedZ - this.guardian.getZ()); double d0 = vec3d.length(); -@@ -390,7 +436,7 @@ public class Guardian extends Monster { +@@ -385,7 +431,7 @@ public class Guardian extends Monster { this.guardian.setYRot(this.rotlerp(this.guardian.getYRot(), f, 90.0F)); this.guardian.yBodyRot = this.guardian.getYRot(); @@ -12418,7 +12468,7 @@ index 45300f79cba6133d2a2eca706eae03ee3cd973c3..54113957c9cfab2ad3be25dbc05b8c29 this.guardian.setSpeed(f2); diff --git a/src/main/java/net/minecraft/world/entity/monster/Husk.java b/src/main/java/net/minecraft/world/entity/monster/Husk.java -index 8ef1e325d722ca36fc0fc36f1e5287d7002b9fb2..473f28e86a0e5157264b83d9c3c4a18c72216da3 100644 +index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd945503d69 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Husk.java +++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java @@ -22,6 +22,59 @@ public class Husk extends Zombie { @@ -12626,7 +12676,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 e4218acaaf7d3aef0fb31f5597fb1af32aa2c8b5..01977550309451cda795583ba4122143b140b9b7 100644 +index 127a344f35e194fc7b1a0783c75291fab929fe19..d90d8539815d92143c994108efdfcc18bcb3b158 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 { @@ -13203,7 +13253,7 @@ index 0c11d9bef8f0129c541e30ad057612e881703b24..c9c21c87e3bd1c404fbef6768761bcb5 if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state continue; diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java -index 8cb6f2d32c4b7a62ec1bdfeb8b661a1387cafe4b..81caa18fca658f70846ba437ac02906f5e9653b9 100644 +index b73dac8f68041f8a2e0752d70cc9d08b5cfd1cde..8a52c1ad5e2872e4b484eebc834fa42fd1930481 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java @@ -22,6 +22,8 @@ import net.minecraft.tags.DamageTypeTags; @@ -13311,7 +13361,7 @@ index 8cb6f2d32c4b7a62ec1bdfeb8b661a1387cafe4b..81caa18fca658f70846ba437ac02906f if (entityshulker != null) { entityshulker.setVariant(this.getVariant()); -@@ -591,7 +651,7 @@ public class Shulker extends AbstractGolem implements VariantHolder getVariant() { @@ -13320,7 +13370,7 @@ index 8cb6f2d32c4b7a62ec1bdfeb8b661a1387cafe4b..81caa18fca658f70846ba437ac02906f } @Nullable -@@ -601,7 +661,7 @@ public class Shulker extends AbstractGolem implements VariantHolder(this, Player.class)); this.targetSelector.addGoal(3, new Spider.SpiderTargetGoal<>(this, IronGolem.class)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Stray.java b/src/main/java/net/minecraft/world/entity/monster/Stray.java -index 118b636a44e4b062e812e433f603b039276337da..a95e983032b3d3d125a39a46700b7db9dc69f307 100644 +index 8185cef34b9300561a00f9e62b98f1aa818a3f5a..e01c91385935b71bb9aa7259b95cb963140e8c94 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Stray.java +++ b/src/main/java/net/minecraft/world/entity/monster/Stray.java @@ -21,6 +21,38 @@ public class Stray extends AbstractSkeleton { @@ -13904,7 +13954,7 @@ index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce82 if (flag && !this.isSilent()) { this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.STRIDER_EAT, this.getSoundSource(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java -index 90e577b1a89b02c38daff2845a63dafe5ed929e1..be1c9a7e2bafb33dcb954ba9fd427c033bb7542f 100644 +index 30ea3f64234fd1fda8dada3c7fb12be0730322a8..44fe951f0297c0efa5169c8972c05eaf90d49edf 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vex.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java @@ -63,6 +63,65 @@ public class Vex extends Monster implements TraceableEntity { @@ -14003,7 +14053,7 @@ index 90e577b1a89b02c38daff2845a63dafe5ed929e1..be1c9a7e2bafb33dcb954ba9fd427c03 } @Override -@@ -240,14 +301,14 @@ public class Vex extends Monster implements TraceableEntity { +@@ -251,14 +312,14 @@ public class Vex extends Monster implements TraceableEntity { return new Vector3f(0.0F, dimensions.height - 0.0625F * scaleFactor, 0.0F); } @@ -14020,7 +14070,7 @@ index 90e577b1a89b02c38daff2845a63dafe5ed929e1..be1c9a7e2bafb33dcb954ba9fd427c03 if (this.operation == MoveControl.Operation.MOVE_TO) { Vec3 vec3d = new Vec3(this.wantedX - Vex.this.getX(), this.wantedY - Vex.this.getY(), this.wantedZ - Vex.this.getZ()); double d0 = vec3d.length(); -@@ -256,7 +317,7 @@ public class Vex extends Monster implements TraceableEntity { +@@ -267,7 +328,7 @@ public class Vex extends Monster implements TraceableEntity { this.operation = MoveControl.Operation.WAIT; Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5D)); } else { @@ -14260,7 +14310,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 5fdad1600cc7a7c22d1d9a58b6b2dda605521b97..1be1bfb831198b68d8e20bf5ff922edff8832114 100644 +index 753defa8f8b48d004a2a53b2fc322fd9c083d95e..f6dd5fd56926215830ccebbd46098d4bc08e17e4 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 { @@ -14471,7 +14521,7 @@ index 5fdad1600cc7a7c22d1d9a58b6b2dda605521b97..1be1bfb831198b68d8e20bf5ff922edf @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 94396ad1a3c280787d36c6c18256d10340ace488..4d744e00bbaf25d1bad3782a6415e9bf5958e536 100644 +index 7de9d012e7416eaa0189b513a0972c846e93c4b6..712f77d4ddad04c7cd89d51c6d0c79c2f3ab9347 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 { @@ -14634,6 +14684,33 @@ index 1afe8a8694c1fd0bf43ce3c0c36a83fda9aec141..df8c7a45eb49a8c667030eb67d6d49dc } @Nullable +diff --git a/src/main/java/net/minecraft/world/entity/monster/breeze/Breeze.java b/src/main/java/net/minecraft/world/entity/monster/breeze/Breeze.java +index 0b8992a9aea781470ab3b1880cf041972a20089d..94431d5c789a9f558c16c0d1fc8f1f7463421ec6 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/breeze/Breeze.java ++++ b/src/main/java/net/minecraft/world/entity/monster/breeze/Breeze.java +@@ -59,7 +59,7 @@ public class Breeze extends Monster { + + @Override + public Brain getBrain() { +- return super.getBrain(); ++ return (Brain) super.getBrain(); // Purpur - decompile error + } + + @Override +@@ -200,10 +200,10 @@ public class Breeze extends Monster { + + @Override + protected void customServerAiStep() { +- this.level().getProfiler().push("breezeBrain"); ++ // this.level().getProfiler().push("breezeBrain"); // Purpur + this.getBrain().tick((ServerLevel)this.level(), this); +- this.level().getProfiler().popPush("breezeActivityUpdate"); +- this.level().getProfiler().pop(); ++ // this.level().getProfiler().popPush("breezeActivityUpdate"); // Purpur ++ // this.level().getProfiler().pop(); // Purpur + super.customServerAiStep(); + } + diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java index e703320717ff620a19ff76d1c10066117c9895d5..9d6c4f13c4a444c6c815c6c4f2114142f166b9bb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java @@ -14868,10 +14945,10 @@ index d02ee11066fc4f07ccb110b09b86d895ff90d4f2..856e6e02c9424a6c06e310262cb4f5bd PiglinBruteAi.maybePlayActivitySound(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -index 5e43912708f9074dee1bb351efa737a7e6796fc3..5e66c2bd3807619cadee5b7081d93d21886e2806 100644 +index 58a7e61e02b7d72326ed4d57ee514adb63b3873c..22263f219ce9e9f014abb76c43297c528acb36eb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -@@ -122,8 +122,32 @@ public class Warden extends Monster implements VibrationSystem { +@@ -123,8 +123,32 @@ public class Warden extends Monster implements VibrationSystem { this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F); this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F); this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F); @@ -14904,7 +14981,7 @@ index 5e43912708f9074dee1bb351efa737a7e6796fc3..5e66c2bd3807619cadee5b7081d93d21 @Override public Packet getAddEntityPacket() { return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); -@@ -277,10 +301,10 @@ public class Warden extends Monster implements VibrationSystem { +@@ -278,10 +302,10 @@ public class Warden extends Monster implements VibrationSystem { protected void customServerAiStep() { ServerLevel worldserver = (ServerLevel) this.level(); @@ -14917,7 +14994,7 @@ index 5e43912708f9074dee1bb351efa737a7e6796fc3..5e66c2bd3807619cadee5b7081d93d21 super.customServerAiStep(); if ((this.tickCount + this.getId()) % 120 == 0) { Warden.applyDarknessAround(worldserver, this.position(), this, 20); -@@ -397,19 +421,16 @@ public class Warden extends Monster implements VibrationSystem { +@@ -398,19 +422,16 @@ public class Warden extends Monster implements VibrationSystem { @Contract("null->false") public boolean canTargetEntity(@Nullable Entity entity) { @@ -14999,7 +15076,7 @@ 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 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b4634b2abf08 100644 +index 1e6d61673b0e3252129c04edcfa1d7d436e8ecbe..27ebfda79d9c4463f157b99c2c56e256839b3a31 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -141,6 +141,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -15111,7 +15188,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 } brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); -@@ -254,15 +340,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -254,15 +340,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler // Paper start this.customServerAiStep(false); } @@ -15128,20 +15205,19 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 + // treat as inactive if lobotomized + inactive = inactive || checkLobotomized(); + } else { -+ // clean up state for API + this.isLobotomized = false; } - // Pufferfish end - this.level().getProfiler().pop(); -+ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Purpur - only use brain if no rider ++ 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(); ++ } else if (this.isLobotomized && shouldRestock()) restock(); + // Purpur end + //this.level().getProfiler().pop(); // Purpur if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } -@@ -318,7 +411,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -318,7 +410,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(); @@ -15150,7 +15226,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 } else { boolean flag = this.getOffers().isEmpty(); -@@ -331,9 +424,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -331,9 +423,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (flag) { @@ -15163,7 +15239,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 this.startTrading(player); } -@@ -502,7 +596,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -502,7 +595,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); @@ -15172,7 +15248,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 } } -@@ -752,7 +846,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -752,7 +845,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public boolean canBreed() { @@ -15181,7 +15257,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 } private boolean hungry() { -@@ -945,6 +1039,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -945,6 +1038,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public boolean hasFarmSeeds() { return this.getInventory().hasAnyMatching((itemstack) -> { @@ -15193,7 +15269,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS); }); } -@@ -1002,6 +1101,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1002,6 +1100,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) { @@ -15201,7 +15277,7 @@ index 2460768aaa7b8e6d183c03c1f0f2ccd6cb61a16f..02df0bf09f2ef91e4dafbdcea590b463 if (this.wantsToSpawnGolem(time)) { AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D); List list = world.getEntitiesOfClass(Villager.class, axisalignedbb); -@@ -1066,6 +1166,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1066,6 +1165,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void startSleeping(BlockPos pos) { @@ -15329,12 +15405,12 @@ 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 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7ba4e69ceb 100644 +index 2668c3b6f752d5d8bc45f4e6e52c20cc6a36a957..9ef9d005036ecbe271b08fa5e4465f328da19815 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 { +@@ -183,17 +183,40 @@ public abstract class Player extends LivingEntity { public boolean affectsSpawning = true; - public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; + public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage // Paper end + public int sixRowEnderchestSlotCount = -1; // Purpur + public int burpDelay = 0; // Purpur @@ -15373,7 +15449,7 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) { super(EntityType.PLAYER, world); this.lastItemInMainHand = ItemStack.EMPTY; -@@ -243,6 +266,12 @@ public abstract class Player extends LivingEntity { +@@ -238,6 +261,12 @@ public abstract class Player extends LivingEntity { @Override public void tick() { @@ -15407,12 +15483,12 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b @Override public int getPortalWaitTime() { -- return this.abilities.invulnerable ? 1 : 80; -+ return canPortalInstant ? 1 : this.abilities.invulnerable ? this.level().purpurConfig.playerCreativePortalWaitTime : this.level().purpurConfig.playerPortalWaitTime; // Purpur +- return Math.max(1, this.level().getGameRules().getInt(this.abilities.invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); ++ return Math.max(1, canPortalInstant ? 1 : this.level().getGameRules().getInt(this.abilities.invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); } @Override -@@ -597,7 +636,7 @@ public abstract class Player extends LivingEntity { +@@ -592,7 +631,7 @@ public abstract class Player extends LivingEntity { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -15421,7 +15497,7 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b list1.add(entity); } else if (!entity.isRemoved()) { this.touch(entity); -@@ -1288,7 +1327,7 @@ public abstract class Player extends LivingEntity { +@@ -1283,7 +1322,7 @@ public abstract class Player extends LivingEntity { flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper flag2 = flag2 && !this.isSprinting(); if (flag2) { @@ -15430,7 +15506,7 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b } f += f1; -@@ -1983,9 +2022,19 @@ public abstract class Player extends LivingEntity { +@@ -1914,9 +1953,19 @@ public abstract class Player extends LivingEntity { @Override public int getExperienceReward() { if (!this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) { @@ -15453,7 +15529,7 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b } else { return 0; } -@@ -2061,6 +2110,11 @@ public abstract class Player extends LivingEntity { +@@ -1992,6 +2041,11 @@ public abstract class Player extends LivingEntity { return this.inventory.armor; } @@ -15465,7 +15541,7 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b public boolean setEntityOnShoulder(CompoundTag entityNbt) { if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) { if (this.getShoulderEntityLeft().isEmpty()) { -@@ -2341,7 +2395,7 @@ public abstract class Player extends LivingEntity { +@@ -2272,7 +2326,7 @@ public abstract class Player extends LivingEntity { public ItemStack eat(Level world, ItemStack stack) { this.getFoodData().eat(stack.getItem(), stack); this.awardStat(Stats.ITEM_USED.get(stack.getItem())); @@ -15474,19 +15550,27 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..724329ded5d72eb230db392972d30e7b if (this instanceof ServerPlayer) { CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack); } +@@ -2366,6 +2420,7 @@ public abstract class Player extends LivingEntity { + } + + public static boolean isValidUsername(String name) { ++ if (true) return org.purpurmc.purpur.PurpurConfig.usernameValidCharactersPattern.matcher(name).matches(); // Purpur + // Paper start + if (name == null || name.isEmpty() || name.length() > 16) { + return false; 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 6c176933967f6ee98da3026f16a10efe4c3842fe..aa5e17e497bbc1d45b361de73cc7a181773dbd8b 100644 +index 505fe5496044f090ce6f7d541b8c3e13c567b16d..1c51ad780cae3c0c2a917f229ac370b75fe62c24 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 { - private IntOpenHashSet piercingIgnoreEntityIds; +@@ -74,6 +74,7 @@ public abstract class AbstractArrow extends Projectile { @Nullable private List piercedAndKilledEntities; + public ItemStack pickupItemStack; + public int lootingLevel; // Purpur // Spigot Start @Override -@@ -312,7 +313,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -319,7 +320,7 @@ public abstract class AbstractArrow extends Projectile { Vec3 vec3d = this.getDeltaMovement(); this.setDeltaMovement(vec3d.multiply((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F))); @@ -15495,7 +15579,7 @@ index 6c176933967f6ee98da3026f16a10efe4c3842fe..aa5e17e497bbc1d45b361de73cc7a181 } @Override -@@ -612,6 +613,12 @@ public abstract class AbstractArrow extends Projectile { +@@ -641,6 +642,12 @@ public abstract class AbstractArrow extends Projectile { this.knockback = punch; } @@ -15554,30 +15638,18 @@ index 0bbe853f7df93f9dcd2b21d762939f8b6be069aa..7db9844083703944f59e112c6dc5e1a5 public void tick() { super.tick(); diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index cd0629581bae5f805842157af36c2d838e01bee3..b0a559dfefac693bda8692a30fbaa5ac8062ef27 100644 +index f0a6251cc8f612b898231e505c47fd5b2bbb4973..8e13b5d3e89e49994ad9763be7e4f35dd58a9c5e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -326,6 +326,6 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -334,7 +334,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean mayInteract(Level world, BlockPos pos) { Entity entity = this.getOwner(); - return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); + return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.purpurConfig.projectilesBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); } - } -diff --git a/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java b/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java -index cc0a3d9794d05b6bc6ab05f4f2ab8d83134b181d..e1f918d0bd2a70db1aba8bda8717149f58766825 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java -@@ -33,7 +33,7 @@ public final class ProjectileUtil { - return getHitResult(vec32, entity, predicate, vec3, level); - } -- private static HitResult getHitResult(Vec3 pos, Entity entity, Predicate predicate, Vec3 velocity, Level world) { -+ public static HitResult getHitResult(Vec3 pos, Entity entity, Predicate predicate, Vec3 velocity, Level world) { // Purpur - private -> public - Vec3 vec3 = pos.add(velocity); - HitResult hitResult = world.clip(new ClipContext(pos, vec3, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)); - if (hitResult.getType() != HitResult.Type.MISS) { + public boolean mayBreak(Level world) { 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 9d43c8520953d6fe0d0948f9dbe14e0650ee01c2..deee9fffe6981d7e728621cc799a812d78000592 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -15638,10 +15710,10 @@ 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 f5db60cbecbe69941873e064315931089fe0e48a..2728eaaf0a9b761d932bd22639ef4e1ccc428482 100644 +index af4da25c9b13c114179fab3254aea5323210d7da..59cc9e9a56898c7bdc5474842c31d2fbe6a81897 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 { +@@ -70,10 +70,11 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { Bukkit.getPluginManager().callEvent(teleEvent); if (!teleEvent.isCancelled() && entityplayer.connection.isAcceptingMessages()) { @@ -15654,7 +15726,7 @@ index f5db60cbecbe69941873e064315931089fe0e48a..2728eaaf0a9b761d932bd22639ef4e1c entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot()); this.level().addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL); } -@@ -83,7 +84,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -86,7 +87,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityplayer.connection.teleport(teleEvent.getTo()); entity.resetFallDistance(); CraftEventFactory.entityDamage = this; @@ -15664,10 +15736,10 @@ index f5db60cbecbe69941873e064315931089fe0e48a..2728eaaf0a9b761d932bd22639ef4e1c } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -index a6bc277b6589dd7104566542733327822d6299a4..dde841cc09ba4a3575a462b03537887551d47ba5 100644 +index 51931e5cecf4c9ed8442136b18a94c7da89cf77d..2e6817fc05fe92615842a29c3e0682306a6b3ec5 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -62,7 +62,7 @@ public class ThrownTrident extends AbstractArrow { +@@ -60,7 +60,7 @@ public class ThrownTrident extends AbstractArrow { Entity entity = this.getOwner(); byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY); @@ -15677,10 +15749,10 @@ index a6bc277b6589dd7104566542733327822d6299a4..dde841cc09ba4a3575a462b035378875 if (!this.level().isClientSide && this.pickup == AbstractArrow.Pickup.ALLOWED) { this.spawnAtLocation(this.getPickupItem(), 0.1F); diff --git a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java -index 06d1bdb9bd124b201c36d284c50d22bf50d3735a..b4687453256ead43cf5288994316c7bf946b86df 100644 +index 78dd3365dc4d1265fc2102f740d75a384f5df5c5..aa5ce9625bf23885a55521cbb4d994b684a5cf61 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java -@@ -97,7 +97,7 @@ public class WitherSkull extends AbstractHurtingProjectile { +@@ -98,7 +98,7 @@ public class WitherSkull extends AbstractHurtingProjectile { if (!this.level().isClientSide) { // CraftBukkit start // this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB); @@ -15689,7 +15761,7 @@ index 06d1bdb9bd124b201c36d284c50d22bf50d3735a..b4687453256ead43cf5288994316c7bf this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { -@@ -109,6 +109,17 @@ public class WitherSkull extends AbstractHurtingProjectile { +@@ -110,6 +110,17 @@ public class WitherSkull extends AbstractHurtingProjectile { } @@ -15765,12 +15837,12 @@ index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1 if (!this.raidMap.containsKey(raid.getId())) { this.raidMap.put(raid.getId(), raid); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index 44a6118d3bd67a95180f750c17967561946e2e87..faf449dfb4f95a300796db46833f3b6a51cb961b 100644 +index dc421a0a6430583f1f0154e1dd689b80253f6e3d..9984ac31e911473a94d90aae1cdd46e16ac0182b 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -112,12 +112,14 @@ public abstract class AbstractMinecart extends Entity { - private double flyingY = 0.949999988079071D; // Paper - restore vanilla precision - private double flyingZ = 0.949999988079071D; // Paper - restore vanilla precision +@@ -105,12 +105,14 @@ public abstract class AbstractMinecart extends VehicleEntity { + private double flyingY = 0.95; + private double flyingZ = 0.95; public double maxSpeed = 0.4D; + public double storedMaxSpeed; // Purpur // CraftBukkit end @@ -15783,7 +15855,7 @@ index 44a6118d3bd67a95180f750c17967561946e2e87..faf449dfb4f95a300796db46833f3b6a } protected AbstractMinecart(EntityType type, Level world, double x, double y, double z) { -@@ -342,6 +344,12 @@ public abstract class AbstractMinecart extends Entity { +@@ -294,6 +296,12 @@ public abstract class AbstractMinecart extends VehicleEntity { @Override public void tick() { @@ -15796,7 +15868,7 @@ index 44a6118d3bd67a95180f750c17967561946e2e87..faf449dfb4f95a300796db46833f3b6a // CraftBukkit start double prevX = this.getX(); double prevY = this.getY(); -@@ -499,16 +507,62 @@ public abstract class AbstractMinecart extends Entity { +@@ -451,16 +459,62 @@ public abstract class AbstractMinecart extends VehicleEntity { public void activateMinecart(int x, int y, int z, boolean powered) {} @@ -15859,7 +15931,7 @@ index 44a6118d3bd67a95180f750c17967561946e2e87..faf449dfb4f95a300796db46833f3b6a this.move(MoverType.SELF, this.getDeltaMovement()); if (!this.onGround()) { -@@ -670,7 +724,7 @@ public abstract class AbstractMinecart extends Entity { +@@ -622,7 +676,7 @@ public abstract class AbstractMinecart extends VehicleEntity { if (d18 > 0.01D) { double d20 = 0.06D; @@ -15869,25 +15941,10 @@ index 44a6118d3bd67a95180f750c17967561946e2e87..faf449dfb4f95a300796db46833f3b6a Vec3 vec3d5 = this.getDeltaMovement(); double d21 = vec3d5.x; diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -index 5c07da62c82bc70138f6cb5007629d6974be69ac..c314febb75a85ef12051bde392c5b57e9c5d85ac 100644 +index c041c0b81be41cfd128c2f5ba56a5329d50b2efc..7e9c88efd2a1edea673d1ef81635c2891a04d30e 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -@@ -242,7 +242,13 @@ public class Boat extends Entity implements VariantHolder { - } - - protected void destroy(DamageSource source) { -- this.spawnAtLocation((ItemLike) this.getDropItem()); -+ // Purpur start -+ final ItemStack boat = new ItemStack(this.getDropItem()); -+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { -+ boat.setHoverName(this.getCustomName()); -+ } -+ this.spawnAtLocation(boat); -+ // Purpur end - } - - @Override -@@ -578,6 +584,7 @@ public class Boat extends Entity implements VariantHolder { +@@ -521,6 +521,7 @@ public class Boat extends VehicleEntity implements VariantHolder { if (f > 0.0F) { this.landFriction = f; @@ -15895,6 +15952,21 @@ index 5c07da62c82bc70138f6cb5007629d6974be69ac..c314febb75a85ef12051bde392c5b57e return Boat.Status.ON_LAND; } else { return Boat.Status.IN_AIR; +@@ -967,7 +968,13 @@ public class Boat extends VehicleEntity implements VariantHolder { + + @Override + public ItemStack getPickResult() { +- return new ItemStack(this.getDropItem()); ++ // Purpur start ++ final ItemStack boat = new ItemStack(this.getDropItem()); ++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { ++ boat.setHoverName(this.getCustomName()); ++ } ++ return boat; ++ // Purpur end + } + + public static enum Type implements StringRepresentable { diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java index c3448707fd8a632b457cc97b35d08a9c6933d5ee..e8079d126e6c0cf0b15c01afb6498922ee05964c 100644 --- a/src/main/java/net/minecraft/world/food/FoodData.java @@ -15966,7 +16038,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 82f18790b9dc55b039ae03600a80a46d56a87521..6a754ecd4e9d6c3ebc7bd91b1de797fdbf3c4290 100644 +index 47a3c18401e2df4c89908691348f2411d3ef6fda..5ca5b5e5925d330f2962a9a1024b5dd675f0003a 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 { @@ -16211,7 +16283,7 @@ index 0dbfd23bbfc6ad203f048142f8c90ef741849fe1..9a80427d2bb470b6b1638e59aba57216 return new ChestMenu(MenuType.GENERIC_9x6, syncId, playerInventory, inventory, 6); } diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -index c5c509fbb915c60dfa95aac8510684d0b9f8b0ff..d604b7ec46f08993647979ed220a84842e3fe325 100644 +index 343f44db579839eb61376f876b5eff2e615dc2e5..849b6a30d412d10f1e2e6e88f2d8d990e4a720e4 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java @@ -40,6 +40,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent; @@ -16277,7 +16349,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 076c2b2938c9b88b7e71dbc2aa9d8c7e90d4fe75..b1eacb9691b320a10de3420fae3632bb9d5b7ae3 100644 +index 4acad717bfec91e4abcdd59900e6872838d0712c..46c4468b846085d92f773142ecbee0fe258ff319 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 { @@ -16352,28 +16424,20 @@ index 076c2b2938c9b88b7e71dbc2aa9d8c7e90d4fe75..b1eacb9691b320a10de3420fae3632bb 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 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..45eec732ff0e4e78b4d3f2112b6a79d7ae668d2f 100644 +index 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..1acb41fab25bdbc4109913b111dbe3b0e106af3f 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; - import net.minecraft.network.chat.Component; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.world.Container; -+import net.minecraft.world.effect.MobEffects; - import net.minecraft.world.entity.EquipmentSlot; - import net.minecraft.world.entity.Mob; - import net.minecraft.world.entity.player.Inventory; -@@ -95,7 +96,7 @@ public class InventoryMenu extends RecipeBookMenu { +@@ -95,7 +95,7 @@ public class InventoryMenu extends RecipeBookMenu { public boolean mayPickup(Player playerEntity) { ItemStack itemstack = this.getItem(); - return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? false : super.mayPickup(playerEntity); -+ return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? playerEntity.level().purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(MobEffects.WEAKNESS) : super.mayPickup(playerEntity); // Purpur ++ return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? playerEntity.level().purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS) : super.mayPickup(playerEntity); // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index c2cf5a8e788637c6264cf43d712a5be223ff1cc5..a578882b64c581ef4f47fa483a9f2988cfa4c8cf 100644 +index e5a7f36843d621e6c714ef2e1cb8e2e3551924ef..2071c21783cc5e3f542018de3b0a7a1c579147da 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -178,7 +178,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -16443,58 +16507,33 @@ index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32b world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F); entityarmorstand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer()); diff --git a/src/main/java/net/minecraft/world/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java -index 18898e16ec42f6b694b06e09d9174b60d62450d7..20f33b77b4a9494be227456bc742a029eb0af59b 100644 +index 2e75fd06e9e379eb95ebfe55086ffc327706ab2f..2918b1aca8fae6a319881a631dc727b6d375a33c 100644 --- a/src/main/java/net/minecraft/world/item/AxeItem.java +++ b/src/main/java/net/minecraft/world/item/AxeItem.java -@@ -33,29 +33,32 @@ public class AxeItem extends DiggerItem { +@@ -33,13 +33,15 @@ public class AxeItem extends DiggerItem { + Level level = context.getLevel(); BlockPos blockPos = context.getClickedPos(); Player player = context.getPlayer(); - BlockState blockState = level.getBlockState(blockPos); -- Optional optional = this.getStripped(blockState); -- Optional optional2 = WeatheringCopper.getPrevious(blockState); -- Optional optional3 = Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(blockState.getBlock())).map((block) -> { -- return block.withPropertiesOf(blockState); -- }); -+ // Purpur start -+ Block clickedBlock = level.getBlockState(blockPos).getBlock(); -+ Optional optional = Optional.ofNullable(level.purpurConfig.axeStrippables.get(blockState.getBlock())); -+ Optional optional2 = Optional.ofNullable(level.purpurConfig.axeWeatherables.get(blockState.getBlock())); -+ Optional optional3 = Optional.ofNullable(level.purpurConfig.axeWaxables.get(blockState.getBlock())); -+ // Purpur end - ItemStack itemStack = context.getItemInHand(); -- Optional optional4 = Optional.empty(); -+ Optional optional4 = Optional.empty(); // Purpur - if (optional.isPresent()) { -- level.playSound(player, blockPos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); -+ if (!STRIPPABLES.containsKey(clickedBlock)) level.playSound(null, blockPos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound - optional4 = optional; - } else if (optional2.isPresent()) { -- level.playSound(player, blockPos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F); -+ if (!HoneycombItem.WAXABLES.get().containsKey(clickedBlock)) level.playSound(null, blockPos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound - level.levelEvent(player, 3005, blockPos, 0); - optional4 = optional2; - } else if (optional3.isPresent()) { -- level.playSound(player, blockPos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); -+ if (!HoneycombItem.WAX_OFF_BY_BLOCK.get().containsKey(clickedBlock)) level.playSound(null, blockPos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound - level.levelEvent(player, 3004, blockPos, 0); - optional4 = optional3; - } - - if (optional4.isPresent()) { -+ org.purpurmc.purpur.tool.Actionable actionable = optional4.get(); // Purpur -+ BlockState state = actionable.into().withPropertiesOf(blockState); // Purpur +- Optional optional = this.evaluateNewBlockState(level, blockPos, player, level.getBlockState(blockPos)); ++ Optional optional = this.evaluateActionable(level, blockPos, player, level.getBlockState(blockPos)); // Purpur + if (optional.isEmpty()) { + return InteractionResult.PASS; + } else { ++ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur ++ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(blockPos)); // Purpur + ItemStack itemStack = context.getItemInHand(); // Paper start - EntityChangeBlockEvent -- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional4.get())) { +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.get())) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { // Purpur return InteractionResult.PASS; } // Paper end -@@ -63,15 +66,22 @@ public class AxeItem extends DiggerItem { +@@ -47,35 +49,40 @@ public class AxeItem extends DiggerItem { CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); } -- level.setBlock(blockPos, optional4.get(), 11); -- level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, optional4.get())); +- level.setBlock(blockPos, optional.get(), 11); +- level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, optional.get())); + // Purpur start + level.setBlock(blockPos, state, 11); + actionable.drops().forEach((drop, chance) -> { @@ -16512,11 +16551,38 @@ index 18898e16ec42f6b694b06e09d9174b60d62450d7..20f33b77b4a9494be227456bc742a029 - return InteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; // Purpur - force arm swing - } else { - return InteractionResult.PASS; } + } + +- private Optional evaluateNewBlockState(Level world, BlockPos pos, @Nullable Player player, BlockState state) { +- Optional optional = this.getStripped(state); ++ private Optional evaluateActionable(Level world, BlockPos pos, @Nullable Player player, BlockState state) { // Purpur ++ Optional optional = Optional.ofNullable(world.purpurConfig.axeStrippables.get(state.getBlock())); // Purpur + if (optional.isPresent()) { +- world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); ++ world.playSound(STRIPPABLES.containsKey(state.getBlock()) ? player : null, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound + return optional; + } else { +- Optional optional2 = WeatheringCopper.getPrevious(state); ++ Optional optional2 = Optional.ofNullable(world.purpurConfig.axeWeatherables.get(state.getBlock())); // Purpur + if (optional2.isPresent()) { +- world.playSound(player, pos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F); ++ world.playSound(WeatheringCopper.getPrevious(state).isPresent() ? player : null, pos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound + world.levelEvent(player, 3005, pos, 0); + return optional2; + } else { +- Optional optional3 = Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(state.getBlock())).map((block) -> { +- return block.withPropertiesOf(state); +- }); ++ Optional optional3 = Optional.ofNullable(world.purpurConfig.axeWaxables.get(state.getBlock())); // Purpur + if (optional3.isPresent()) { +- world.playSound(player, pos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); ++ world.playSound(HoneycombItem.WAX_OFF_BY_BLOCK.get().containsKey(state.getBlock()) ? player : null, pos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound + world.levelEvent(player, 3004, pos, 0); + return optional3; + } else { diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index efdf56044396b4ce486948d2c993971f99174a5e..42bfde8e36b6395f50973300313d6959e2735327 100644 +index 6404323f01833569e46c4ae45ceb21eb297c0c7f..891cc06311fd135d2ac4a46d9cb3368ea2c041dd 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java @@ -152,7 +152,24 @@ public class BlockItem extends Item { @@ -16555,10 +16621,10 @@ index efdf56044396b4ce486948d2c993971f99174a5e..42bfde8e36b6395f50973300313d6959 CompoundTag nbttagcompound = BlockItem.getBlockEntityData(itemstack); diff --git a/src/main/java/net/minecraft/world/item/BoatItem.java b/src/main/java/net/minecraft/world/item/BoatItem.java -index aec7ac31a35b1cc81f40b3fbeb5cf95c0f2c8a6c..cbcd35e60a2c344c83978abf0b94c2120ff53dee 100644 +index 67a5a201d0b26ca7b27e6d0c3ffb9f8b6e16bce0..ec3d60b561de45349b705b7f14592be930af4b91 100644 --- a/src/main/java/net/minecraft/world/item/BoatItem.java +++ b/src/main/java/net/minecraft/world/item/BoatItem.java -@@ -69,6 +69,11 @@ public class BoatItem extends Item { +@@ -71,6 +71,11 @@ public class BoatItem extends Item { entityboat.setVariant(this.type); entityboat.setYRot(user.getYRot()); @@ -16710,7 +16776,7 @@ index 58cb992c5defec2f092755cbde661ff10f38bf9d..52f48681407d23f0925f4c9c072d5f0a com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity()); if (event.callEvent() && world.addFreshEntity(entityegg)) { diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java -index 3688e9f8c6c6d1239095e3a87060ccca90386d0c..34254eec36d34ae343733fa1abbaaba60be41a3b 100644 +index faa3f62d22266a3c32d6c95c3ffebd4aa3880739..0cf62b1f64afa56c319392eafe0d444b7c5662c7 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java +++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -26,7 +26,7 @@ public class EndCrystalItem extends Item { @@ -16841,10 +16907,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 d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53ef149e43 100644 +index 5caf48c84b8dd46903dbdacaa3a5e13272374e0e..cbfd535d62acdde7789fa88332f4a607c381d450 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -432,6 +432,7 @@ public final class ItemStack { +@@ -453,6 +453,7 @@ public final class ItemStack { world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 for (BlockState blockstate : blocks) { blockstate.update(true, false); @@ -16852,7 +16918,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 } world.preventPoiUpdated = false; -@@ -463,6 +464,7 @@ public final class ItemStack { +@@ -484,6 +485,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 } @@ -16860,7 +16926,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point } -@@ -591,6 +593,16 @@ public final class ItemStack { +@@ -612,6 +614,16 @@ public final class ItemStack { return this.isDamageableItem() && this.getDamageValue() > 0; } @@ -16877,7 +16943,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 public int getDamageValue() { return this.tag == null ? 0 : this.tag.getInt("Damage"); } -@@ -610,7 +622,7 @@ public final class ItemStack { +@@ -631,7 +643,7 @@ public final class ItemStack { int j; if (amount > 0) { @@ -16886,7 +16952,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 int k = 0; for (int l = 0; j > 0 && l < amount; ++l) { -@@ -665,6 +677,12 @@ public final class ItemStack { +@@ -686,6 +698,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(); @@ -16899,7 +16965,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 // 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); -@@ -1191,7 +1209,7 @@ public final class ItemStack { +@@ -1216,7 +1234,7 @@ public final class ItemStack { ListTag nbttaglist = this.tag.getList("Enchantments", 10); @@ -16908,7 +16974,7 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 processEnchantOrder(this.tag); // Paper } -@@ -1199,6 +1217,12 @@ public final class ItemStack { +@@ -1224,6 +1242,12 @@ public final class ItemStack { return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; } @@ -16922,10 +16988,10 @@ index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..2776b124dd15e4c84edcfbf98ba44d53 this.getOrCreateTag().put(key, element); } diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java -index 5f20e075c532f0f1d413242949d1738c0c152bf7..5fbb13ebef0ca66419f3e5006d19e4a5918a038a 100644 +index f692149d91b525bda6dc79d489d7496ea24037e8..cf68dca4096556b0c2594c76fcf113419e56dae0 100644 --- a/src/main/java/net/minecraft/world/item/Items.java +++ b/src/main/java/net/minecraft/world/item/Items.java -@@ -294,7 +294,7 @@ public class Items { +@@ -316,7 +316,7 @@ public class Items { public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK); public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR); public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS); @@ -16934,7 +17000,7 @@ index 5f20e075c532f0f1d413242949d1738c0c152bf7..5fbb13ebef0ca66419f3e5006d19e4a5 public static final Item CHEST = registerBlock(Blocks.CHEST); public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE); public static final Item FARMLAND = registerBlock(Blocks.FARMLAND); -@@ -1184,7 +1184,7 @@ public class Items { +@@ -1224,7 +1224,7 @@ public class Items { public static final Item LANTERN = registerBlock(Blocks.LANTERN); public static final Item SOUL_LANTERN = registerBlock(Blocks.SOUL_LANTERN); public static final Item SWEET_BERRIES = registerItem("sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, (new Item.Properties()).food(Foods.SWEET_BERRIES))); @@ -16943,7 +17009,7 @@ index 5f20e075c532f0f1d413242949d1738c0c152bf7..5fbb13ebef0ca66419f3e5006d19e4a5 public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE); public static final Item SOUL_CAMPFIRE = registerBlock(Blocks.SOUL_CAMPFIRE); public static final Item SHROOMLIGHT = registerBlock(Blocks.SHROOMLIGHT); -@@ -1309,6 +1309,13 @@ public class Items { +@@ -1367,6 +1367,13 @@ public class Items { ((BlockItem)item).registerBlocks(Item.BY_BLOCK, item); } @@ -16958,10 +17024,10 @@ index 5f20e075c532f0f1d413242949d1738c0c152bf7..5fbb13ebef0ca66419f3e5006d19e4a5 } } diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index c368b437597edf7e165326727ae778a69c3fcc83..fed5bfb02ab7d6c1d1d9bf993fda5b3f411b9352 100644 +index 797415866a7f182d804f6b8e57ceb07a6ac2a20a..6cfd169c2c32b644d70907358c2d4a2087c00a68 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -243,6 +243,7 @@ public class MapItem extends ComplexItem { +@@ -235,6 +235,7 @@ public class MapItem extends ComplexItem { MapItemSavedData worldmap = MapItem.getSavedData(map, world); if (worldmap != null) { @@ -16993,10 +17059,10 @@ index f33977d95b6db473be4f95075ba99caf90ad0220..56dc04d8875971ee9a5d077a695509af return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack; diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..2b2218e2de535ebc8f529f5b5bf98fa1ef819a5e 100644 +index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976d533d54e 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -122,8 +122,9 @@ public class MinecartItem extends Item { +@@ -119,8 +119,9 @@ public class MinecartItem extends Item { BlockState iblockdata = world.getBlockState(blockposition); if (!iblockdata.is(BlockTags.RAILS)) { @@ -17007,8 +17073,8 @@ index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..2b2218e2de535ebc8f529f5b5bf98fa1 + } // else { // Purpur - place minecarts anywhere ItemStack itemstack = context.getItemInHand(); - if (!world.isClientSide) { -@@ -151,6 +152,6 @@ public class MinecartItem extends Item { + if (world instanceof ServerLevel) { +@@ -145,6 +146,6 @@ public class MinecartItem extends Item { itemstack.shrink(1); return InteractionResult.sidedSuccess(world.isClientSide); @@ -17071,25 +17137,26 @@ index ef3f90a5bcdd7b9815a4053cff166f9d2552f55d..e7e5e1cc92f56e3daba8fa09c59188fe com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); if (event.callEvent() && world.addFreshEntity(entitysnowball)) { diff --git a/src/main/java/net/minecraft/world/item/SpawnEggItem.java b/src/main/java/net/minecraft/world/item/SpawnEggItem.java -index 741719301e6fc91a598e74342810c4185e6fde26..6fbff9c02fbabf03c9c649a9ea6128021081f9cd 100644 +index 4f10f801dc126e9135432939b6663770c0e7a0bc..8f89a1c7e6214f549490ecf75afbdd72b897b120 100644 --- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java +++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java -@@ -68,6 +68,15 @@ public class SpawnEggItem extends Item { - SpawnerBlockEntity tileentitymobspawner = (SpawnerBlockEntity) tileentity; - EntityType entitytypes = this.getType(itemstack.getTag()); +@@ -68,6 +68,16 @@ public class SpawnEggItem extends Item { + Spawner spawner = (Spawner) tileentity; -+ // Purpur start -+ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName())); -+ if (!event.callEvent()) { -+ return InteractionResult.FAIL; -+ } -+ entitytypes = EntityType.getFromBukkitType(event.getEntityType()); -+ // Purpur end + entitytypes = this.getType(itemstack.getTag()); + - tileentitymobspawner.setEntityId(entitytypes, world.getRandom()); - tileentity.setChanged(); - world.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3); ++ // Purpur start ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName())); ++ if (!event.callEvent()) { ++ return InteractionResult.FAIL; ++ } ++ entitytypes = EntityType.getFromBukkitType(event.getEntityType()); ++ // Purpur end ++ + spawner.setEntityId(entitytypes, world.getRandom()); + world.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3); + world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_CHANGE, blockposition); diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java index de5bdceb4c8578fb972a2fd5ee0dfdae509e46dc..bcf63ccb6e679cb97d658780b2663aafa3568bcb 100644 --- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java @@ -17104,7 +17171,7 @@ index de5bdceb4c8578fb972a2fd5ee0dfdae509e46dc..bcf63ccb6e679cb97d658780b2663aaf com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity()); if (event.callEvent() && world.addFreshEntity(thrownPotion)) { diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java -index 8078f127ff4b6e0aafb5804b9c02e237f79445b5..c32cbe6065ecb6810f352b8a3598c21e42e60e1d 100644 +index 5fab851b319847035fb1eefd0ab999de3ccc2cd8..ec5daeef857fdad6c7659130fb42f52cf6eb491f 100644 --- a/src/main/java/net/minecraft/world/item/TridentItem.java +++ b/src/main/java/net/minecraft/world/item/TridentItem.java @@ -77,11 +77,19 @@ public class TridentItem extends Item implements Vanishable { @@ -17128,7 +17195,7 @@ index 8078f127ff4b6e0aafb5804b9c02e237f79445b5..c32cbe6065ecb6810f352b8a3598c21e // CraftBukkit start // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity()); -@@ -130,6 +138,14 @@ public class TridentItem extends Item implements Vanishable { +@@ -131,6 +139,14 @@ public class TridentItem extends Item implements Vanishable { f2 *= f6 / f5; f3 *= f6 / f5; f4 *= f6 / f5; @@ -17144,10 +17211,10 @@ 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..3532db21cee82c18f95c540d24b2071585d71c4e 100644 +index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a449f2268f 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 { +@@ -36,6 +36,7 @@ public final class Ingredient implements Predicate { @Nullable private IntList stackingIds; public boolean exact; // CraftBukkit @@ -17155,7 +17222,7 @@ index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..3532db21cee82c18f95c540d24b20715 public static final Codec CODEC = Ingredient.codec(true); public static final Codec CODEC_NONEMPTY = Ingredient.codec(false); -@@ -70,6 +71,12 @@ public final class Ingredient implements Predicate { +@@ -67,6 +68,12 @@ public final class Ingredient implements Predicate { } else if (this.isEmpty()) { return itemstack.isEmpty(); } else { @@ -17301,10 +17368,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 6eca4a9b3cf462a4d18f32619bbcdfda0fa2ebc5..914564a528c360f352927e7681ab2e31ed365b21 100644 +index 3aa4cb526f04a171ace0b95d18ecebc9a002470a..ac6bdf21d5ff8ba563f8c9187f6a8dcc823587aa 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java -@@ -71,6 +71,7 @@ public abstract class BaseSpawner { +@@ -57,6 +57,7 @@ public abstract class BaseSpawner { } public boolean isNearPlayer(Level world, BlockPos pos) { @@ -17313,7 +17380,7 @@ index 6eca4a9b3cf462a4d18f32619bbcdfda0fa2ebc5..914564a528c360f352927e7681ab2e31 } diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index aaa07fcd4b32fe0de88142ab30378327a01f1729..bc8555d21d418f9da37cc089904f7cb038b1cdbe 100644 +index ff0b7b9e4ae3aa0c170d05bc51fd7ff26e7531ee..53d4000593d4c79de8e8ab04bfd614b7ee0ad7a5 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java @@ -191,7 +191,7 @@ public interface EntityGetter { @@ -17326,10 +17393,10 @@ index aaa07fcd4b32fe0de88142ab30378327a01f1729..bc8555d21d418f9da37cc089904f7cb0 if (range < 0.0D || d < range * range) { return true; diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 45243249a561440512ef2a620c60b02e159c80e2..ef9b1687dd2dfda5398523140aecc678b4690642 100644 +index 210b6d71207b99e66ba014b176b2c1445053b1d1..1223e678395e84859449a11e9e403454ddae0b15 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -87,7 +87,7 @@ public class Explosion { +@@ -97,7 +97,7 @@ public class Explosion { this.hitPlayers = Maps.newHashMap(); this.level = world; this.source = entity; @@ -17338,7 +17405,7 @@ index 45243249a561440512ef2a620c60b02e159c80e2..ef9b1687dd2dfda5398523140aecc678 this.x = x; this.y = y; this.z = z; -@@ -403,10 +403,27 @@ public class Explosion { +@@ -425,10 +425,27 @@ public class Explosion { public void explode() { // CraftBukkit start @@ -17367,37 +17434,37 @@ index 45243249a561440512ef2a620c60b02e159c80e2..ef9b1687dd2dfda5398523140aecc678 this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); Set set = Sets.newHashSet(); boolean flag = true; -@@ -706,7 +723,7 @@ public class Explosion { - if (!iblockdata.isAir() && iblockdata.isDestroyable()) { // Paper - BlockPos blockposition1 = blockposition.immutable(); +@@ -659,7 +676,7 @@ public class Explosion { + } -- this.level.getProfiler().push("explosion_blocks"); -+ //this.level.getProfiler().push("explosion_blocks"); // Purpur - if (block.dropFromExplosion(this)) { - Level world = this.level; + if (flag1) { +- this.level.getProfiler().push("explosion_blocks"); ++ // this.level.getProfiler().push("explosion_blocks"); // Purpur + List> list = new ArrayList(); -@@ -728,7 +745,7 @@ public class Explosion { - - this.level.setBlock(blockposition, Blocks.AIR.defaultBlockState(), 3); - block.wasExploded(this.level, blockposition, this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur - } + Util.shuffle(this.toBlow, this.level.random); +@@ -735,7 +752,7 @@ public class Explosion { + Block.popResource(this.level, (BlockPos) pair.getSecond(), (ItemStack) pair.getFirst()); } +- this.level.getProfiler().pop(); ++ // this.level.getProfiler().pop(); // Purpur + } + + if (this.fire) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9be7dab401 100644 +index 2902c29cd7f0b99b84cff3664fc4ec15a383e41b..b58402221840a9e72b30a31d884b0fb2d86883fd 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 { - // Paper end +@@ -179,6 +179,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Paper end - add paper world config 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 public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -193,6 +194,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -196,6 +197,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - fix and optimise world upgrading @@ -17447,22 +17514,24 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b public CraftWorld getWorld() { return this.world; } -@@ -210,11 +254,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -212,12 +256,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Paper end 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 + 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 - create paper world config; 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 + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config + 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; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); -@@ -1255,18 +1301,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1269,18 +1315,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } protected void tickBlockEntities() { @@ -17484,9 +17553,9 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b - this.timings.tileEntityTick.startTiming(); // Spigot + //this.timings.tileEntityTick.startTiming(); // Spigot // Purpur // Spigot start - // Iterator iterator = this.blockEntityTickers.iterator(); - int tilesThisCycle = 0; -@@ -1299,10 +1345,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Iterator iterator = this.blockEntityTickers.iterator(); + boolean flag = this.tickRateManager().runsNormally(); +@@ -1309,10 +1355,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } this.blockEntityTickers.removeAll(toRemove); @@ -17499,7 +17568,7 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b this.spigotConfig.currentPrimedTnt = 0; // Spigot } -@@ -1505,7 +1551,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1522,7 +1568,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { @@ -17508,7 +17577,7 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b List list = Lists.newArrayList(); ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call return list; -@@ -1524,7 +1570,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1541,7 +1587,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { @@ -17517,7 +17586,7 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b // Paper start - optimise this call //TODO use limit if (filter instanceof net.minecraft.world.entity.EntityType entityTypeTest) { -@@ -1781,7 +1827,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1800,7 +1846,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { @@ -17526,7 +17595,7 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b return (ProfilerFiller) this.profiler.get(); } -@@ -1881,4 +1927,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1912,4 +1958,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } } // Paper end - notify observers even if grow failed @@ -17542,7 +17611,7 @@ index 99e1c645871be28d130319b65700a1b8db093de4..25540a7f5631acd856726cdb44bace9b + // 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 9c2d62feff1816f5729060c6192269a5b2d34153..a2a59dd2e515bf4dca84a442703c122fd36f05e0 100644 +index 3fb96de68b93e8d33bd5ab9137e5d4facc94d788..22e12f0028187cf6c92aa0bf1f67764daae6f151 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 { @@ -17577,10 +17646,10 @@ index 9c2d62feff1816f5729060c6192269a5b2d34153..a2a59dd2e515bf4dca84a442703c122f if (entityhuman != null) { double d2 = entityhuman.distanceToSqr(d0, (double) i, d1); diff --git a/src/main/java/net/minecraft/world/level/block/AnvilBlock.java b/src/main/java/net/minecraft/world/level/block/AnvilBlock.java -index 5c5a3b169795bf8a527b316c666cbc2105c66622..020afeca950d2c7fb6c7b179d424548fd90f8b0d 100644 +index 9fca247f51e8b4d445f61ab5c16faf3928626deb..583bb1282fedcab75dbe4359a9f53b76a538d903 100644 --- a/src/main/java/net/minecraft/world/level/block/AnvilBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AnvilBlock.java -@@ -55,6 +55,54 @@ public class AnvilBlock extends FallingBlock { +@@ -62,6 +62,54 @@ public class AnvilBlock extends FallingBlock { @Override public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { @@ -17636,10 +17705,10 @@ index 5c5a3b169795bf8a527b316c666cbc2105c66622..020afeca950d2c7fb6c7b179d424548f return InteractionResult.SUCCESS; } else { diff --git a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java -index 087f3b3cc180e16195efdc0b402701fd9f5d78b4..aa4e13f1c77f10221128569483497668cd2eb7d3 100644 +index 3ecc92439fc85d224ff52f41c5e34079e042a5e6..2336fea8c65d64a77a1afa4b8b976fb0d7da00eb 100644 --- a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java -@@ -43,6 +43,20 @@ public class AzaleaBlock extends BushBlock implements BonemealableBlock { +@@ -49,6 +49,20 @@ public class AzaleaBlock extends BushBlock implements BonemealableBlock { @Override public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { @@ -17657,14 +17726,14 @@ index 087f3b3cc180e16195efdc0b402701fd9f5d78b4..aa4e13f1c77f10221128569483497668 + + private void growTree(ServerLevel world, RandomSource random, BlockPos pos, net.minecraft.world.level.block.state.BlockState state) { + // Purpur end - TREE_GROWER.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); + TreeGrower.AZALEA.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); } diff --git a/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java b/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java -index 3d2b34c5a7c9b00c1164b4f89c2cbff81fc460eb..b5505e926e5cdb447de68e8eb8e46c97eb988e27 100644 +index 2a65c7b859b1126dbac9819a01ca2652e20498a9..3192edee23b899107b17e354ddfb3159ac2ef429 100644 --- a/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java -@@ -35,6 +35,7 @@ public class BaseCoralPlantTypeBlock extends Block implements SimpleWaterloggedB +@@ -39,6 +39,7 @@ public abstract class BaseCoralPlantTypeBlock extends Block implements SimpleWat } protected static boolean scanForWater(BlockState state, BlockGetter world, BlockPos pos) { @@ -17673,28 +17742,28 @@ index 3d2b34c5a7c9b00c1164b4f89c2cbff81fc460eb..b5505e926e5cdb447de68e8eb8e46c97 return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index d40500f9a807cab0b2fb6fa9032f33f4fb74c895..2b66ddafaaca17f64d1e7502dfa4d7576e3e032f 100644 +index 2c1d03237d5b24b93807c7e97d969ace13d6a917..59fb467c3338edc7caf5103ad7c6becfc6311aa6 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -96,7 +96,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -106,7 +106,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = pos.getCenter(); -- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); -+ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state ++ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Paper - add exploded state // Purpur return InteractionResult.SUCCESS; } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first -@@ -149,7 +149,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -159,7 +159,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = blockposition.getCenter(); -- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); -+ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state ++ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Paper - add exploded state // Purpur return InteractionResult.SUCCESS; } } -@@ -173,7 +173,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -183,7 +183,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -17704,10 +17773,10 @@ index d40500f9a807cab0b2fb6fa9032f33f4fb74c895..2b66ddafaaca17f64d1e7502dfa4d757 @Override diff --git a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -index 54cf35b0c48d96ecfb27ff13cd685c16a1cd616b..1822ea0c72cc1685aab86a44f75c791bc5c595fa 100644 +index 8e4a6a1188b2ce2825dc5750505212c72efb5c7b..c7f78ccb228d261984ac360f2ca6ae9478786184 100644 --- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -@@ -236,7 +236,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone +@@ -243,7 +243,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone BigDripleafBlock.playTiltSound(world, blockposition, soundeffect); } @@ -17717,10 +17786,10 @@ index 54cf35b0c48d96ecfb27ff13cd685c16a1cd616b..1822ea0c72cc1685aab86a44f75c791b if (i != -1) { world.scheduleTick(blockposition, (Block) this, i); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca885627014444563a 100644 +index 3f2fdf73e2e520838c7b59fe994e67ab2d1a4d6b..4543aa29d73bcff5d2e1e4b4f8bfaf53444d6322 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -62,6 +62,13 @@ import net.minecraft.world.phys.shapes.Shapes; +@@ -63,6 +63,13 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; @@ -17733,8 +17802,8 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 + public class Block extends BlockBehaviour implements ItemLike { - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -87,6 +94,10 @@ public class Block extends BlockBehaviour implements ItemLike { + public static final MapCodec CODEC = simpleCodec(Block::new); +@@ -89,6 +96,10 @@ public class Block extends BlockBehaviour implements ItemLike { public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; @@ -17745,7 +17814,7 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 // Paper start public final boolean isDestroyable() { return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || -@@ -313,7 +324,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -320,7 +331,7 @@ public class Block extends BlockBehaviour implements ItemLike { public static void dropResources(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockEntity blockEntity) { if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity).forEach((itemstack) -> { @@ -17754,23 +17823,23 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 }); state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); } -@@ -329,7 +340,7 @@ public class Block extends BlockBehaviour implements ItemLike { - io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.block.CraftBlock.at(world, source), items); +@@ -338,7 +349,7 @@ public class Block extends BlockBehaviour implements ItemLike { + event.setExpToDrop(block.getExpDrop(state, (ServerLevel) world, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping event.callEvent(); for (var drop : event.getDrops()) { - popResource(world.getMinecraftWorld(), pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop)); + popResource(world.getMinecraftWorld(), pos, applyDisplayNameAndLoreFromTile(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop), blockEntity)); // Purpur } - state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, true); - } -@@ -340,13 +351,53 @@ public class Block extends BlockBehaviour implements ItemLike { - public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { + state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping + block.popExperience((ServerLevel) world, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping +@@ -355,13 +366,53 @@ public class Block extends BlockBehaviour implements ItemLike { + // Paper end - Properly handle xp dropping if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { - Block.popResource(world, pos, itemstack1); + Block.popResource(world, pos, applyDisplayNameAndLoreFromTile(itemstack1, blockEntity)); // Purpur }); - state.spawnAfterBreak((ServerLevel) world, pos, tool, true); + state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping } } @@ -17818,8 +17887,8 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 public static void popResource(Level world, BlockPos pos, ItemStack stack) { double d0 = (double) EntityType.ITEM.getHeight() / 2.0D; double d1 = (double) pos.getX() + 0.5D + Mth.nextDouble(world.random, -0.25D, 0.25D); -@@ -430,7 +481,17 @@ public class Block extends BlockBehaviour implements ItemLike { - } // Paper +@@ -445,7 +496,17 @@ public class Block extends BlockBehaviour implements ItemLike { + } // Paper - fix drops not preventing stats/food exhaustion } - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} @@ -17837,7 +17906,7 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 public boolean isPossibleToRespawnInThis(BlockState state) { return !state.isSolid() && !state.liquid(); -@@ -449,7 +510,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -464,7 +525,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -17847,10 +17916,10 @@ index d4cbff18adb62073a1dceb189043789620af6877..65504432a13df45e895cf6ca88562701 public void updateEntityAfterFallOn(BlockGetter world, Entity entity) { diff --git a/src/main/java/net/minecraft/world/level/block/Blocks.java b/src/main/java/net/minecraft/world/level/block/Blocks.java -index d5654cfe37bd82f1290b280990a8502432491ae1..6425bc42bb8024aa7936b841d6c2ee2c892eb329 100644 +index 9a2de546dc2af2ad4bf5d32ca6583f0e1f3f70d8..3d48293c34fa37ba5091c6058dadb32a8f74a009 100644 --- a/src/main/java/net/minecraft/world/level/block/Blocks.java +++ b/src/main/java/net/minecraft/world/level/block/Blocks.java -@@ -1094,8 +1094,8 @@ public class Blocks { +@@ -1145,8 +1145,8 @@ public class Blocks { public static final Block CAVE_VINES = register("cave_vines", new CaveVinesBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES).pushReaction(PushReaction.DESTROY))); public static final Block CAVE_VINES_PLANT = register("cave_vines_plant", new CaveVinesPlantBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES).pushReaction(PushReaction.DESTROY))); public static final Block SPORE_BLOSSOM = register("spore_blossom", new SporeBlossomBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instabreak().noCollission().sound(SoundType.SPORE_BLOSSOM).pushReaction(PushReaction.DESTROY))); @@ -17861,7 +17930,7 @@ index d5654cfe37bd82f1290b280990a8502432491ae1..6425bc42bb8024aa7936b841d6c2ee2c public static final Block MOSS_CARPET = register("moss_carpet", new CarpetBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS_CARPET).pushReaction(PushReaction.DESTROY))); public static final Block PINK_PETALS = register("pink_petals", new PinkPetalsBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().sound(SoundType.PINK_PETALS).pushReaction(PushReaction.DESTROY))); public static final Block MOSS_BLOCK = register("moss_block", new MossBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS).pushReaction(PushReaction.DESTROY))); -@@ -1160,7 +1160,7 @@ public class Blocks { +@@ -1215,7 +1215,7 @@ public class Blocks { } private static Boolean ocelotOrParrot(BlockState state, BlockGetter world, BlockPos pos, EntityType type) { @@ -17869,12 +17938,12 @@ index d5654cfe37bd82f1290b280990a8502432491ae1..6425bc42bb8024aa7936b841d6c2ee2c + return type == EntityType.OCELOT || type == EntityType.PARROT; // Purpur - decompile error } - private static BedBlock bed(DyeColor color) { + private static Block bed(DyeColor color) { diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java -index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..ca906b0250e5332f7ececf1419ca6d2c1d385adc 100644 +index bed3d9c781c7d3ca260027b4737970889a54689c..db1941ed32d141327a8b11e54b3ff9900072ad36 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java -@@ -48,4 +48,24 @@ public class BushBlock extends Block { +@@ -52,4 +52,24 @@ public abstract class BushBlock extends Block { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return type == PathComputationType.AIR && !this.hasCollision ? true : super.isPathfindable(state, world, pos, type); } @@ -17900,19 +17969,19 @@ index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..ca906b0250e5332f7ececf1419ca6d2c + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index 0003fb51ae3a6575575e10b4c86719f3061e2577..fa6a2fbb8065b1f120750491b7e4b89542a6a891 100644 +index a9629a102c4fa4e5720e63fcf4590e9231426c62..a476f9a1eaa99b557962947149b6ee6ea3288d6e 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -22,7 +22,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; +@@ -23,7 +23,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -public class CactusBlock extends Block { +public class CactusBlock extends Block implements BonemealableBlock { // Purpur + public static final MapCodec CODEC = simpleCodec(CactusBlock::new); public static final IntegerProperty AGE = BlockStateProperties.AGE_15; - public static final int MAX_AGE = 15; -@@ -107,7 +107,7 @@ public class CactusBlock extends Block { +@@ -114,7 +114,7 @@ public class CactusBlock extends Block { enumdirection = (Direction) iterator.next(); iblockdata1 = world.getBlockState(pos.relative(enumdirection)); @@ -17921,7 +17990,7 @@ index 0003fb51ae3a6575575e10b4c86719f3061e2577..fa6a2fbb8065b1f120750491b7e4b895 return false; } -@@ -129,4 +129,34 @@ public class CactusBlock extends Block { +@@ -136,4 +136,34 @@ public class CactusBlock extends Block { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return false; } @@ -17957,10 +18026,10 @@ index 0003fb51ae3a6575575e10b4c86719f3061e2577..fa6a2fbb8065b1f120750491b7e4b895 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..cfa02b274286374c7555919d0e8d66a2c8fb8b88 100644 +index 7302d07c6ff69608e75ac52fdb19f2ec1d105129..35e2f279d358201384ff74fd767df18f6fda432b 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -@@ -123,7 +123,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB +@@ -138,7 +138,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB BlockPos blockposition = ctx.getClickedPos(); boolean flag = world.getFluidState(blockposition).getType() == Fluids.WATER; @@ -17970,10 +18039,10 @@ index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..cfa02b274286374c7555919d0e8d66a2 @Override diff --git a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java -index 23c487e295b3b736d8800f0c884324c9b18a5373..ebeb7caf7fd4f45714bab0856a48b847a544cce7 100644 +index cdd7ab3fe589d089c0c03508721f46f6c136fc8a..6f148028c0fe503e9f6b327596d0954ce9e53269 100644 --- a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java -@@ -64,7 +64,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { +@@ -71,7 +71,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { SnowGolem entitysnowman = (SnowGolem) EntityType.SNOW_GOLEM.create(world); if (entitysnowman != null) { @@ -17982,7 +18051,7 @@ index 23c487e295b3b736d8800f0c884324c9b18a5373..ebeb7caf7fd4f45714bab0856a48b847 } } else { BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection1 = this.getOrCreateIronGolemFull().find(world, pos); -@@ -74,7 +74,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { +@@ -81,7 +81,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { if (entityirongolem != null) { entityirongolem.setPlayerCreated(true); @@ -17991,7 +18060,7 @@ index 23c487e295b3b736d8800f0c884324c9b18a5373..ebeb7caf7fd4f45714bab0856a48b847 } } } -@@ -82,6 +82,16 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { +@@ -89,6 +89,16 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { } private static void spawnGolemInWorld(Level world, BlockPattern.BlockPatternMatch patternResult, Entity entity, BlockPos pos) { @@ -18009,10 +18078,10 @@ index 23c487e295b3b736d8800f0c884324c9b18a5373..ebeb7caf7fd4f45714bab0856a48b847 entity.moveTo((double) pos.getX() + 0.5D, (double) pos.getY() + 0.05D, (double) pos.getZ() + 0.5D, 0.0F, 0.0F); // CraftBukkit start diff --git a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java -index 2f85b893dd0abc39fcedec65acc89e1567faf6f0..3ee012a9ef8cada0b2203e53b2f731f60f697cb1 100644 +index a821a981adbebdcf22997731b9bbea3d033cd2b1..028419d45c098baf5eab5d6e7a73189cb3e86622 100644 --- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java -@@ -29,7 +29,7 @@ public class CauldronBlock extends AbstractCauldronBlock { +@@ -36,7 +36,7 @@ public class CauldronBlock extends AbstractCauldronBlock { } protected static boolean shouldHandlePrecipitation(Level world, Biome.Precipitation precipitation) { @@ -18022,10 +18091,10 @@ index 2f85b893dd0abc39fcedec65acc89e1567faf6f0..3ee012a9ef8cada0b2203e53b2f731f6 @Override diff --git a/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java b/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java -index ead7b37122c76d43af2cdd17af7f0da8014efb26..1acc2dcda68ec8e462d51927f2ea985e7952a830 100644 +index 54916c80720f219bf747250a2ff9a875f180c7a2..cae6d33728a39de9db908e1e24fdc3ad987d0542 100644 --- a/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java -@@ -88,4 +88,11 @@ public class CaveVinesBlock extends GrowingPlantHeadBlock implements Bonemealabl +@@ -94,4 +94,11 @@ public class CaveVinesBlock extends GrowingPlantHeadBlock implements Bonemealabl public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { world.setBlock(pos, state.setValue(BERRIES, Boolean.valueOf(true)), 2); } @@ -18038,23 +18107,23 @@ 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 +index daae7fd6e0148cfba8e359d990748a0c83a3376e..0e06b1bcd906e92c083dc74d56d6d0a2a36f62a7 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> { +@@ -67,7 +67,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) -> { + return random.nextFloat() < f1 ? this.getNext(state) : Optional.empty(); + } 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 af6e245b02d5fb78764d2db0ac200056277b212a..4ee31c5a6053237b15ddb8e3208cdb9a35a0d08d 100644 +index 9804ee2020e5cef23d3f5174d153fc149e611503..3a5e5cf88c5592e1bc3e6dc9eced2d1dd47bd145 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 +@@ -358,6 +358,7 @@ public class ChestBlock extends AbstractChestBlock implements } private static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) { @@ -18063,10 +18132,10 @@ index af6e245b02d5fb78764d2db0ac200056277b212a..4ee31c5a6053237b15ddb8e3208cdb9a return world.getBlockState(blockposition1).isRedstoneConductor(world, blockposition1); diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 10d3912ef043eefdf89105332e29b0d2bf4a5539..596b77306f690a2298835f0f0fea1abee2a7c85d 100644 +index d78fe4081bc2938326066e0afddb4a6c833a4bf7..70fbe678b27656f07b1048ab9ddfd755a64e0328 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -229,20 +229,28 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -236,20 +236,28 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { ItemStack itemstack = player.getItemInHand(hand); if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(itemstack.getItem())) { @@ -18107,7 +18176,7 @@ index 10d3912ef043eefdf89105332e29b0d2bf4a5539..596b77306f690a2298835f0f0fea1abe return InteractionResult.sidedSuccess(world.isClientSide); } else if (i == 8) { -@@ -253,6 +261,26 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -260,6 +268,26 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { } } @@ -18135,10 +18204,10 @@ index 10d3912ef043eefdf89105332e29b0d2bf4a5539..596b77306f690a2298835f0f0fea1abe int i = (Integer) state.getValue(ComposterBlock.LEVEL); diff --git a/src/main/java/net/minecraft/world/level/block/CoralBlock.java b/src/main/java/net/minecraft/world/level/block/CoralBlock.java -index 88faea00be60a519f56f975a5311df5e1eb3e6b8..cbb726ac367be81e27d3a86643baf7c4f0746edf 100644 +index 8fd8285e07de4a0457da507501e49a807542f3b1..e580c5a141bebdc45893b5abde01e633c864fc13 100644 --- a/src/main/java/net/minecraft/world/level/block/CoralBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CoralBlock.java -@@ -45,6 +45,7 @@ public class CoralBlock extends Block { +@@ -59,6 +59,7 @@ public class CoralBlock extends Block { } protected boolean scanForWater(BlockGetter world, BlockPos pos) { @@ -18147,10 +18216,10 @@ index 88faea00be60a519f56f975a5311df5e1eb3e6b8..cbb726ac367be81e27d3a86643baf7c4 int i = aenumdirection.length; diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java -index 6365ddea0c23bc5d4009d98915f2b39aed2a0328..61d051f42d8c3d1f039b97fdc7a61b54f57ee86a 100644 +index 9550ce8588c6aa3ba4cbbbb86912eae2b452eb01..2dbfc522990964b2ae5a9e5f84426e0749f92563 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java -@@ -172,7 +172,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { +@@ -179,7 +179,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper @@ -18159,27 +18228,27 @@ index 6365ddea0c23bc5d4009d98915f2b39aed2a0328..61d051f42d8c3d1f039b97fdc7a61b54 world.destroyBlock(pos, true, entity); } -@@ -207,4 +207,15 @@ public class CropBlock extends BushBlock implements BonemealableBlock { +@@ -214,4 +214,15 @@ public class CropBlock extends BushBlock implements BonemealableBlock { protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(CropBlock.AGE); } + + // Purpur start + @Override -+ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { ++ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops, boolean dropExp) { + if (world.purpurConfig.hoeReplantsCrops && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, getBaseSeedId()); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops, dropExp); + } + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/DoorBlock.java b/src/main/java/net/minecraft/world/level/block/DoorBlock.java -index c028a7158e41a0754abb8e24dcd647633fbf3fe8..cd65d32f4af016d4937e598c71386a3072f4c490 100644 +index ed57fbcfcff29a71026b0600b02daf4178d78429..31a5d3a5642123983b8c7df49be04f25141d15a2 100644 --- a/src/main/java/net/minecraft/world/level/block/DoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoorBlock.java -@@ -167,6 +167,7 @@ public class DoorBlock extends Block { +@@ -198,6 +198,7 @@ public class DoorBlock extends Block { public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (!this.type.canOpenByHand()) { return InteractionResult.PASS; @@ -18187,7 +18256,7 @@ index c028a7158e41a0754abb8e24dcd647633fbf3fe8..cd65d32f4af016d4937e598c71386a30 } else { state = (BlockState) state.cycle(DoorBlock.OPEN); world.setBlock(pos, state, 10); -@@ -270,4 +271,18 @@ public class DoorBlock extends Block { +@@ -301,4 +302,18 @@ public class DoorBlock extends Block { flag = false; return flag; } @@ -18207,10 +18276,10 @@ index c028a7158e41a0754abb8e24dcd647633fbf3fe8..cd65d32f4af016d4937e598c71386a30 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java b/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java -index 7e1edcc7b9f170b7c649437c2f0dd78c0bab9be4..5f8ac1fdac2c334951261f2b9702f5e711743c88 100644 +index 7f365143ce5c62e734eceb855ba0a02ab3a99b27..bbb266cbe23da2573d3dfb3a6edd57461988d3c5 100644 --- a/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java -@@ -42,8 +42,8 @@ public class DragonEggBlock extends FallingBlock { +@@ -49,8 +49,8 @@ public class DragonEggBlock extends FallingBlock { } private void teleport(BlockState state, Level world, BlockPos pos) { @@ -18221,10 +18290,10 @@ index 7e1edcc7b9f170b7c649437c2f0dd78c0bab9be4..5f8ac1fdac2c334951261f2b9702f5e7 BlockPos blockposition1 = pos.offset(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); diff --git a/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java b/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -index 839b7bc9392906dca384003468746963631fe095..286f34eef22a85be3fe9747dc3c3f9a7d51f437c 100644 +index 790cf30c2bfd4e2530ff563dfcf05e25554248b3..ba69e9b37ce9f2d8b439d471e6de770da38d6971 100644 --- a/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -@@ -29,6 +29,8 @@ import net.minecraft.world.level.pathfinder.PathComputationType; +@@ -30,6 +30,8 @@ import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -18232,8 +18301,8 @@ index 839b7bc9392906dca384003468746963631fe095..286f34eef22a85be3fe9747dc3c3f9a7 +import net.minecraft.world.item.Items; // Purpur public class EnchantmentTableBlock extends BaseEntityBlock { - protected static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D); -@@ -121,4 +123,18 @@ public class EnchantmentTableBlock extends BaseEntityBlock { + public static final MapCodec CODEC = simpleCodec(EnchantmentTableBlock::new); +@@ -128,4 +130,18 @@ public class EnchantmentTableBlock extends BaseEntityBlock { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return false; } @@ -18253,10 +18322,10 @@ index 839b7bc9392906dca384003468746963631fe095..286f34eef22a85be3fe9747dc3c3f9a7 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index 41d7cff39fc37955877668337689b4b26cd8c7cf..2deddc746e43896584bd65ba8e7971a80acb4a4d 100644 +index c82ebcac07033d887af499f81520982fbe5ed4f1..0b45bc1db5f57a4381c470a563aa81ac0d3a1be7 100644 --- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -46,6 +46,14 @@ public class EndPortalBlock extends BaseEntityBlock { +@@ -54,6 +54,14 @@ public class EndPortalBlock extends BaseEntityBlock { public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper if (world instanceof ServerLevel && entity.canChangeDimensions() && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) { @@ -18271,7 +18340,7 @@ index 41d7cff39fc37955877668337689b4b26cd8c7cf..2deddc746e43896584bd65ba8e7971a8 ResourceKey resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends ServerLevel worldserver = ((ServerLevel) world).getServer().getLevel(resourcekey); -@@ -53,6 +61,22 @@ public class EndPortalBlock extends BaseEntityBlock { +@@ -61,6 +69,22 @@ public class EndPortalBlock extends BaseEntityBlock { // return; // CraftBukkit - always fire event in case plugins wish to change it } @@ -18295,10 +18364,10 @@ index 41d7cff39fc37955877668337689b4b26cd8c7cf..2deddc746e43896584bd65ba8e7971a8 entity.portalWorld = ((ServerLevel)world); entity.portalBlock = pos.immutable(); diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -index 7385e91f32f070e86a4e0fd3d214f55d832c7979..7b73de87236a60ce7343c29ec147e1866b448ba3 100644 +index ddca14f1224327a738415fb8b37398d8df0aa9c8..fe3236295790b9e250486835176cae810160c33a 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -@@ -85,6 +85,34 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -92,6 +92,34 @@ public class EnderChestBlock extends AbstractChestBlock i EnderChestBlockEntity enderChestBlockEntity = (EnderChestBlockEntity)blockEntity; playerEnderChestContainer.setActiveChest(enderChestBlockEntity); player.openMenu(new SimpleMenuProvider((syncId, inventory, playerx) -> { @@ -18334,10 +18403,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 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..856099241737c43b8213ccc203ef6bb7b7667b1f 100644 +index 59bbdead2ebd8965d222540c7243dde051bbcc4b..c4eca9db159d6a581d863558ebc3008d51d25cfb 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -103,7 +103,7 @@ public class FarmBlock extends Block { +@@ -110,7 +110,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. @@ -18346,7 +18415,7 @@ index 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..856099241737c43b8213ccc203ef6bb7 // CraftBukkit start - Interact soil org.bukkit.event.Cancellable cancellable; if (entity instanceof Player) { -@@ -117,6 +117,22 @@ public class FarmBlock extends Block { +@@ -124,6 +124,22 @@ public class FarmBlock extends Block { return; } @@ -18369,7 +18438,7 @@ index 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..856099241737c43b8213ccc203ef6bb7 if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { return; } -@@ -164,7 +180,7 @@ public class FarmBlock extends Block { +@@ -171,7 +187,7 @@ public class FarmBlock extends Block { } } @@ -18379,10 +18448,10 @@ index 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..856099241737c43b8213ccc203ef6bb7 @Override diff --git a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a522304f28178 100644 +index 4ebdc4918131a15a1c91b45e8ceb1392bca20a81..2537f99baca6213618865d60f84e96b8a4849307 100644 --- a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +++ b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -@@ -30,12 +30,12 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements +@@ -34,12 +34,12 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements @Override public BlockState getStateForPlacement(LevelAccessor world) { @@ -18397,7 +18466,7 @@ index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a5223 } @Override -@@ -51,7 +51,7 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements +@@ -55,7 +55,7 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements } else { modifier = world.spigotConfig.caveVinesModifier; } @@ -18406,7 +18475,7 @@ index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a5223 // Spigot end BlockPos blockposition1 = pos.relative(this.growthDirection); -@@ -73,11 +73,11 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements +@@ -77,11 +77,11 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements } public BlockState getMaxAgeState(BlockState state) { @@ -18420,7 +18489,7 @@ index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a5223 } protected BlockState updateBodyAfterConvertedFromHead(BlockState from, BlockState to) { -@@ -119,13 +119,13 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements +@@ -123,13 +123,13 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements @Override public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { BlockPos blockposition1 = pos.relative(this.growthDirection); @@ -18436,7 +18505,7 @@ index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a5223 } } -@@ -138,4 +138,6 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements +@@ -142,4 +142,6 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements protected GrowingPlantHeadBlock getHeadBlock() { return this; } @@ -18444,10 +18513,10 @@ index b325fdec8eb99ce57152a5c0fefa5059685276e4..c93e60b01dd46e7de6a6b5a5149a5223 + public abstract int getMaxGrowthAge(); // Purpur } diff --git a/src/main/java/net/minecraft/world/level/block/HayBlock.java b/src/main/java/net/minecraft/world/level/block/HayBlock.java -index cfbe1dae76db76cf54a4f5d72aca72d5e893859e..74cb10230d459ac9f300a9d59af504d233ac663e 100644 +index ef364aa171a48482a45bc18cfe730ec20c3f7be6..74971d90506aa253d5ee821b5390fb2551a3a393 100644 --- a/src/main/java/net/minecraft/world/level/block/HayBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HayBlock.java -@@ -15,6 +15,6 @@ public class HayBlock extends RotatedPillarBlock { +@@ -23,6 +23,6 @@ public class HayBlock extends RotatedPillarBlock { @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -18456,10 +18525,10 @@ index cfbe1dae76db76cf54a4f5d72aca72d5e893859e..74cb10230d459ac9f300a9d59af504d2 } } diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java -index 04089e6f7d6e3d532b00585870283922b6be5246..61e6d14abd54ecd5e43a5459f8daa7d86adedf44 100644 +index 19f6e36daed6af02dca3bb88bb81000268264438..24d771e4196a4ed7d93ddefdc34879b82b129469 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java -@@ -33,7 +33,7 @@ public class IceBlock extends HalfTransparentBlock { +@@ -41,7 +41,7 @@ public class IceBlock extends HalfTransparentBlock { public void afterDestroy(Level world, BlockPos pos, ItemStack tool) { // Paper end if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) { @@ -18468,7 +18537,7 @@ index 04089e6f7d6e3d532b00585870283922b6be5246..61e6d14abd54ecd5e43a5459f8daa7d8 world.removeBlock(pos, false); return; } -@@ -61,7 +61,7 @@ public class IceBlock extends HalfTransparentBlock { +@@ -69,7 +69,7 @@ public class IceBlock extends HalfTransparentBlock { return; } // CraftBukkit end @@ -18478,10 +18547,10 @@ index 04089e6f7d6e3d532b00585870283922b6be5246..61e6d14abd54ecd5e43a5459f8daa7d8 } else { world.setBlockAndUpdate(pos, IceBlock.meltsInto()); diff --git a/src/main/java/net/minecraft/world/level/block/KelpBlock.java b/src/main/java/net/minecraft/world/level/block/KelpBlock.java -index ff30a93f4160e8e22b40c7a7033c14fa15839160..bf043e1b9f0ec5876a2fa2d0597ec3c60b32b2c0 100644 +index 4dbacee1930bc3955ce431e1d32353588b47afc9..a53c6ab63fd10ac94292836120152f54f23c1e13 100644 --- a/src/main/java/net/minecraft/world/level/block/KelpBlock.java +++ b/src/main/java/net/minecraft/world/level/block/KelpBlock.java -@@ -65,4 +65,11 @@ public class KelpBlock extends GrowingPlantHeadBlock implements LiquidBlockConta +@@ -72,4 +72,11 @@ public class KelpBlock extends GrowingPlantHeadBlock implements LiquidBlockConta public FluidState getFluidState(BlockState state) { return Fluids.WATER.getSource(false); } @@ -18494,10 +18563,10 @@ index ff30a93f4160e8e22b40c7a7033c14fa15839160..bf043e1b9f0ec5876a2fa2d0597ec3c6 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -index 4a1830f85f47014da63e4584f411d13f0f0cd8b3..17b3dbb83fd9eb6ecdd58c1ac6446410b4bc3a51 100644 +index 2bd097203f1e92d3fc343f91dc37220e09dd5066..016fe816819ab9022fd03c50427b62abbcd18b3c 100644 --- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -@@ -107,7 +107,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -139,7 +139,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { @@ -18506,7 +18575,7 @@ index 4a1830f85f47014da63e4584f411d13f0f0cd8b3..17b3dbb83fd9eb6ecdd58c1ac6446410 world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper } -@@ -135,7 +135,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -167,7 +167,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { @@ -18515,7 +18584,7 @@ index 4a1830f85f47014da63e4584f411d13f0f0cd8b3..17b3dbb83fd9eb6ecdd58c1ac6446410 world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world)); } -@@ -144,7 +144,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -176,7 +176,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { @@ -18525,10 +18594,10 @@ index 4a1830f85f47014da63e4584f411d13f0f0cd8b3..17b3dbb83fd9eb6ecdd58c1ac6446410 } diff --git a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -index 1b766045687e4dcded5cbcc50b746c55b9a34e22..be365914856593bb3c4e1945cc990786072f2953 100644 +index 10f5ffacc72a5e0116e2599ca83ee57a5b1ce0eb..31e6468f639de3ed0b25c3bc4ee09333c2150e1b 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -@@ -22,7 +22,7 @@ public class MagmaBlock extends Block { +@@ -29,7 +29,7 @@ public class MagmaBlock extends Block { @Override public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { @@ -18538,10 +18607,10 @@ index 1b766045687e4dcded5cbcc50b746c55b9a34e22..be365914856593bb3c4e1945cc990786 entity.hurt(world.damageSources().hotFloor(), 1.0F); org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = null; // CraftBukkit diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index a6ab0d0defc05e56a91084c49897059670a1324b..589b437e7c97c846410f293e2f014bdcd7cb333e 100644 +index ee998d06804e344ea9d5b84ef0074b84aaba04c2..673dd5cc5c83eb606aa5684b8ae14b82e0346a35 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -52,7 +52,7 @@ public class NetherPortalBlock extends Block { +@@ -60,7 +60,7 @@ public class NetherPortalBlock extends Block { @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { @@ -18550,7 +18619,7 @@ index a6ab0d0defc05e56a91084c49897059670a1324b..589b437e7c97c846410f293e2f014bdc while (world.getBlockState(pos).is((Block) this)) { pos = pos.below(); } -@@ -84,6 +84,14 @@ public class NetherPortalBlock extends Block { +@@ -92,6 +92,14 @@ public class NetherPortalBlock extends Block { public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper if (entity.canChangeDimensions()) { @@ -18566,30 +18635,30 @@ index a6ab0d0defc05e56a91084c49897059670a1324b..589b437e7c97c846410f293e2f014bdc EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); world.getCraftServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java -index e55720c4d2fbdf6aae526910e87a67c29cf906fd..7d15796e3637c1a865703807c98a22c01315c307 100644 +index 0fc333f240d6918e841a9221be42973839408802..13eb4dffd60ea7902d620f484df5e3f2c4688402 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java -@@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; +@@ -16,7 +16,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -public class NetherWartBlock extends BushBlock { +public class NetherWartBlock extends BushBlock implements BonemealableBlock { // Purpur + public static final MapCodec CODEC = simpleCodec(NetherWartBlock::new); public static final int MAX_AGE = 3; - public static final IntegerProperty AGE = BlockStateProperties.AGE_3; -@@ -60,4 +60,32 @@ public class NetherWartBlock extends BushBlock { +@@ -68,4 +68,32 @@ public class NetherWartBlock extends BushBlock { protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(NetherWartBlock.AGE); } + + // Purpur start + @Override -+ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { ++ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops, boolean dropExp) { + if (world.purpurConfig.hoeReplantsNetherWarts && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, Items.NETHER_WART); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops, dropExp); + } + } + @@ -18612,10 +18681,10 @@ index e55720c4d2fbdf6aae526910e87a67c29cf906fd..7d15796e3637c1a865703807c98a22c0 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -index e46d84750bdd7c940f400efda226e12a3fdc3848..6343cd0c33cafb30225cfae17ea1cf15859073b1 100644 +index ff16075fbfe664c73a46bc4b002450867974114e..604053c7b5b2b7f2f1666baa3e0ce5acf3b37e46 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -@@ -87,7 +87,7 @@ public class NoteBlock extends Block { +@@ -94,7 +94,7 @@ public class NoteBlock extends Block { } private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { @@ -18625,10 +18694,10 @@ index e46d84750bdd7c940f400efda226e12a3fdc3848..6343cd0c33cafb30225cfae17ea1cf15 // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE)); // if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/level/block/ObserverBlock.java b/src/main/java/net/minecraft/world/level/block/ObserverBlock.java -index 7b45d6b9a005036ca5051d089a7be792eb87012f..8806c97ecc6bdd8a64c2d82bb2f58f46ac37c468 100644 +index 713352b68f82d4c4a19a712d5207de0f99456713..d056e80c98973e9ba64adc5a8554acc8a5f3eac9 100644 --- a/src/main/java/net/minecraft/world/level/block/ObserverBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ObserverBlock.java -@@ -64,6 +64,7 @@ public class ObserverBlock extends DirectionalBlock { +@@ -71,6 +71,7 @@ public class ObserverBlock extends DirectionalBlock { @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { if (state.getValue(ObserverBlock.FACING) == direction && !(Boolean) state.getValue(ObserverBlock.POWERED)) { @@ -18637,10 +18706,10 @@ index 7b45d6b9a005036ca5051d089a7be792eb87012f..8806c97ecc6bdd8a64c2d82bb2f58f46 } diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index cd943997f11f5ea5c600fdc6db96043fb0fa713c..4adeda49a2e422e11f885bffb311653d99159bf4 100644 +index bd22d3fdecbc992b11073a74d854b7d1b43c3f6a..0a3b97f18abcc9b385c9efd5a30f3e2ce5e4bd59 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -186,7 +186,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -195,7 +195,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @VisibleForTesting public static void maybeTransferFluid(BlockState state, ServerLevel world, BlockPos pos, float dripChance) { @@ -18649,7 +18718,7 @@ index cd943997f11f5ea5c600fdc6db96043fb0fa713c..4adeda49a2e422e11f885bffb311653d if (PointedDripstoneBlock.isStalactiteStartPos(state, world, pos)) { Optional optional = PointedDripstoneBlock.getFluidAboveStalactite(world, pos, state); -@@ -195,13 +195,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -204,13 +204,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate float f1; if (fluidtype == Fluids.WATER) { @@ -18666,10 +18735,10 @@ index cd943997f11f5ea5c600fdc6db96043fb0fa713c..4adeda49a2e422e11f885bffb311653d if (dripChance < f1) { diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java -index e6fcea4482d5d87ed78beefad4c57bc86089460f..1626eb90a6b348ad9735b82452f52d4560075a03 100644 +index f579911b06b66e94e6311d970e93cca33fa089c6..2c63579226409a1823d2e8990e7ffc4250b83afb 100644 --- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java -@@ -73,7 +73,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { +@@ -80,7 +80,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { if (!world.isClientSide) { // CraftBukkit start if (entity.isOnFire() && entity.mayInteract(world, pos)) { @@ -18679,10 +18748,10 @@ index e6fcea4482d5d87ed78beefad4c57bc86089460f..1626eb90a6b348ad9735b82452f52d45 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -index 7fddb6fa8fd30ef88346a59f7867aae792f13772..40893e71fe8447b695350273bef9623bd5accdcd 100644 +index b84c48902ef24fdae17578a304e6c93dc20c5dce..e03125281767845564c48c98c3e6b6bbd269ade1 100644 --- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -@@ -23,7 +23,7 @@ public class PoweredRailBlock extends BaseRailBlock { +@@ -30,7 +30,7 @@ public class PoweredRailBlock extends BaseRailBlock { } protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { @@ -18692,23 +18761,23 @@ index 7fddb6fa8fd30ef88346a59f7867aae792f13772..40893e71fe8447b695350273bef9623b } else { int j = pos.getX(); diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java -index 2ed78cf83c0ae66a6ddba1ff307da89a24b0d0a8..ae17d6a54fad0bd2d71d306f418b5ced2f11b863 100644 +index ec7b5e089c2911c7833e3fd7db4018ca2e0d4e85..1734e2e9ac1e3e609cf58cfd8532433fc9559284 100644 --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java -@@ -141,7 +141,7 @@ public class RespawnAnchorBlock extends Block { +@@ -148,7 +148,7 @@ public class RespawnAnchorBlock extends Block { }; Vec3 vec3d = explodedPos.getCenter(); -- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper -+ if (world.purpurConfig.respawnAnchorExplode)world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, (float) world.purpurConfig.respawnAnchorExplosionPower, world.purpurConfig.respawnAnchorExplosionFire, world.purpurConfig.respawnAnchorExplosionEffect); // Paper // Purpur +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state ++ if (world.purpurConfig.respawnAnchorExplode)world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, (float) world.purpurConfig.respawnAnchorExplosionPower, world.purpurConfig.respawnAnchorExplosionFire, world.purpurConfig.respawnAnchorExplosionEffect);// Paper - add exploded state // Purpur } public static boolean canSetSpawn(Level world) { diff --git a/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java b/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java -index 02d01eabb9606ae8c3b76ad9fa4bb9a525e247b1..ce51fec4a874f9466f9966684c535315dbf40b9e 100644 +index 09c61eb5ba129e9630a756b452ef6aa61745c533..837c8399b2f490d98ca556e66018bfd471cf05bf 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java -@@ -130,7 +130,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -137,7 +137,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo @Nullable @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { @@ -18717,24 +18786,11 @@ index 02d01eabb9606ae8c3b76ad9fa4bb9a525e247b1..ce51fec4a874f9466f9966684c535315 } @Override -diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index d5fe3b8e2f5a8899f6afeb0600764284a617f261..2b513fc2f6c33963e43093cb08594bff946d72fa 100644 ---- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -135,7 +135,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { - public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity) { -- if (!world.isClientSide && player.isCreative() && !shulkerBoxBlockEntity.isEmpty()) { -+ if (world.purpurConfig.shulkerBoxAllowOversizedStacks || (!world.isClientSide && player.isCreative() && !shulkerBoxBlockEntity.isEmpty())) { // Purpur - ItemStack itemStack = getColoredItemStack(this.getColor()); - blockEntity.saveToItem(itemStack); - if (shulkerBoxBlockEntity.hasCustomName()) { diff --git a/src/main/java/net/minecraft/world/level/block/SlabBlock.java b/src/main/java/net/minecraft/world/level/block/SlabBlock.java -index ea8c78af35b0ddc0d08adfccfc78770b867e5df6..88cfa41f90d4ad395b96fd0b69ac0bdefe06ed2d 100644 +index adc7eba4bb5e8f7c507a16cdbd7497338a7658cf..512c528e0f2f3aa0da0253698a0189415329265a 100644 --- a/src/main/java/net/minecraft/world/level/block/SlabBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SlabBlock.java -@@ -131,4 +131,25 @@ public class SlabBlock extends Block implements SimpleWaterloggedBlock { +@@ -138,4 +138,25 @@ public class SlabBlock extends Block implements SimpleWaterloggedBlock { return false; } } @@ -18761,10 +18817,10 @@ index ea8c78af35b0ddc0d08adfccfc78770b867e5df6..88cfa41f90d4ad395b96fd0b69ac0bde + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java b/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java -index 14e00c7feb1c051d56a3d27cd00dcef072dd771a..4952fb1aaaafb55baa0fddb389f966a120a4786c 100644 +index a3da9536c3a3ad33d1c795673bdd7b05d6534054..9b057f3967aae5d0ca621b19d1212db91aaaee22 100644 --- a/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java -@@ -81,6 +81,12 @@ public class SnowLayerBlock extends Block { +@@ -88,6 +88,12 @@ public class SnowLayerBlock extends Block { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { BlockState iblockdata1 = world.getBlockState(pos.below()); @@ -18778,23 +18834,26 @@ index 14e00c7feb1c051d56a3d27cd00dcef072dd771a..4952fb1aaaafb55baa0fddb389f966a1 } diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java -index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad253814a0 100644 +index e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b7b24875c 100644 --- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java -@@ -40,6 +40,58 @@ public class SpawnerBlock extends BaseEntityBlock { +@@ -42,6 +42,60 @@ public class SpawnerBlock extends BaseEntityBlock { return createTickerHelper(type, BlockEntityType.MOB_SPAWNER, world.isClientSide ? SpawnerBlockEntity::clientTick : SpawnerBlockEntity::serverTick); } + // Purpur start + @Override -+ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack, boolean includeDrops) { ++ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack, boolean includeDrops, boolean dropExp) { + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) { -+ Optional> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn()); ++ java.util.Optional> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn()); + + net.minecraft.world.entity.EntityType entityType = type.orElse(null); + final net.kyori.adventure.text.Component mobName = io.papermc.paper.adventure.PaperAdventure.asAdventure(entityType == null ? Component.empty() : entityType.getDescription()); -+ CompoundTag display = new CompoundTag(); -+ CompoundTag tag = new CompoundTag(); ++ net.minecraft.nbt.CompoundTag display = new net.minecraft.nbt.CompoundTag(); ++ net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); ++ net.minecraft.nbt.CompoundTag blockEntityTag = blockEntity.getUpdateTag(); ++ blockEntityTag.remove("Delay"); // remove this tag to allow stacking duplicate spawners ++ tag.put("BlockEntityTag", blockEntityTag); + + String name = level.purpurConfig.silkTouchSpawnerName; + if (name != null && !name.isEmpty() && !name.equals("Monster Spawner")) { @@ -18822,14 +18881,13 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad + + ItemStack item = new ItemStack(Blocks.SPAWNER.asItem()); + if (entityType != null) { -+ tag.putString("Purpur.mob_type", entityType.getName()); -+ tag.putDouble("HideFlags", 32); // hides the "Interact with Spawn Egg" tooltip ++ tag.putDouble("HideFlags", ItemStack.TooltipPart.ADDITIONAL.getMask()); // hides the "Interact with Spawn Egg" tooltip + item.setTag(tag); + } + + popResource(level, pos, item); + } -+ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops); ++ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops, dropExp); + } + + private boolean isSilkTouch(Level level, ItemStack stack) { @@ -18840,7 +18898,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad @Override public void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { super.spawnAfterBreak(state, world, pos, tool, dropExperience); -@@ -48,6 +100,7 @@ public class SpawnerBlock extends BaseEntityBlock { +@@ -50,6 +104,7 @@ public class SpawnerBlock extends BaseEntityBlock { @Override public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { @@ -18849,10 +18907,10 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15); diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -index d810f6bf9a8a354e5b8994e51ec3672428277dde..cc1ac862526377b2ac7b66bc20f428dc1aed6e78 100644 +index c4667bea0708d12e228ec2a4c84fcee7e48ca08c..9e4146ecd36ff2698ee951660ed88290c80fd8f7 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -@@ -51,7 +51,7 @@ public class SpongeBlock extends Block { +@@ -58,7 +58,7 @@ public class SpongeBlock extends Block { private boolean removeWaterBreadthFirstSearch(Level world, BlockPos pos) { BlockStateListPopulator blockList = new BlockStateListPopulator(world); // CraftBukkit - Use BlockStateListPopulator @@ -18861,7 +18919,7 @@ index d810f6bf9a8a354e5b8994e51ec3672428277dde..cc1ac862526377b2ac7b66bc20f428dc Direction[] aenumdirection = SpongeBlock.ALL_DIRECTIONS; int i = aenumdirection.length; -@@ -70,7 +70,7 @@ public class SpongeBlock extends Block { +@@ -77,7 +77,7 @@ public class SpongeBlock extends Block { FluidState fluid = blockList.getFluidState(blockposition1); // CraftBukkit end @@ -18870,7 +18928,7 @@ index d810f6bf9a8a354e5b8994e51ec3672428277dde..cc1ac862526377b2ac7b66bc20f428dc return false; } else { Block block = iblockdata.getBlock(); -@@ -85,6 +85,10 @@ public class SpongeBlock extends Block { +@@ -92,6 +92,10 @@ public class SpongeBlock extends Block { if (iblockdata.getBlock() instanceof LiquidBlock) { blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit @@ -18882,10 +18940,10 @@ index d810f6bf9a8a354e5b8994e51ec3672428277dde..cc1ac862526377b2ac7b66bc20f428dc if (!iblockdata.is(Blocks.KELP) && !iblockdata.is(Blocks.KELP_PLANT) && !iblockdata.is(Blocks.SEAGRASS) && !iblockdata.is(Blocks.TALL_SEAGRASS)) { return false; diff --git a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..0882e67c5cf876e0fc58a4ca4accb4be40418983 100644 +index 77ae7b8ab24935d046cce1f8f7f476310876f9df..b683f3c2fcd37b17a732802738cd14be87065e54 100644 --- a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -@@ -92,4 +92,16 @@ public class StonecutterBlock extends Block { +@@ -99,4 +99,16 @@ public class StonecutterBlock extends Block { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return false; } @@ -18903,19 +18961,19 @@ index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..0882e67c5cf876e0fc58a4ca4accb4be + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java -index c3f500580d257e1397f2eb7c47b063a6fe6bb405..21a194fadb7d1f0a30f94caf999dabdd78847f36 100644 +index ceaec1776067b7635c3952025f00f13f4ea86c88..8b6c43b0a2fb4b89d6f63716e56074ef0e194e63 100644 --- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java -@@ -19,7 +19,7 @@ import net.minecraft.world.level.material.FluidState; +@@ -20,7 +20,7 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -public class SugarCaneBlock extends Block { +public class SugarCaneBlock extends Block implements BonemealableBlock { // Purpur + public static final MapCodec CODEC = simpleCodec(SugarCaneBlock::new); public static final IntegerProperty AGE = BlockStateProperties.AGE_15; - protected static final float AABB_OFFSET = 6.0F; -@@ -106,4 +106,34 @@ public class SugarCaneBlock extends Block { +@@ -113,4 +113,34 @@ public class SugarCaneBlock extends Block { protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(SugarCaneBlock.AGE); } @@ -18951,10 +19009,10 @@ index c3f500580d257e1397f2eb7c47b063a6fe6bb405..21a194fadb7d1f0a30f94caf999dabdd + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -index 07157822659288e76b2fba34db8d5d566506f33b..e23b920be6702ef6faf97b42fb8a87442707d6be 100644 +index b4646e26965e0f1f26c5019e7c6a13fdf22bdb47..9a76665c6369b4106d152370dc3d2f5645cb02b1 100644 --- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -162,7 +162,7 @@ public class TurtleEggBlock extends Block { +@@ -169,7 +169,7 @@ public class TurtleEggBlock extends Block { private boolean shouldUpdateHatchLevel(Level world) { float f = world.getTimeOfDay(1.0F); @@ -18963,7 +19021,7 @@ index 07157822659288e76b2fba34db8d5d566506f33b..e23b920be6702ef6faf97b42fb8a8744 } @Override -@@ -195,6 +195,31 @@ public class TurtleEggBlock extends Block { +@@ -202,6 +202,31 @@ public class TurtleEggBlock extends Block { } private boolean canDestroyEgg(Level world, Entity entity) { @@ -18997,10 +19055,10 @@ index 07157822659288e76b2fba34db8d5d566506f33b..e23b920be6702ef6faf97b42fb8a8744 } } diff --git a/src/main/java/net/minecraft/world/level/block/TwistingVinesBlock.java b/src/main/java/net/minecraft/world/level/block/TwistingVinesBlock.java -index 6866605c7ef5361b21130a19a59c3fa3660dfb19..dee5d76d29da13f8639ab5d392cd0143201e71ba 100644 +index b4f75d034fbaea8ca68c1b5c5715773e0b8a9036..d05939c4b2ae42a09ee9e97431e83babfc8ed76c 100644 --- a/src/main/java/net/minecraft/world/level/block/TwistingVinesBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TwistingVinesBlock.java -@@ -27,4 +27,11 @@ public class TwistingVinesBlock extends GrowingPlantHeadBlock { +@@ -34,4 +34,11 @@ public class TwistingVinesBlock extends GrowingPlantHeadBlock { protected boolean canGrowInto(BlockState state) { return NetherVines.isValidGrowthState(state); } @@ -19013,10 +19071,10 @@ index 6866605c7ef5361b21130a19a59c3fa3660dfb19..dee5d76d29da13f8639ab5d392cd0143 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/WeepingVinesBlock.java b/src/main/java/net/minecraft/world/level/block/WeepingVinesBlock.java -index e5c135ec059746b75fe58516809584221285cdbe..713c7e6e31a3e1097b612c77a4fce147c9252e0b 100644 +index 98e62d2cd3c106753c3be4a217e9107397d388ab..6a1fd51423c17cd1498cb313fa52314daaca0a29 100644 --- a/src/main/java/net/minecraft/world/level/block/WeepingVinesBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WeepingVinesBlock.java -@@ -27,4 +27,11 @@ public class WeepingVinesBlock extends GrowingPlantHeadBlock { +@@ -34,4 +34,11 @@ public class WeepingVinesBlock extends GrowingPlantHeadBlock { protected boolean canGrowInto(BlockState state) { return NetherVines.isValidGrowthState(state); } @@ -19029,10 +19087,10 @@ index e5c135ec059746b75fe58516809584221285cdbe..713c7e6e31a3e1097b612c77a4fce147 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -index 1aa0e921890d600c9274deb923da04e72b12bcc6..44bd7bee2665a05878fd2df935a700f02cd13a75 100644 +index fb180f0bcd20e51d41cfc924029c0b23d3d26258..688d161cd6725f494366c23668ebd6ff709b1587 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -@@ -69,6 +69,7 @@ public class WitherSkullBlock extends SkullBlock { +@@ -76,6 +76,7 @@ public class WitherSkullBlock extends SkullBlock { entitywither.moveTo((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F); entitywither.yBodyRot = shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F; entitywither.makeInvulnerable(); @@ -19041,7 +19099,7 @@ index 1aa0e921890d600c9274deb923da04e72b12bcc6..44bd7bee2665a05878fd2df935a700f0 if (!world.addFreshEntity(entitywither, SpawnReason.BUILD_WITHER)) { return; diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index a18aadbf7ae83713e1f2b21553185d8000bc7699..92e58d9503daf4cc9bc1f4c7785e159e0c1f4bf3 100644 +index 5eaab97a0c3b93a44a45e2ed11033fe01c0c95c2..af66c7eec6291b0bc9575f59c8210cd7f697232a 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -44,6 +44,7 @@ import net.minecraft.world.level.Level; @@ -19052,7 +19110,7 @@ index a18aadbf7ae83713e1f2b21553185d8000bc7699..92e58d9503daf4cc9bc1f4c7785e159e import net.minecraft.world.phys.Vec3; // CraftBukkit start import org.bukkit.craftbukkit.block.CraftBlock; -@@ -207,6 +208,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -208,6 +209,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit // Paper end } @@ -19075,7 +19133,7 @@ index a18aadbf7ae83713e1f2b21553185d8000bc7699..92e58d9503daf4cc9bc1f4c7785e159e // CraftBukkit start - add fields and methods private int maxStack = MAX_STACK; public List transaction = new java.util.ArrayList(); -@@ -324,6 +341,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -325,6 +342,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } ItemStack itemstack = (ItemStack) blockEntity.items.get(1); @@ -19097,7 +19155,7 @@ index a18aadbf7ae83713e1f2b21553185d8000bc7699..92e58d9503daf4cc9bc1f4c7785e159e boolean flag2 = !((ItemStack) blockEntity.items.get(0)).isEmpty(); boolean flag3 = !itemstack.isEmpty(); -@@ -409,6 +441,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -410,6 +442,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit setChanged(world, pos, state); } @@ -19164,7 +19222,7 @@ index 416aa989ebb18a8741cc9d605a1180ab830f6643..e38a0adf5463c48311ad08b8d2e5b5c2 @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index f13943db6f2fb923c52dcf9e8bf7000041d0a362..99ef8d7e3ee0ee9777d12ad825e728c38d886114 100644 +index 5a1da6316ff56ea94a1ba1b68ce51bdffcee9736..14482d8e275dcc61be506da6085186b49e03d222 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -88,6 +88,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -19212,7 +19270,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 cf09525efd2d53bf884cd6ec3b0b9229715895eb..1098cf5a7675ec742caf687cc8828e09cfd3125e 100644 +index dfd364ac4b7551a13c4c6c100b5e62c0dfb10595..f5bcfece7bba52234964da646370bc271043a631 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 { @@ -19282,7 +19340,7 @@ index cf09525efd2d53bf884cd6ec3b0b9229715895eb..1098cf5a7675ec742caf687cc8828e09 int exitTickCounter; // Paper - separate counter for checking if bee should exit to reduce exit attempts final int minOccupationTicks; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 370a25d2deb54f10a35ee24d9e7e92fbfde60edf..3431f1a00ae2918b91a6b7a449e613e6e12ff6d4 100644 +index a6f47fa9f6065ed669414996b447e2daf34b3495..0af2444ff86bdd0350d2c50543c917635d03995c 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -6,6 +6,8 @@ import net.minecraft.CrashReportCategory; @@ -19489,10 +19547,10 @@ index 65e1381bb2d10bd212463feb602c60f8fdb9ade1..b7370e64fd0d50e8725d7d5afc30af2e + // Purpur } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 38cde466714e5663cd416b6afd5d2558e139ec09..2d625f18f2ba42ee5a1ebeea78ca395ad6f88b37 100644 +index 9bc1e7f03106cc35ac79bc9d7cced2bc5871b36c..074e7ae55c9e291c24cd9b5fd6d6740bf964376a 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -202,16 +202,31 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -200,16 +200,31 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C return this.setText((SignText) textChanger.apply(signtext), front); } @@ -19526,7 +19584,7 @@ index 38cde466714e5663cd416b6afd5d2558e139ec09..2d625f18f2ba42ee5a1ebeea78ca395a } } -@@ -351,6 +366,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -349,6 +364,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C return ClientboundBlockEntityDataPacket.create(this); } @@ -19556,7 +19614,7 @@ index 38cde466714e5663cd416b6afd5d2558e139ec09..2d625f18f2ba42ee5a1ebeea78ca395a public CompoundTag getUpdateTag() { return this.saveWithoutMetadata(); 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 1ec80f9c901dff1c9f29befa5a8e3c3f6f37aaf7..7291e4056b8e46ab59b71818388ac55fbb12993f 100644 +index b7a0d8ffd1823a1d1edee6baaa62c15f69e6af3d..21cbe88178fe2a63900209b9907646a983a209f9 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 @@ -177,6 +177,15 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -19607,10 +19665,10 @@ index 744d91546d1a810f60a43c15ed74b4158f341a4a..354538daefa603f6df5a139b6bff87db } diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index e6a4a5898ffdcb2aa2bc01371a6d7dbc06d610ce..e46a097dc134672720bc753ec0da0a9102737d2c 100644 +index 7a29d43d06de9138c8db5d3f4af29d6b5dc60efc..2d4f11b173040a6fc9055890064ccd31e67d0f3a 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -81,7 +81,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -85,7 +85,7 @@ public abstract class BlockBehaviour implements FeatureElement { protected static final Direction[] UPDATE_SHAPE_ORDER = new Direction[]{Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH, Direction.DOWN, Direction.UP}; public final boolean hasCollision; @@ -19619,7 +19677,7 @@ index e6a4a5898ffdcb2aa2bc01371a6d7dbc06d610ce..e46a097dc134672720bc753ec0da0a91 protected final boolean isRandomlyTicking; protected final SoundType soundType; protected final float friction; -@@ -89,7 +89,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -93,7 +93,7 @@ public abstract class BlockBehaviour implements FeatureElement { protected final float jumpFactor; protected final boolean dynamicShape; protected final FeatureFlagSet requiredFeatures; @@ -19629,7 +19687,7 @@ 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 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef0172f9ff 100644 +index 1afac69b5bc7055d2adb07aea4755b87b246275c..c37aa33134b8602caae5ecff00439ad5e0005d18 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -122,7 +122,7 @@ public class LevelChunk extends ChunkAccess { @@ -19656,7 +19714,7 @@ index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef } boolean flag3 = iblockdata1.hasBlockEntity(); -@@ -800,7 +800,7 @@ public class LevelChunk extends ChunkAccess { +@@ -799,7 +799,7 @@ public class LevelChunk extends ChunkAccess { this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system if (this.needsDecoration) { @@ -19665,7 +19723,7 @@ index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -820,7 +820,7 @@ public class LevelChunk extends ChunkAccess { +@@ -819,7 +819,7 @@ public class LevelChunk extends ChunkAccess { } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -19674,7 +19732,7 @@ index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef } } } -@@ -1175,10 +1175,10 @@ public class LevelChunk extends ChunkAccess { +@@ -1174,10 +1174,10 @@ public class LevelChunk extends ChunkAccess { if (LevelChunk.this.isTicking(blockposition)) { try { @@ -19688,7 +19746,7 @@ index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1189,7 +1189,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1188,7 +1188,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}); } @@ -19697,7 +19755,7 @@ index 7fd68d4aba72b15b2e21e5c88b44e677b794fe57..66656c4cf157228c9f52b33b358713ef } catch (Throwable throwable) { if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes -@@ -1200,7 +1200,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1199,7 +1199,7 @@ public class LevelChunk extends ChunkAccess { // Paper end // Spigot start } finally { @@ -19719,13 +19777,13 @@ index 060e064625969610539dbf969ce773b877a7c579..32cd9df202704cdfb8fa06aaf0e738d4 final EntityType entityType = entity.getType(); final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); 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 dfeb3e336e06ef01f5401a362755030db942bb07..f74c5eda91a3d521763ec7bc33f23e0c62458cc2 100644 +index 7d7d37334321c844958ce09e77547dd61dcba6c8..e731fd6f196116f4995dc6de8ad06b1985abe22b 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -49,7 +49,7 @@ public class PhantomSpawner implements CustomSpawner { int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds; this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; - // Paper end + // Paper end - Ability to control player's insomnia and phantoms - if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) { + if (world.getSkyDarken() < world.purpurConfig.phantomSpawnMinSkyDarkness && world.dimensionType().hasSkyLight()) { // Purpur return 0; @@ -19780,7 +19838,7 @@ index c55f51e6db55f9fa66f53eef0e7a56af5f81d742..74688f4672936cd2ac629b9f2f404163 if (state.getBlock() instanceof LiquidBlockContainer) { ((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState); diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java -index c3f8e1e2dd89c168b8b4a15b589109db486bc8d7..70ddb3b130ee59a6e200ea5af3ac89f3c3fa9e9b 100644 +index 3bb4a9a1a6249e8ba2de237f801210e7f4fd5825..2d492d849ff73a738dfbcb16507feb89bf19a962 100644 --- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java +++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java @@ -180,7 +180,7 @@ public abstract class LavaFluid extends FlowingFluid { @@ -19807,7 +19865,7 @@ index c3f8e1e2dd89c168b8b4a15b589109db486bc8d7..70ddb3b130ee59a6e200ea5af3ac89f3 protected boolean canConvertToSource(Level world) { return world.getGameRules().getBoolean(GameRules.RULE_LAVA_SOURCE_CONVERSION); diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -index d280c98aed5262c4ce39526c917de884f25a8584..e7d9f6802520620a1dcf0938256ffe80fc72a6f0 100644 +index d8c26b02188a6d443c6ec73bd5fa2fa8197a5e59..a358c93be160df7daddc0b015f2606f8d545f243 100644 --- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java +++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java @@ -64,6 +64,13 @@ public abstract class WaterFluid extends FlowingFluid { @@ -19840,7 +19898,7 @@ index d23481453717f715124156b5d83f6448f720d049..a8af51a25b0f99c3a64d9150fdfcd6b8 startNode.g = 0.0F; startNode.h = this.getBestH(startNode, positions); // Paper - optimize collection diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -index 3583fcf5284bc5883308876dbd9886664b391e28..ba57accc272958da4714896baeadb52c99383561 100644 +index 2aca9b193db5dadc4fb90b8d7548277b698924aa..29ec2f9a35dd73e8a6adf2e4edcfe543270520d8 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java @@ -241,7 +241,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { @@ -19852,7 +19910,7 @@ index 3583fcf5284bc5883308876dbd9886664b391e28..ba57accc272958da4714896baeadb52c node = this.findAcceptedNode(x, y + 1, z, maxYStep - 1, prevFeetY, direction, nodeType); if (node != null && (node.type == BlockPathTypes.OPEN || node.type == BlockPathTypes.WALKABLE) && this.mob.getBbWidth() < 1.0F) { double g = (double)(x - direction.getStepX()) + 0.5D; -@@ -465,7 +465,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -471,7 +471,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { return BlockPathTypes.BLOCKED; } else { // Paper end @@ -19861,7 +19919,7 @@ index 3583fcf5284bc5883308876dbd9886664b391e28..ba57accc272958da4714896baeadb52c return BlockPathTypes.DANGER_OTHER; } -@@ -498,7 +498,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -504,7 +504,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { } else if (!blockState.is(BlockTags.TRAPDOORS) && !blockState.is(Blocks.LILY_PAD) && !blockState.is(Blocks.BIG_DRIPLEAF)) { if (blockState.is(Blocks.POWDER_SNOW)) { return BlockPathTypes.POWDER_SNOW; @@ -19871,7 +19929,7 @@ index 3583fcf5284bc5883308876dbd9886664b391e28..ba57accc272958da4714896baeadb52c return BlockPathTypes.STICKY_HONEY; } else if (blockState.is(Blocks.COCOA)) { 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 c461e0d04047db9c0c5ecc04063cebd38bf96ec2..e7554ec800f321e4e34c926c53f2375a8c3aa979 100644 +index 590cd053a1b1c2a489772a2879998725fe0d783c..ba3f79cc1f7e672f0a9d32d262122ec6eba22b97 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java @@ -34,7 +34,7 @@ public class PortalShape { @@ -19914,7 +19972,7 @@ index 3fb1e558c3510243c94981211f9a0e5e0ef1895b..e5177e5ffcac360f935f2139db4554c6 if (context.hasParam(LootContextParams.LOOTING_MOD)) { i = context.getParamOrNull(LootContextParams.LOOTING_MOD); diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java -index e3dbf3066337a482460238f8a94d854cf88adfa2..5c70aa2ce1a9e89c8c271201b6755ea1325058ac 100644 +index 67d595f75e0c3bffdb27b85b25ccd1f0bf1427d5..4d0c524af87d05dbd4a923ad6c40e1f26149e921 100644 --- a/src/main/java/net/minecraft/world/phys/AABB.java +++ b/src/main/java/net/minecraft/world/phys/AABB.java @@ -374,4 +374,10 @@ public class AABB { @@ -19962,7 +20020,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 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..d0e3b531392738679894a989293ae49eb319676c 100644 +index 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..91fbc0cfc84045e32a4ee16fba8164de7901c7e6 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 @@ -20169,10 +20227,10 @@ index 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..d0e3b531392738679894a989293ae49e + File playerDir = server.console.playerDataStorage.getPlayerDir(); + try { + File tempFile = File.createTempFile(this.getUniqueId()+"-", ".dat", playerDir); -+ net.minecraft.nbt.NbtIo.writeCompressed(compoundTag, tempFile); ++ net.minecraft.nbt.NbtIo.writeCompressed(compoundTag, tempFile.toPath()); + File playerDataFile = new File(playerDir, this.getUniqueId()+".dat"); + File playerDataFileOld = new File(playerDir, this.getUniqueId()+".dat_old"); -+ net.minecraft.Util.safeReplaceFile(playerDataFile, tempFile, playerDataFileOld); ++ net.minecraft.Util.safeReplaceFile(playerDataFile.toPath(), tempFile.toPath(), playerDataFileOld.toPath()); + } catch (java.io.IOException e) { + e.printStackTrace(); + } @@ -20180,10 +20238,10 @@ index 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..d0e3b531392738679894a989293ae49e + // 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 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755c84a4b03 100644 +index cfc41926305441cb36ed67a8cb7e327cd80ff301..fd754fc9ff313421d221eea8d21fbde98be24914 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -269,7 +269,7 @@ import javax.annotation.Nullable; // Paper +@@ -264,7 +264,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -20192,8 +20250,8 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -401,6 +401,20 @@ public final class CraftServer implements Server { - this.dataPackManager = new CraftDataPackManager(this.getServer().getPackRepository()); +@@ -398,6 +398,20 @@ public final class CraftServer implements Server { + this.serverTickManager = new CraftServerTickManager(console.tickRateManager()); Bukkit.setServer(this); + // Purpur start @@ -20213,7 +20271,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 CraftRegistry.setMinecraftRegistry(console.registryAccess()); -@@ -1041,6 +1055,7 @@ public final class CraftServer implements Server { +@@ -1037,6 +1051,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); @@ -20221,7 +20279,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 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)) -@@ -1056,6 +1071,7 @@ public final class CraftServer implements Server { +@@ -1052,6 +1067,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot @@ -20229,7 +20287,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1071,6 +1087,7 @@ public final class CraftServer implements Server { +@@ -1067,6 +1083,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper @@ -20237,7 +20295,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -1537,6 +1554,55 @@ public final class CraftServer implements Server { +@@ -1570,6 +1587,55 @@ public final class CraftServer implements Server { return true; } @@ -20293,7 +20351,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 @Override public List getRecipesFor(ItemStack result) { Preconditions.checkArgument(result != null, "ItemStack cannot be null"); -@@ -2937,6 +3003,7 @@ public final class CraftServer implements Server { +@@ -2969,6 +3035,7 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { return new double[] { @@ -20301,7 +20359,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps15.getAverage() -@@ -2983,6 +3050,18 @@ public final class CraftServer implements Server { +@@ -3015,6 +3082,18 @@ public final class CraftServer implements Server { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } @@ -20320,7 +20378,7 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 @Override public void restart() { org.spigotmc.RestartCommand.restart(); -@@ -3201,4 +3280,16 @@ public final class CraftServer implements Server { +@@ -3237,4 +3316,16 @@ public final class CraftServer implements Server { } // Paper end @@ -20338,10 +20396,10 @@ index 2ecb8bfd98c141e9f5e7f4e441c8df91e1b9fbc2..a8a887236c68567816badc0620833755 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 90c76ddcb8af13409490b8976263d27a71954668..bc9a049df648fa5a169219bb009c92a213df9ffd 100644 +index f785e7b366175a32c834e1ebb56166a6fdcca3da..ae01fa8872c138afbd2d3f2b036392c3f47845c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2354,6 +2354,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2415,6 +2415,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } @@ -20391,7 +20449,7 @@ index 90c76ddcb8af13409490b8976263d27a71954668..bc9a049df648fa5a169219bb009c92a2 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 c737c5d62407337d3db2899cfc01713a058a6467..d41f9c4a3c992b5dadacb4fcb1107235fff79fa8 100644 +index ef8bbef6e4143b9432ee2ae2fb79e2aa2a9b84df..c7f8f85ad6cb76413275ebe64385a3ec7051257e 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -174,6 +174,20 @@ public class Main { @@ -20537,17 +20595,18 @@ 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 21e83238a0bad86ffacf60d5c5612771a49ef33d..a38149b8883195736ec6093aeb54971a89ec056c 100644 +index 4daf2c54c7127e8e091ffc49362f288594956143..f782e8dd9d3456f345859dffd69e5830d576ccd1 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 { - return EnchantmentTarget.CROSSBOW; - case VANISHABLE: - return EnchantmentTarget.VANISHABLE; -+ case BOW_AND_CROSSBOW: return EnchantmentTarget.BOW_AND_CROSSBOW; // Purpur - default: - return null; - } +@@ -80,6 +80,8 @@ public class CraftEnchantment extends Enchantment { + case TRIDENT -> EnchantmentTarget.TRIDENT; + case CROSSBOW -> EnchantmentTarget.CROSSBOW; + case VANISHABLE -> EnchantmentTarget.VANISHABLE; ++ case BOW_AND_CROSSBOW -> EnchantmentTarget.BOW_AND_CROSSBOW; // Purpur ++ case WEAPON_AND_SHEARS -> EnchantmentTarget.WEAPON_AND_SHEARS; // Purpur + }; + } + diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..985e9ec21c60a1f47973bd5fc53b96a6f9b7d04a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java @@ -20568,10 +20627,10 @@ 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 9f843b89dc20b91bf7243facee8486d525e4a1b3..aa8efff39ca3b2c2ed69a19f1872a295b7103c6b 100644 +index 1c3e1153d08b59d29b3613fc3b50a4780aa7a3ac..315c9be5841d55910500fcc225b5e42f271cf2cb 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 { +@@ -83,6 +83,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); } @@ -20590,10 +20649,10 @@ index 9f843b89dc20b91bf7243facee8486d525e4a1b3..aa8efff39ca3b2c2ed69a19f1872a295 + return getHandle().isSunBurnTick(); + } + - public static CraftEntity getEntity(CraftServer server, Entity entity) { - /* - * Order is *EXTREMELY* important -- keep it right! =D -@@ -600,6 +615,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + public static CraftEntity getEntity(CraftServer server, T entity) { + Preconditions.checkArgument(entity != null, "Unknown entity"); + +@@ -252,6 +267,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Paper end if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API @@ -20604,7 +20663,7 @@ index 9f843b89dc20b91bf7243facee8486d525e4a1b3..aa8efff39ca3b2c2ed69a19f1872a295 return false; } -@@ -1538,4 +1557,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1227,4 +1246,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getScoreboardName(); } // Paper end - entity scoreboard name @@ -20633,7 +20692,7 @@ index 9f843b89dc20b91bf7243facee8486d525e4a1b3..aa8efff39ca3b2c2ed69a19f1872a295 + // 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 aefb9879b2edadfb4b21d80135d713b9d34c9941..2a534391e49c0653fd98fe5c22e474ae7e82feef 100644 +index 827fe201a7b74f485abb46b127a28bf0cb479c3b..00f64a0ce2d32bf8b9a627495c043297e013633c 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 { @@ -20667,7 +20726,7 @@ index 63cae1a2e95d8da17c45c4404a8dd0ca6a413c39..966587c2788b5c93be83259ddc962a89 + // 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 f444e843535ec68ede0f05e7e7ef182ce872342b..f03a6fad31b240722a2b944d91282412cf79d884 100644 +index 81498941748d646ebe6495f4a7ce6953532144c6..ba33fb0b049a670851004022da18fe744dca27eb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -151,4 +151,51 @@ public class CraftItem extends CraftEntity implements Item { @@ -20723,10 +20782,10 @@ index f444e843535ec68ede0f05e7e7ef182ce872342b..f03a6fad31b240722a2b944d91282412 + // 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 6be370a2be88aac6e229210ef625380171504693..9c94fd78cbd0d3ef0c4dd3678262126b6ed2847b 100644 +index 1f1ef68a9a449a4a90c284f34a397ab4b6d905f6..a2d1c22e778aa4c3c44c3a1a604c1656cc86f0da 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 { +@@ -452,7 +452,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { net.minecraft.server.level.ServerPlayer entityPlayer = killer == null ? null : ((CraftPlayer) killer).getHandle(); getHandle().lastHurtByPlayer = entityPlayer; getHandle().lastHurtByMob = entityPlayer; @@ -20735,16 +20794,7 @@ index 6be370a2be88aac6e229210ef625380171504693..9c94fd78cbd0d3ef0c4dd3678262126b } // Paper end -@@ -465,7 +465,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - @Override - public boolean addPotionEffect(PotionEffect effect, boolean force) { - org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper -- 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; - } - -@@ -912,7 +912,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -915,7 +915,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return EntityCategory.WATER; } @@ -20753,7 +20803,7 @@ index 6be370a2be88aac6e229210ef625380171504693..9c94fd78cbd0d3ef0c4dd3678262126b } @Override -@@ -1115,4 +1115,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1118,4 +1118,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { getHandle().knockback(strength, directionX, directionZ); }; // Paper end @@ -20808,10 +20858,10 @@ 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 3a792ddc31e76038b84e8f87088c4cd94c349138..3b3bbeda831f82b6d9b284d85a31a1fff578a64f 100644 +index 99830dfacc0d4ff78f43f970b2d1486710c83ef3..f21e29d173b89d072c8422b80ae0132f67e74f6c 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 { +@@ -524,10 +524,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setPlayerListName(String name) { @@ -20828,7 +20878,7 @@ index 3a792ddc31e76038b84e8f87088c4cd94c349138..3b3bbeda831f82b6d9b284d85a31a1ff 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())); -@@ -1358,6 +1363,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1363,6 +1368,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API @@ -20839,7 +20889,7 @@ index 3a792ddc31e76038b84e8f87088c4cd94c349138..3b3bbeda831f82b6d9b284d85a31a1ff return false; } -@@ -2518,6 +2527,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2637,6 +2646,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -20868,7 +20918,7 @@ index 3a792ddc31e76038b84e8f87088c4cd94c349138..3b3bbeda831f82b6d9b284d85a31a1ff private void validateSpeed(float value) { Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); } -@@ -3303,4 +3334,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3373,4 +3404,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.spigot; } // Spigot end @@ -21021,10 +21071,10 @@ index 38b6d2c377800134de592a780b737b45c8096a11..449acd9dc983be1cd51208bc8f8d843d + // 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 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773b8ce45df 100644 +index 55c26840957f69860816c917c16f59d02074b388..b3d8e795683ab186295902aba7d476a689ff0f3f 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -594,6 +594,15 @@ public class CraftEventFactory { +@@ -591,6 +591,15 @@ public class CraftEventFactory { // Paper end craftServer.getPluginManager().callEvent(event); @@ -21040,7 +21090,7 @@ index 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773 return event; } -@@ -1071,6 +1080,7 @@ public class CraftEventFactory { +@@ -1070,6 +1079,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 @@ -21048,7 +21098,7 @@ index 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773 } event.setCancelled(cancelled); -@@ -1185,6 +1195,7 @@ public class CraftEventFactory { +@@ -1184,6 +1194,7 @@ public class CraftEventFactory { } else { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } @@ -21056,7 +21106,7 @@ index 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773 return event; } -@@ -1248,6 +1259,7 @@ public class CraftEventFactory { +@@ -1247,6 +1258,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 @@ -21065,10 +21115,10 @@ index 64ae7cfe765ebe697a2cce1b71751e628d6f1662..1920c154b43711473cdf29aeb881a773 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 b4bd318d61834d70d666577073f18e4c49ded113..a35f60b01b371673023bd23f47a8ddafd38787f2 100644 +index 977b77547f7ba62cef3640cf8d4f1c8e7cded53a..beae43e9b6fe447e7515d878ac175f461968768a 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 { +@@ -184,8 +184,19 @@ public class CraftContainer extends AbstractContainerMenu { case PLAYER: case CHEST: case ENDER_CHEST: @@ -21090,10 +21140,10 @@ index b4bd318d61834d70d666577073f18e4c49ded113..a35f60b01b371673023bd23f47a8ddaf case DISPENSER: case DROPPER: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java -index 471ae4458e7ea7c29d7551b32cec98180fbccd4e..23db63c78e9fcf86cd498b3ed36ca50253c2fe97 100644 +index af1ae3dacb628da23f7d2988c6e76d3fb2d64103..4ee2d501f882279b48edb4b8bf0824587c276bf6 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java -@@ -83,7 +83,7 @@ public class CraftInventory implements Inventory { +@@ -84,7 +84,7 @@ public class CraftInventory implements Inventory { @Override public void setContents(ItemStack[] items) { @@ -21143,10 +21193,10 @@ index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe + // 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 +index 090ba0b85fe72419c419cc72b5584ec391c0cfa1..e46018774aa99453f6fbb5dbb19513469d808700 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 { +@@ -597,4 +597,17 @@ public final class CraftItemFactory implements ItemFactory { return CraftItemStack.asCraftMirror(enchanted); } // Paper end - enchantWithLevels API @@ -21213,10 +21263,10 @@ index bac3a5c378054481e1a5abaec1f83afde5d64ac1..f1050bf2b9efc54a894426b08989d445 } this.customEffects.set(index, effect); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 13d25d118eb4d3ef35a4cdfb9bbde9ed83f6c04b..553ecc9b5631ffc0848a798bb3295f16d1722c1f 100644 +index 6ba29875d78ede4aa7978ff689e588f7fed11528..4afec4387971612f62b825e9e56c2ead7424a7c2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -@@ -30,6 +30,7 @@ public interface CraftRecipe extends Recipe { +@@ -29,6 +29,7 @@ public interface CraftRecipe extends Recipe { } else if (bukkit instanceof RecipeChoice.ExactChoice) { stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat)))); stack.exact = true; @@ -21225,7 +21275,7 @@ index 13d25d118eb4d3ef35a4cdfb9bbde9ed83f6c04b..553ecc9b5631ffc0848a798bb3295f16 throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -index 2677e21d8239bf0361a3bc5c9a50c328e54d70f6..544a79d5da661aff19e2019f7b83a3a49350bb68 100644 +index fde9aadd6c688b9797a6755f9d214918047598a0..ffaa80b645da3ddf2da828071090e01aa667504d 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java @@ -256,6 +256,7 @@ public final class CraftLegacy { @@ -21233,7 +21283,7 @@ index 2677e21d8239bf0361a3bc5c9a50c328e54d70f6..544a79d5da661aff19e2019f7b83a3a4 static { + if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressInitLegacyMaterialError) // Purpur - LOGGER.warn("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); // Paper - doesn't need to be an error + LOGGER.warn("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); // Paper - Improve logging and errors; doesn't need to be an error 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 @@ -21252,24 +21302,24 @@ index 15e9dd8844f893de5e8372b847c9e8295d6f69ca..b4b105c0190502328d5aeb680dd8e67c + // 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 844fb8c662a409670f631228f687d85c5436d3dd..2bfa5908f1848702ceb42da7576a609d0928eddd 100644 +index e938255fcc5db0c289d3e132175a541187e4a748..f7a747ea73a80c97d863e0fd3772a0c333aef3c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java -@@ -73,7 +73,7 @@ public class CraftPotionUtil { - +@@ -74,7 +74,7 @@ public class CraftPotionUtil { public static MobEffectInstance fromBukkit(PotionEffect effect) { MobEffect type = CraftPotionEffectType.bukkitToMinecraft(effect.getType()); + // Paper - Note: do not copy over the hidden effect, as this method is only used for applying to entities which we do not want to convert over. - 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) { -@@ -82,7 +82,7 @@ public class CraftPotionUtil { +@@ -83,7 +83,7 @@ public class CraftPotionUtil { int duration = effect.getDuration(); boolean ambient = effect.isAmbient(); boolean particles = effect.isVisible(); -- 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 +- return new PotionEffect(type, duration, amp, ambient, particles, effect.showIcon(), effect.hiddenEffect == null ? null : toBukkit(effect.hiddenEffect)); // Paper ++ return new PotionEffect(type, duration, amp, ambient, particles, effect.showIcon(), effect.hiddenEffect == null ? null : toBukkit(effect.hiddenEffect), effect.getKey()); // Paper // Purpur - add key } public static boolean equals(MobEffect mobEffect, PotionEffectType type) { @@ -21338,11 +21388,11 @@ index ea26d9464644b5217879b8c21b4da28e57708dcb..5835dc236b3f5291a804f7fb14a12eb4 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 891f850ea99dac1433f3e395e26be14c8abf2bfb..280ed3a3b61b3eadbb6f253cd4e058641e2c3d2e 100644 +index b3e1adeb932da9b3bed16acd94e2f16da48a7c72..d3ec817e95628f1fc8be4a29c9a0f13c7d5fd552 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 { - public void getScoreboardScores(ObjectiveCriteria criteria, String name, Consumer consumer) { + public void forAllObjectives(ObjectiveCriteria criteria, ScoreHolder holder, Consumer consumer) { // Paper start - add timings for scoreboard search // plugins leaking scoreboards will make this very expensive, let server owners debug it easily - co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.startTimingIfSync(); @@ -21351,7 +21401,7 @@ index 891f850ea99dac1433f3e395e26be14c8abf2bfb..280ed3a3b61b3eadbb6f253cd4e05864 // Paper end - add timings for scoreboard search for (CraftScoreboard scoreboard : this.scoreboards) { @@ -123,7 +123,7 @@ public final class CraftScoreboardManager implements ScoreboardManager { - board.forAllObjectives(criteria, name, (score) -> consumer.accept(score)); + board.forAllObjectives(criteria, holder, (score) -> consumer.accept(score)); } } finally { // Paper start - add timings for scoreboard search - co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.stopTimingIfSync(); @@ -21360,15 +21410,15 @@ index 891f850ea99dac1433f3e395e26be14c8abf2bfb..280ed3a3b61b3eadbb6f253cd4e05864 // 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 397c10f64db3a4d7296fe18585b56851bc3a1f01..1e81801e5701b08feedd840c1e1663ae26507c16 100644 +index c909efd2060dc95bd3ecb8c9fec36a1e69a642ff..6eeebfaf577263316f3562a8f968310acd616763 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -485,7 +485,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -482,7 +482,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { - return new gg.pufferfish.pufferfish.PufferfishVersionFetcher(); // Pufferfish -+ return new com.destroystokyo.paper.PaperVersionFetcher(); // Pufferfish // Purpur ++ return new com.destroystokyo.paper.PaperVersionFetcher(); // Purpur } @Override @@ -21386,7 +21436,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 ea732f8fe7b5dd56aab5d3a061a1cad19c49ae0b..8d2b0dc792120eda396947f5935052346f770567 100644 +index dd95b3bfe59f2bb635afe92317288efcd2986326..11f43f44f359ce57d3a8f3322e58b9f5dfdaf00a 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 { @@ -21408,7 +21458,7 @@ index ea732f8fe7b5dd56aab5d3a061a1cad19c49ae0b..8d2b0dc792120eda396947f593505234 DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands); diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..3633574e112f217b412217dd243a631dc4e9c40c +index 0000000000000000000000000000000000000000..e9fc2b4661f5275b93db5d3fdf25a8bdc3b38920 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -0,0 +1,655 @@ @@ -21489,8 +21539,8 @@ index 0000000000000000000000000000000000000000..3633574e112f217b412217dd243a631d + commands = new HashMap<>(); + commands.put("purpur", new PurpurCommand("purpur")); + -+ version = getInt("config-version", 33); -+ set("config-version", 33); ++ version = getInt("config-version", 34); ++ set("config-version", 34); + + readConfig(PurpurConfig.class, null); + @@ -22069,10 +22119,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..b9d1117885a8dd15f207e55ce5e402d8cefe0226 +index 0000000000000000000000000000000000000000..dab252cbadffbcdf19bacc0b378d671b29393e9c --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3241 @@ +@@ -0,0 +1,3302 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -22510,8 +22560,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + public double playerCriticalDamageMultiplier = 1.5D; + public int playerBurpDelay = 10; + public boolean playerBurpWhenFull = false; -+ public int playerPortalWaitTime = 80; -+ public int playerCreativePortalWaitTime = 1; + public boolean playerRidableInWater = false; + public boolean playerRemoveBindingWithWeakness = false; + public int shiftRightClickRepairsMendingPoints = 0; @@ -22540,8 +22588,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + playerCriticalDamageMultiplier = getDouble("gameplay-mechanics.player.critical-damage-multiplier", playerCriticalDamageMultiplier); + playerBurpDelay = getInt("gameplay-mechanics.player.burp-delay", playerBurpDelay); + playerBurpWhenFull = getBoolean("gameplay-mechanics.player.burp-when-full", playerBurpWhenFull); -+ playerPortalWaitTime = getInt("gameplay-mechanics.player.portal-wait-time", playerPortalWaitTime); -+ playerCreativePortalWaitTime = getInt("gameplay-mechanics.player.creative-portal-wait-time", playerCreativePortalWaitTime); + playerRidableInWater = getBoolean("gameplay-mechanics.player.ridable-in-water", playerRidableInWater); + playerRemoveBindingWithWeakness = getBoolean("gameplay-mechanics.player.curse-of-binding.remove-with-weakness", playerRemoveBindingWithWeakness); + shiftRightClickRepairsMendingPoints = getInt("gameplay-mechanics.player.shift-right-click-repairs-mending-points", shiftRightClickRepairsMendingPoints); @@ -22683,6 +22729,45 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + }); + set("gameplay-mechanics.shovel-turns-block-to-grass-path", null); + } ++ if (PurpurConfig.version < 34) { ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_chiseled_copper", Map.of("into", "minecraft:oxidized_chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_door", Map.of("into", "minecraft:oxidized_copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_trapdoor", Map.of("into", "minecraft:oxidized_copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_grate", Map.of("into", "minecraft:oxidized_copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_bulb", Map.of("into", "minecraft:oxidized_copper_bulb", "drops", new HashMap())); ++ ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap())); ++ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap())); ++ } + getMap("tools.axe.strippables", Map.ofEntries( + Map.entry("minecraft:oak_wood", Map.of("into", "minecraft:stripped_oak_wood", "drops", new HashMap())), + Map.entry("minecraft:oak_log", Map.of("into", "minecraft:stripped_oak_log", "drops", new HashMap())), @@ -22738,7 +22823,27 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + Map.entry("minecraft:waxed_cut_copper_stairs", Map.of("into", "minecraft:cut_copper_stairs", "drops", new HashMap())), + Map.entry("minecraft:waxed_exposed_cut_copper_stairs", Map.of("into", "minecraft:exposed_cut_copper_stairs", "drops", new HashMap())), + Map.entry("minecraft:waxed_weathered_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap())), -+ Map.entry("minecraft:waxed_oxidized_cut_copper_stairs", Map.of("into", "minecraft:oxidized_cut_copper_stairs", "drops", new HashMap()))) ++ Map.entry("minecraft:waxed_oxidized_cut_copper_stairs", Map.of("into", "minecraft:oxidized_cut_copper_stairs", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_exposed_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_weathered_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_oxidized_chiseled_copper", Map.of("into", "minecraft:oxidized_chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_exposed_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_weathered_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_oxidized_copper_door", Map.of("into", "minecraft:oxidized_copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_exposed_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_weathered_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_oxidized_copper_trapdoor", Map.of("into", "minecraft:oxidized_copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_exposed_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_weathered_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_oxidized_copper_grate", Map.of("into", "minecraft:oxidized_copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_exposed_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_weathered_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap())), ++ Map.entry("minecraft:waxed_oxidized_copper_bulb", Map.of("into", "minecraft:oxidized_copper_bulb", "drops", new HashMap()))) + ).forEach((blockId, obj) -> { + Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.waxables`: " + blockId); return; } @@ -22763,12 +22868,27 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + Map.entry("minecraft:exposed_cut_copper", Map.of("into", "minecraft:cut_copper", "drops", new HashMap())), + Map.entry("minecraft:weathered_cut_copper", Map.of("into", "minecraft:exposed_cut_copper", "drops", new HashMap())), + Map.entry("minecraft:oxidized_cut_copper", Map.of("into", "minecraft:weathered_cut_copper", "drops", new HashMap())), ++ Map.entry("minecraft:exposed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:weathered_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap())), ++ Map.entry("minecraft:oxidized_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap())), + Map.entry("minecraft:exposed_cut_copper_slab", Map.of("into", "minecraft:cut_copper_slab", "drops", new HashMap())), + Map.entry("minecraft:weathered_cut_copper_slab", Map.of("into", "minecraft:exposed_cut_copper_slab", "drops", new HashMap())), + Map.entry("minecraft:oxidized_cut_copper_slab", Map.of("into", "minecraft:weathered_cut_copper_slab", "drops", new HashMap())), + Map.entry("minecraft:exposed_cut_copper_stairs", Map.of("into", "minecraft:cut_copper_stairs", "drops", new HashMap())), + Map.entry("minecraft:weathered_cut_copper_stairs", Map.of("into", "minecraft:exposed_cut_copper_stairs", "drops", new HashMap())), -+ Map.entry("minecraft:oxidized_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap()))) ++ Map.entry("minecraft:oxidized_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap())), ++ Map.entry("minecraft:exposed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:weathered_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:oxidized_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap())), ++ Map.entry("minecraft:exposed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:weathered_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:oxidized_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap())), ++ Map.entry("minecraft:exposed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:weathered_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:oxidized_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap())), ++ Map.entry("minecraft:exposed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap())), ++ Map.entry("minecraft:weathered_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap())), ++ Map.entry("minecraft:oxidized_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap()))) + ).forEach((blockId, obj) -> { + Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.weatherables`: " + blockId); return; } @@ -23117,11 +23237,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + sculkShriekerCanSummonDefault = getBoolean("blocks.sculk_shrieker.can-summon-default", sculkShriekerCanSummonDefault); + } + -+ public boolean shulkerBoxAllowOversizedStacks = false; -+ private void shulkerBoxSettings() { -+ shulkerBoxAllowOversizedStacks = getBoolean("blocks.shulker_box.allow-oversized-stacks", shulkerBoxAllowOversizedStacks); -+ } -+ + public boolean signAllowColors = false; + private void signSettings() { + signAllowColors = getBoolean("blocks.sign.allow-colors", signAllowColors); @@ -24484,7 +24599,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + public boolean sheepBypassMobGriefing = false; + public boolean sheepTakeDamageFromWater = false; + public boolean sheepAlwaysDropExp = false; -+ public boolean sheepShearJebRandomColor = false; + private void sheepSettings() { + sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); + sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); @@ -24499,7 +24613,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + sheepBypassMobGriefing = getBoolean("mobs.sheep.bypass-mob-griefing", sheepBypassMobGriefing); + sheepTakeDamageFromWater = getBoolean("mobs.sheep.takes-damage-from-water", sheepTakeDamageFromWater); + sheepAlwaysDropExp = getBoolean("mobs.sheep.always-drop-exp", sheepAlwaysDropExp); -+ sheepShearJebRandomColor = getBoolean("mobs.sheep.jeb-shear-random-color", sheepShearJebRandomColor); + } + + public boolean shulkerRidable = false; @@ -24656,7 +24769,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + public boolean snowGolemControllable = true; + public boolean snowGolemLeaveTrailWhenRidden = false; + public double snowGolemMaxHealth = 4.0D; -+ public boolean snowGolemDropsPumpkin = true; + public boolean snowGolemPutPumpkinBack = false; + public int snowGolemSnowBallMin = 20; + public int snowGolemSnowBallMax = 20; @@ -24676,7 +24788,6 @@ index 0000000000000000000000000000000000000000..b9d1117885a8dd15f207e55ce5e402d8 + set("mobs.snow_golem.attributes.max_health", oldValue); + } + snowGolemMaxHealth = getDouble("mobs.snow_golem.attributes.max_health", snowGolemMaxHealth); -+ snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); + snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); + snowGolemSnowBallMin = getInt("mobs.snow_golem.min-shoot-interval-ticks", snowGolemSnowBallMin); + snowGolemSnowBallMax = getInt("mobs.snow_golem.max-shoot-interval-ticks", snowGolemSnowBallMax); @@ -26118,7 +26229,7 @@ index 0000000000000000000000000000000000000000..ba2a37dad43e238e54632975abea8ee6 +} diff --git a/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java new file mode 100644 -index 0000000000000000000000000000000000000000..ce614ae6b1fa0b31c1ee8dacb69134bb20c949f4 +index 0000000000000000000000000000000000000000..92d562fa11f69bb6b841299aef257ea0c674ca1c --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java @@ -0,0 +1,106 @@ @@ -26170,7 +26281,7 @@ index 0000000000000000000000000000000000000000..ce614ae6b1fa0b31c1ee8dacb69134bb + super_tick(); + + Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResult(this.position(), this, this::canHitEntity, mot, level()); ++ HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + + this.preOnHit(hitResult); + @@ -26230,7 +26341,7 @@ index 0000000000000000000000000000000000000000..ce614ae6b1fa0b31c1ee8dacb69134bb +} diff --git a/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java new file mode 100644 -index 0000000000000000000000000000000000000000..ea8b928b6d82689e71bbcc39ab497491072dfba6 +index 0000000000000000000000000000000000000000..d0d951f867390fa12cae2ba2a49212354b10d7b0 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java @@ -0,0 +1,121 @@ @@ -26285,7 +26396,7 @@ index 0000000000000000000000000000000000000000..ea8b928b6d82689e71bbcc39ab497491 + super_tick(); + + Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResult(this.position(), this, this::canHitEntity, mot, level()); ++ HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + + this.preOnHit(hitResult); + @@ -26810,10 +26921,10 @@ index 0000000000000000000000000000000000000000..7f526883495b3222746de3d0442e9e4f +} diff --git a/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java new file mode 100644 -index 0000000000000000000000000000000000000000..c038fb2bbb0f0e78380bc24bbd6348b869669a90 +index 0000000000000000000000000000000000000000..d6cc7e434cb2bacc00e4cad9e1f4be7fcf5d0bee --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java -@@ -0,0 +1,36 @@ +@@ -0,0 +1,38 @@ +package org.purpurmc.purpur.item; + +import net.minecraft.core.BlockPos; @@ -26844,6 +26955,8 @@ index 0000000000000000000000000000000000000000..c038fb2bbb0f0e78380bc24bbd6348b8 + if (tag.contains("Purpur.mob_type")) { + EntityType.byString(tag.getString("Purpur.mob_type")).ifPresent(type -> + ((SpawnerBlockEntity) spawner).getSpawner().setEntityId(type, level, level.random, pos)); ++ } else if (tag.contains("BlockEntityTag")) { ++ spawner.load(tag.getCompound("BlockEntityTag")); + } + } + } @@ -27579,7 +27692,7 @@ index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index c0333ba8e57cd284bb8ab15181da6b39d55872f9..0b03dae85e6008283e68b07fa438daccf0e4f5fa 100644 +index 651063863b451d24ffe39f0a4d8db296e58ff585..9357539c71e3a8408b1f055527ffd192b5f9f1d9 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; @@ -28222,19 +28335,6 @@ z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S LFIp>X81%mY^Bg|U -diff --git a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java -index 654ed436e99dd56f1fe7c1d4f38da34d95ce9349..6453b1d4182a47367e89500ed4180ce75556b47d 100644 ---- a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java -+++ b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java -@@ -36,7 +36,7 @@ public class VanillaMobGoalTest { - } - - List> classes; -- try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft").scan()) { -+ try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft", "org.purpurmc.purpur.entity.ai").scan()) { // Purpur - classes = scanResult.getSubclasses(net.minecraft.world.entity.ai.goal.Goal.class.getName()).loadClasses(); - } - diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java index afeb4271fffb7546209f1e651214065187c88302..81bc3af856b8af019fd13e1da1f7cccd526b7cf0 100644 --- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java