diff --git a/.github/workflows/build-1204.yml b/.github/workflows/build-1206.yml similarity index 79% rename from .github/workflows/build-1204.yml rename to .github/workflows/build-1206.yml index 6cd529c1..6f523c80 100644 --- a/.github/workflows/build-1204.yml +++ b/.github/workflows/build-1206.yml @@ -1,10 +1,10 @@ -name: Build Leaf 1.20.4 +name: Build Leaf 1.20.6 on: push: - branches: [ "ver/1.20.4" ] + branches: [ "ver/1.20.6" ] pull_request: - branches: [ "ver/1.20.4" ] + branches: [ "ver/1.20.6" ] jobs: build: @@ -26,11 +26,11 @@ jobs: - name: Apply patches run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" applyPatches --stacktrace --no-daemon - - name: Create ReobfPaperclipJar - run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" createReobfPaperclipJar --stacktrace --no-daemon + - name: Create MojmapPaperclipJar + run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" createMojmapPaperclipJar --stacktrace --no-daemon - name: Rename Paperclip Jar - run: mv build/libs/leaf-paperclip-1.20.4-R0.1-SNAPSHOT-reobf.jar ./leaf-1.20.4.jar + run: mv build/libs/leaf-paperclip-1.20.6-R0.1-SNAPSHOT-mojmap.jar ./leaf-1.20.6.jar - name: Publish API if: github.event_name != 'pull_request' @@ -45,15 +45,15 @@ jobs: - name: Upload Leaf uses: actions/upload-artifact@main with: - name: Leaf 1.20.4 - path: ./leaf-1.20.4.jar + name: Leaf 1.20.6 + path: ./leaf-1.20.6.jar - name: Release Leaf if: github.event_name != 'pull_request' uses: marvinpinto/action-automatic-releases@master with: - title: "Leaf 1.20.4" - automatic_release_tag: "ver-1.20.4" + title: "Leaf 1.20.6" + automatic_release_tag: "ver-1.20.6" repo_token: "${{ secrets.GITHUB_TOKEN }}" - files: "./leaf-1.20.4.jar" + files: "./leaf-1.20.6.jar" prerelease: false diff --git a/README.md b/README.md index 0c0b23d0..6a844f5c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
[![Github Releases](https://img.shields.io/badge/Download-Releases-blue?&style=for-the-badge&colorA=19201a&colorB=298046)](https://github.com/Winds-Studio/Leaf/releases)โ € -[![Github Actions Build](https://img.shields.io/github/actions/workflow/status/Winds-Studio/Leaf/build-1204.yml?&style=for-the-badge&colorA=19201a&colorB=298046)](https://github.com/Winds-Studio/Leaf/actions)โ € +[![Github Actions Build](https://img.shields.io/github/actions/workflow/status/Winds-Studio/Leaf/build-1206.yml?&style=for-the-badge&colorA=19201a&colorB=298046)](https://github.com/Winds-Studio/Leaf/actions)โ € [![Discord](https://img.shields.io/discord/1145991395388162119?label=discord&style=for-the-badge&colorA=19201a&colorB=298046)](https://discord.gg/gfgAwdSEuM) **Leaf** is a drop-in replacement for [Paper](https://papermc.io/) servers designed to remove some checks, customized and high-performance, built on top of [Gale](https://github.com/GaleMC/Gale) with optimizations and fixes from other forks. @@ -10,8 +10,7 @@ ## ๐Ÿƒ Features - **Fork of [Gale](https://github.com/GaleMC/Gale)** for better performance - - **Async** entity tracker, pathfinding and mob spawning - - **Linear region support** from [LinearPurpur](https://github.com/StupidCraft/LinearPurpur) to save disk space + - **Async** pathfinding, mob spawning and entity tracker - **Various optimizations** blending from [other forks](https://github.com/Winds-Studio/Leaf#-credits) - **Fully compatible** with Bukkit, Spigot and Paper plugins - **Latest dependencies**, keeping all dependencies in the newest version @@ -19,7 +18,6 @@ - **Ability to disable** useless console messages - **Fixes** some Minecraft bugs - **Allows** to connect the backend via a proxy server without enabling the bungeecord mode - - **Configurable** tripwire dupe - **Configurable UseItem distance** for anarchy servers - **Mod Protocols** support - **More customized** relying on features of [Purpur](https://github.com/PurpurMC/Purpur) @@ -36,12 +34,12 @@ ## ๐Ÿ“ฅ Download You can find latest successful build in [GitHub Action](https://github.com/Winds-Studio/Leaf/actions) or [Releases](https://github.com/Winds-Studio/Leaf/releases) -**Please note Java >= 17 is required, Java 21 is recommended.** +**Please note Java >= 21 is required.** ## ๐Ÿ“ฆ Building Building a Paperclip JAR for distribution: ```bash -./gradlew applyPatches && ./gradlew createReobfPaperclipJar +./gradlew applyPatches && ./gradlew createMojmapPaperclipJar ``` ## ๐Ÿงช API (WIP) @@ -51,14 +49,14 @@ Building a Paperclip JAR for distribution: org.dreeam.leaf leaf-api - 1.20.4-R0.1-SNAPSHOT + 1.20.6-R0.1-SNAPSHOT provided ``` ### Gradle ```kotlin dependencies { - compileOnly("org.dreeam.leaf:leaf-api:1.20.4-R0.1-SNAPSHOT") + compileOnly("org.dreeam.leaf:leaf-api:1.20.6-R0.1-SNAPSHOT") } ``` diff --git a/build.gradle.kts b/build.gradle.kts index 52b58897..eb891ade 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,7 @@ plugins { java `maven-publish` - id("com.github.johnrengelman.shadow") version "8.1.1" apply false // paperweight required this original shadow - id("io.github.goooler.shadow") version "8.1.7" apply false - id("io.papermc.paperweight.patcher") version "1.5.16-SNAPSHOT" + id("io.papermc.paperweight.patcher") version "1.6.4-SNAPSHOT" } val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" @@ -16,7 +14,7 @@ repositories { } dependencies { - remapper("net.fabricmc:tiny-remapper:0.10.1:fat") + remapper("net.fabricmc:tiny-remapper:0.10.2:fat") decompiler("org.vineflower:vineflower:1.10.1") paperclip("io.papermc:paperclip:3.0.4-SNAPSHOT") } @@ -27,13 +25,13 @@ subprojects { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(21)) } } tasks.withType { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } tasks.withType { options.encoding = Charsets.UTF_8.name() @@ -52,6 +50,7 @@ subprojects { maven("https://hub.spigotmc.org/nexus/content/groups/public/") maven("https://jitpack.io") maven("https://repo.codemc.io/repository/maven-public/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // TODO - Adventure snapshot } } diff --git a/gradle.properties b/gradle.properties index 2b4ef864..6f275b3f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ group = org.dreeam.leaf -version = 1.20.4-R0.1-SNAPSHOT +version = 1.20.6-R0.1-SNAPSHOT -galeCommit = 05f24b652c77b253b1cffef14b21f4fe971a84fa +galeCommit = 454a795cab19c2690483401c2b461a7bb2bd0cbc org.gradle.caching = true org.gradle.parallel = true diff --git a/patches/api/0001-Leaf-config-files.patch b/patches/api/0001-Leaf-config-files.patch index a46a35e8..309dc019 100644 --- a/patches/api/0001-Leaf-config-files.patch +++ b/patches/api/0001-Leaf-config-files.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaf config files diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index e0615e17765406bab75b5d16f9056d6821c577ee..80499cd30914ca97576532bd86967cbfaabe2577 100644 +index db539f0324f2d7c9a9bcb2738bd8eb4158f8d4b5..defa5be01d2f396a1e46c3ad9aa1d20e7c505424 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2288,6 +2288,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2307,6 +2307,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Paper end diff --git a/patches/api/0002-Pufferfish-Sentry.patch b/patches/api/0002-Pufferfish-Sentry.patch index 3e9e6301..e906ce35 100644 --- a/patches/api/0002-Pufferfish-Sentry.patch +++ b/patches/api/0002-Pufferfish-Sentry.patch @@ -7,7 +7,7 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/build.gradle.kts b/build.gradle.kts -index 810100ac785d49bd332455de23690d37e5fbbb81..4a9deabf03236533aa86860326f0da21650dd38f 100644 +index 05180de5beea923d9f96bbe70fae84fb48320643..a085f6fa2cfb3721752b38096a2c35fcdd114d02 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,6 +51,7 @@ dependencies { @@ -20,7 +20,7 @@ index 810100ac785d49bd332455de23690d37e5fbbb81..4a9deabf03236533aa86860326f0da21 implementation("org.ow2.asm:asm-commons:9.7") diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java new file mode 100644 -index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac6be3306f +index 0000000000000000000000000000000000000000..c7772aac00f6db664f7a5673bc2585fa025e6aad --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java @@ -0,0 +1,165 @@ @@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac + public static void setPluginContext(@Nullable Plugin plugin) { + if (plugin != null) { + ThreadContext.put("pufferfishsentry_pluginname", plugin.getName()); -+ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getDescription().getVersion()); ++ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getPluginMeta().getVersion()); + } + } + @@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac + if (player != null) { + setSenderContext(player); + } -+ } catch (Exception e) { ++ } catch (Exception ignored) { + } // We can't really safely log exceptions. + + ThreadContext.put("pufferfishsentry_eventdata", GSON.toJson(serializeFields(event))); @@ -134,7 +134,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac + } else { + fields.put(fieldName, ""); + } -+ } catch (Exception e) { ++ } catch (Exception ignored) { + } // We can't really safely log exceptions. + } + return fields; @@ -190,10 +190,10 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac + } +} diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index fc2dae69165776d08274e34a69962cc70445f411..899d67fa782fac639fe7fb096e05c551d75bd647 100644 +index 07a9c9e254188c251165ca84c8e961fccda01175..5dc64d8c9aeae612fd31af0673f3530a9e777dfc 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -@@ -584,7 +584,9 @@ public final class SimplePluginManager implements PluginManager { +@@ -596,7 +596,9 @@ public final class SimplePluginManager implements PluginManager { // Paper start private void handlePluginException(String msg, Throwable ex, Plugin plugin) { @@ -203,7 +203,7 @@ index fc2dae69165776d08274e34a69962cc70445f411..899d67fa782fac639fe7fb096e05c551 callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin))); } // Paper end -@@ -654,9 +656,11 @@ public final class SimplePluginManager implements PluginManager { +@@ -666,9 +668,11 @@ public final class SimplePluginManager implements PluginManager { )); } } catch (Throwable ex) { diff --git a/patches/api/0003-Purpur-API-Changes.patch b/patches/api/0003-Purpur-API-Changes.patch index 94aa2206..d4200ddc 100644 --- a/patches/api/0003-Purpur-API-Changes.patch +++ b/patches/api/0003-Purpur-API-Changes.patch @@ -1,12 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Github Actions -Date: Mon, 25 Sep 2023 03:15:07 +0000 +Date: Mon, 29 Apr 2024 09:05:40 +0000 Subject: [PATCH] Purpur API Changes Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b +Commit: a90a4730d672968428e371f024c8317b64eba9af Patches below are removed in this patch: Pufferfish-API-Changes.patch @@ -14,7 +14,6 @@ Fix-pufferfish-issues.patch Build-System-Changes.patch Remove-Timings.patch Add-log-suppression-for-LibraryLoader.patch -Fire-Immunity-API.patch 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 @@ -34,10 +33,10 @@ index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48c @Override diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index d8201747ede92a0123eec012844a7a674e6947f5..e0ecc43fc6a952b4897c530af2e89f2c0558740e 100644 +index 1a4eae45a9352fcc55b8c8a63a126d734604e8c6..a3c696dfb2d6b00ba3f681b74e2cd56c65cf16b2 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2951,4 +2951,127 @@ public final class Bukkit { +@@ -2974,4 +2974,127 @@ public final class Bukkit { public static Server.Spigot spigot() { return server.spigot(); } @@ -256,10 +255,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 ec117c47401ea1a04beb0e5ee9d4d394db7c5c4e..5b058d709751a5b720e209931774e09fcc9c960c 100644 +index 82d009c0bbe4b3026a535e02d6e0ed20c7bd525d..0366400fe6dea7af40badaa3335b49ff5992a516 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -11559,4 +11559,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -11653,4 +11653,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla public boolean isEnabledByFeature(@NotNull World world) { return Bukkit.getDataPackManager().isEnabledByFeature(this, world); } @@ -412,10 +411,10 @@ index 30298a629b39bd43ce14b414fc697b2dfcbea89c..ce00af9121de7a910aaea4e0685a06d4 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172a9d32973 100644 +index defa5be01d2f396a1e46c3ad9aa1d20e7c505424..20b9547f892e6da0337e1f19015fbb2d144cf871 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2288,6 +2288,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2307,6 +2307,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Paper end @@ -434,14 +433,13 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 // Leaf start @NotNull public org.bukkit.configuration.file.YamlConfiguration getLeafConfig() -@@ -2605,4 +2617,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2624,4 +2636,104 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi long getLastTickOversleepTime(); // Gale end - YAPFA - last tick time - API + // Purpur start + /** + * Get the name of this server -+ * + * @return the name of the server + */ + @NotNull @@ -473,7 +471,6 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * + * @param location Location to highlight + * @param duration Duration for highlight to show in milliseconds + */ @@ -483,10 +480,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * + * @param location Location to highlight + * @param duration Duration for highlight to show in milliseconds -+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client ++ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client + */ + void sendBlockHighlight(@NotNull Location location, int duration, int argb); + @@ -494,10 +490,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * + * @param location Location to highlight + * @param duration Duration for highlight to show in milliseconds -+ * @param text Text to show above the highlight ++ * @param text Text to show above the highlight + */ + void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text); + @@ -505,11 +500,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * + * @param location Location to highlight + * @param duration Duration for highlight to show in milliseconds -+ * @param text Text to show above the highlight -+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client ++ * @param text Text to show above the highlight ++ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client + */ + void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb); + @@ -517,10 +511,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * -+ * @param location Location to highlight -+ * @param duration Duration for highlight to show in milliseconds -+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client ++ * @param location Location to highlight ++ * @param duration Duration for highlight to show in milliseconds ++ * @param color Color of the highlight. Will be ignored on some versions of vanilla client + * @param transparency Transparency of the highlight + * @throws IllegalArgumentException If transparency is outside 0-255 range + */ @@ -530,11 +523,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + * Creates debug block highlight on specified block location and show it to all players on the server. + *

+ * Clients may be inconsistent in displaying it. -+ * -+ * @param location Location to highlight -+ * @param duration Duration for highlight to show in milliseconds -+ * @param text Text to show above the highlight -+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client ++ * @param location Location to highlight ++ * @param duration Duration for highlight to show in milliseconds ++ * @param text Text to show above the highlight ++ * @param color Color of the highlight. Will be ignored on some versions of vanilla client + * @param transparency Transparency of the highlight + * @throws IllegalArgumentException If transparency is outside 0-255 range + */ @@ -547,10 +539,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172 + // Purpur end } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index e6f66d70d024cf4f0536a5bf8e51bf7b306335df..07e75978b4fc0e446e8aa46a40be5e371dc1c11b 100644 +index 97f97ea5c6aa513c439f86a9c82821e0f7d9cd1e..83a5b68c785a88594e6e3824ed282844086f7f1a 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -4233,6 +4233,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -4249,6 +4249,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable public DragonBattle getEnderDragonBattle(); @@ -667,7 +659,7 @@ index 739911cda33b373f99df627a3a378b37d7d461aa..51e78c22cd021722b963fe31d1d9175d * Add an entity to the block. * diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java -index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4 100644 +index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e842d13febca67ffa1c89fb2c1324d2609fb81fd 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -143,6 +143,19 @@ public class SimpleCommandMap implements CommandMap { @@ -690,6 +682,15 @@ index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e43d0e0a2c5edfcc82a677b6c4db9314 // Paper start - Plugins do weird things to workaround normal registration if (target.timings == null) { target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target); +@@ -152,7 +165,7 @@ public class SimpleCommandMap implements CommandMap { + try { + try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources + // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) +- target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length)); ++ target.execute(sender, sentCommandLabel, parsedArgs); // Purpur + } // target.timings.stopTiming(); // Spigot // Paper + } catch (CommandException ex) { + server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java index fd5d9881abfd930bb883120f018f76dc78b62b14..d3dadad49df09e85c724c93e8cc88da2c985e9b4 100644 --- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java @@ -786,10 +787,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 23def071492ccd715693d534cc506936e18f0f46..51ae4b559a6ebb5c324ac029c86e5b5a6b894d7e 100644 +index 62e3793903905b94eb1a120345015149abb33713..07b8c0dd049ff783fd2e408be634642479bf8b1e 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1144,4 +1144,42 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent +@@ -1155,4 +1155,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ @NotNull String getScoreboardEntryName(); // Paper end - entity scoreboard name @@ -830,6 +831,19 @@ index 23def071492ccd715693d534cc506936e18f0f46..51ae4b559a6ebb5c324ac029c86e5b5a + * @return True if in daylight + */ + boolean isInDaylight(); ++ ++ /** ++ * Checks if the entity is fire immune ++ * ++ * @return True if fire immune ++ */ ++ boolean isImmuneToFire(); ++ ++ /** ++ * Sets if the entity is fire immune ++ * Set this to null to restore the entity type default ++ */ ++ void setImmuneToFire(@Nullable Boolean fireImmune); + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/IronGolem.java b/src/main/java/org/bukkit/entity/IronGolem.java @@ -925,30 +939,16 @@ index bcc6ba95bd21c7972865838c636a03f50b6c1f1a..c3fcd8dd7dbb1e1a18e17c014c1e6411 + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 65112eae8b92344796850b1e4c89e75443eab2fe..5369d802d37863a1efc0c031520147ceedcadc78 100644 +index b777e530122549455dcce6fac8d4a151c1c0af42..61a046584acf48693489ff551a0dd4c4b16af9ff 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1445,4 +1445,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -1447,4 +1447,27 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setBodyYaw(float bodyYaw); // Paper end - body yaw API + + // Purpur start + /** -+ * Gets the distance (in blocks) this entity can safely fall without taking damage -+ * -+ * @return Safe fall distance -+ */ -+ float getSafeFallDistance(); -+ -+ /** -+ * Set the distance (in blocks) this entity can safely fall without taking damage -+ * -+ * @param safeFallDistance Safe fall distance -+ */ -+ void setSafeFallDistance(float safeFallDistance); -+ -+ /** + * Play item break animation for the item in specified equipment slot + * + * @param slot Equipment slot to play break animation for @@ -996,10 +996,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 db3dfc95ca2997745092cf4632c60705d05a6640..6a9ce422d1def472ef4bbd3cc716426385be0cc4 100644 +index 0b3a1f3285fc0d8954f4204a93d3905df01cd828..2ba39b38a97333f867bcabdf593448ca14255703 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3762,4 +3762,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3806,4 +3806,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end @@ -1193,13 +1193,13 @@ index 14543c2238b45c526dd9aebea2aa5c22f5df54dc..5312daf33405704c74e2c9e109754285 + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/Wolf.java b/src/main/java/org/bukkit/entity/Wolf.java -index 84db38388bf7a58e66d6cd29620b4fe64b0a897e..82ebd99549ce9f9e6427a50cef424e9007735708 100644 +index 4b84c04675775e2a606630b00de8afe51665cebc..ccbaf40a3131f477b4be2264401ad893725c1162 100644 --- a/src/main/java/org/bukkit/entity/Wolf.java +++ b/src/main/java/org/bukkit/entity/Wolf.java -@@ -69,4 +69,20 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar - * @param interested Whether the wolf is interested - */ - public void setInterested(boolean interested); +@@ -112,4 +112,20 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar + return variant; + } + } + + // Purpur start + /** @@ -1249,10 +1249,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 daa1306a7324d946d66ad5a674bbc84371d8d4d6..f3b2d7b6fda051211add2b3215f120fb6911aeed 100644 +index 59b375569a75cb1e1f7c610f96078e102ec0d3ed..a3f74891abbdc51dbbddaeb511f2754e0603c904 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryType.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -165,7 +165,7 @@ public enum InventoryType { +@@ -166,7 +166,7 @@ public enum InventoryType { SMITHING_NEW(4, "Upgrade Gear"), ; @@ -1278,33 +1278,13 @@ index c60be4fd24c7fdf65251dd6169e5e1ac3b588d95..569deccd2f1cf21da9b5906433ac493c + boolean canDoUnsafeEnchants(); + + void setDoUnsafeEnchants(boolean canDoUnsafeEnchants); -+ // Purpur end - } -diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index f680545b6b59bf8d2ad154b0472dda4cba42a162..3709ff939acdcaec124c2875a37c4a07745cdaab 100644 ---- a/src/main/java/org/bukkit/inventory/ItemFactory.java -+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java -@@ -353,4 +353,15 @@ public interface ItemFactory { - */ - @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, boolean allowTreasure, @NotNull java.util.Random random); - // Paper end - enchantWithLevels API -+ -+ // Purpur start -+ /** -+ * Returns the lines of text shown when hovering over an item -+ * -+ * @param itemStack The ItemStack -+ * @param advanced Whether advanced tooltips are shown -+ * @return the list of Components -+ */ -+ @NotNull java.util.List getHoverLines(@NotNull ItemStack itemStack, boolean advanced); + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d62ba03abf 100644 +index 84a7bf0936d35bf42b5ed038d295d5c31740f472..6e9b4cbc81878616b1c48add5db534286d267b05 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -17,6 +17,18 @@ import org.bukkit.inventory.meta.ItemMeta; +@@ -17,6 +17,17 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1318,12 +1298,11 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6 +import org.bukkit.inventory.meta.Repairable; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataHolder; -+import com.destroystokyo.paper.Namespaced; +// Purpur end /** * Represents a stack of items. -@@ -1061,4 +1073,636 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1073,4 +1084,565 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player); } // Paper end - expose itemstack tooltip lines @@ -1808,67 +1787,6 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6 + } + + /** -+ * Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE} -+ * -+ * @return Set of {@link com.destroystokyo.paper.Namespaced} -+ */ -+ @NotNull -+ public java.util.Set getDestroyableKeys() { -+ return getItemMeta().getDestroyableKeys(); -+ } -+ -+ /** -+ * Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE} -+ * -+ * @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced} -+ */ -+ public void setDestroyableKeys(@NotNull Collection canDestroy) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setDestroyableKeys(canDestroy); -+ setItemMeta(itemMeta); -+ } -+ -+ /** -+ * Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} -+ * -+ * @return Set of {@link com.destroystokyo.paper.Namespaced} -+ */ -+ @NotNull -+ public java.util.Set getPlaceableKeys() { -+ return getItemMeta().getPlaceableKeys(); -+ } -+ -+ /** -+ * Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} -+ * -+ * @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced} -+ */ -+ @NotNull -+ public void setPlaceableKeys(@NotNull Collection canPlaceOn) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setPlaceableKeys(canPlaceOn); -+ setItemMeta(itemMeta); -+ } -+ -+ /** -+ * Checks for the existence of any keys that the item can be placed on -+ * -+ * @return true if this item has placeable keys -+ */ -+ public boolean hasPlaceableKeys() { -+ return hasItemMeta() && getItemMeta().hasPlaceableKeys(); -+ } -+ -+ /** -+ * Checks for the existence of any keys that the item can destroy -+ * -+ * @return true if this item has destroyable keys -+ */ -+ public boolean hasDestroyableKeys() { -+ return hasItemMeta() && getItemMeta().hasDestroyableKeys(); -+ } -+ -+ /** + * Repairs this item by 1 durability + */ + public void repair() { @@ -1913,7 +1831,7 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6 + public boolean damage(int amount, boolean ignoreUnbreaking) { + Damageable damageable = (Damageable) getItemMeta(); + if (amount > 0) { -+ int unbreaking = getEnchantLevel(Enchantment.DURABILITY); ++ int unbreaking = getEnchantLevel(Enchantment.UNBREAKING); + int reduce = 0; + for (int i = 0; unbreaking > 0 && i < amount; ++i) { + if (reduceDamage(java.util.concurrent.ThreadLocalRandom.current(), unbreaking)) { @@ -1948,16 +1866,6 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6 + } + return random.nextInt(unbreaking + 1) > 0; + } -+ -+ /** -+ * Returns the lines of text shown when hovering over the item -+ * -+ * @param advanced Whether advanced tooltips are shown -+ * @return the list of Components -+ */ -+ public @NotNull List getHoverLines(boolean advanced) { -+ return Bukkit.getItemFactory().getHoverLines(this, advanced); -+ } + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java @@ -2045,205 +1953,6 @@ index cd3296fea01648592d2af89b3d80135acb6d0958..45797a6fbae1d8edc4211cb30def24ad String lname = name.toLowerCase(java.util.Locale.ENGLISH); permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value)); -diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java -index c8ab330ef171795d08fa201cf8320703c7f1c66b..ea656ed39ebc9875f93f99bea274b0ea4456fcf5 100644 ---- a/src/main/java/org/bukkit/potion/PotionEffect.java -+++ b/src/main/java/org/bukkit/potion/PotionEffect.java -@@ -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"; -+ private static final String KEY = "namespacedKey"; // Purpur - private final int amplifier; - private final int duration; - private final PotionEffectType type; -@@ -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,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,28 @@ 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) { -- 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 -+ * @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 icon the icon status, see {@link PotionEffect#hasIcon()} -+ * @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) { -+ this(type, duration, amplifier, ambient, particles, icon, null, key); -+ } -+ // Purpur end -+ - /** - * Creates a potion effect with no defined color. - * -@@ -126,33 +148,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)), (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 - @NotNull - public PotionEffect withType(@NotNull PotionEffectType type) { -- return new PotionEffect(type, duration, amplifier, ambient, particles, icon); -+ return new PotionEffect(type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key - } - @NotNull - public PotionEffect withDuration(int duration) { -- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); -+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key - } - @NotNull - public PotionEffect withAmplifier(int amplifier) { -- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); -+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key - } - @NotNull - public PotionEffect withAmbient(boolean ambient) { -- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); -+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key - } - @NotNull - public PotionEffect withParticles(boolean particles) { -- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); -+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key - } - @NotNull - public PotionEffect withIcon(boolean icon) { -- 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 +191,13 @@ public class PotionEffect implements ConfigurationSerializable { - } - // Paper end - -+ // Purpur start -+ @NotNull -+ public PotionEffect withKey(@Nullable NamespacedKey key) { -+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); -+ } -+ // Purpur end -+ - @NotNull - private static PotionEffectType getEffectType(@NotNull Map map) { - PotionEffectType effect; -@@ -201,6 +230,17 @@ public class PotionEffect implements ConfigurationSerializable { - return def; - } - -+ // Purpur start -+ @Nullable -+ private static NamespacedKey getKey(@NotNull Map map) { -+ Object key = map.get(KEY); -+ if (key instanceof String stringKey) { -+ return NamespacedKey.fromString(stringKey); -+ } -+ return null; -+ } -+ // Purpur end -+ - @Override - @NotNull - public Map serialize() { -@@ -215,6 +255,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()); -+ } -+ // Purpur end - return builder.build(); - // Paper end - } -@@ -243,7 +288,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 && 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 - } - - /** -@@ -339,6 +384,24 @@ public class PotionEffect implements ConfigurationSerializable { - return icon; - } - -+ -+ // Purpur start -+ /** -+ * @return if the key isn't the default namespacedKey -+ */ -+ public boolean hasKey() { -+ return key != null; -+ } -+ -+ /** -+ * @return the key attached to the potion -+ */ -+ @Nullable -+ public NamespacedKey getKey() { -+ return key; -+ } -+ // Purpur end -+ - @Override - public int hashCode() { - int hash = 1; -@@ -354,6 +417,6 @@ public class PotionEffect implements ConfigurationSerializable { - - @Override - public String toString() { -- 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 index 7763d6101ac61900db1e2310966b99584539fd0e..d5a42707d365ffd72532bbb1a59a1ca7145f9918 100644 --- a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java @@ -2770,10 +2479,10 @@ index 0000000000000000000000000000000000000000..519809eab5d926dc7b0a7bad5d446d0d +} diff --git a/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b23455615a7b +index 0000000000000000000000000000000000000000..8ea97ddceedb7c719e8a50a0dd8f3f0919ca1647 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,53 @@ +package org.purpurmc.purpur.event; + +import org.bukkit.block.Block; @@ -2782,7 +2491,6 @@ index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b234 +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockExplodeEvent; +import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; +import java.util.Collections; + +/** @@ -2793,8 +2501,8 @@ index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b234 + private boolean cancelled; + private final float yield; + -+ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @Nullable BlockState explodedBlockState) { -+ super(what, Collections.emptyList(), yield, explodedBlockState); ++ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @NotNull BlockState explodedBlockState) { ++ super(what, explodedBlockState, Collections.emptyList(), yield); + this.yield = yield; + this.cancelled = false; + } @@ -3695,60 +3403,6 @@ index 0000000000000000000000000000000000000000..eebb5d124456b8209d1b8e8cc4cb772d + return handlers; + } +} -diff --git a/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java b/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c0da73d2ea83a6055e34894ba1c7506fc8667712 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java -@@ -0,0 +1,48 @@ -+package org.purpurmc.purpur.event.packet; -+ -+import org.bukkit.event.Event; -+import org.bukkit.event.HandlerList; -+import org.bukkit.inventory.ItemStack; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+ -+/** -+ * Called when an item is about to be written to a packet. -+ */ -+public class NetworkItemSerializeEvent extends Event { -+ private ItemStack itemStack; -+ -+ public NetworkItemSerializeEvent(@NotNull ItemStack itemStack) { -+ super(!org.bukkit.Bukkit.isPrimaryThread()); -+ this.itemStack = itemStack; -+ } -+ -+ /** -+ * @return The item that is about to be serialized. Not mutable -+ */ -+ @NotNull -+ public ItemStack getItemStack() { -+ return itemStack; -+ } -+ -+ /** -+ * Sets the item that will be serialized. -+ * -+ * @param itemStack The item -+ */ -+ public void setItemStack(@Nullable ItemStack itemStack) { -+ this.itemStack = itemStack; -+ } -+ -+ private static final HandlerList handlers = new HandlerList(); -+ -+ @NotNull -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} diff --git a/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java b/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..c88394336bc9ab0f66a2af24d393f4a176a234d5 diff --git a/patches/api/0004-Remove-Timings.patch b/patches/api/0004-Remove-Timings.patch index 307d14e5..4343639f 100644 --- a/patches/api/0004-Remove-Timings.patch +++ b/patches/api/0004-Remove-Timings.patch @@ -2830,29 +2830,19 @@ index 3e61a926620a67daec3af54b72a1b911eaef2ed4..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index b9a07b2db8a3dcdb72c33c8ceda129921b2c02f1..d2e8e1f000277343801261d2dde4d1e5b91035ea 100644 +index a3ba9249e636d1fb8dad98fab413436009fe04df..0a4d7e3b8eda50ec10a7cdb4110628b51b771ef8 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -40,7 +40,6 @@ public interface UnsafeValues { - net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException; - // Paper end - -- void reportTimings(); // Paper - Material toLegacy(Material material); - - Material fromLegacy(Material material); -@@ -141,11 +140,6 @@ public interface UnsafeValues { - // Paper end +@@ -142,7 +142,8 @@ public interface UnsafeValues { // Paper start -- /** -- * Server name to report to timings v2 -- * @return name -- */ -- String getTimingsServerName(); - /** - * Called once by the version command on first use, then cached. +- * Server name to report to timings v2 ++ * Server name ++ * + * @return name + */ + String getTimingsServerName(); diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java deleted file mode 100644 index f9a00aecca5ec41b460bf41dfe1c69694768cf98..0000000000000000000000000000000000000000 @@ -2881,7 +2871,7 @@ index f9a00aecca5ec41b460bf41dfe1c69694768cf98..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java -index b791358f90fe92bc2264d9a26492245763813af3..dc5860f9735ec4767ef9f6ee013006a3da0c67dd 100644 +index b3a2c274f05156fd603bcc7a68ab41265f2eaf44..7c94976e6bac4a0adbe4bbdb25764040aa5c447d 100644 --- a/src/main/java/org/bukkit/command/Command.java +++ b/src/main/java/org/bukkit/command/Command.java @@ -33,8 +33,6 @@ public abstract class Command { @@ -2917,7 +2907,7 @@ index 9d4f553c04784cca63901a56a7aea62a5cae1d72..0f96873eff87ea267f9c1875b3893f35 return i >= j && i <= k; } diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java -index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce47591477749128b007 100644 +index e842d13febca67ffa1c89fb2c1324d2609fb81fd..3a146a9c2fc99ea8f9f6a8c2c1d053bf68aeb853 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -34,7 +34,6 @@ public class SimpleCommandMap implements CommandMap { @@ -2949,7 +2939,7 @@ index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce4759147774 try { - try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) - target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length)); + target.execute(sender, sentCommandLabel, parsedArgs); // Purpur - } // target.timings.stopTiming(); // Spigot // Paper } catch (CommandException ex) { server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper @@ -2961,7 +2951,7 @@ index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce4759147774 server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper throw new CommandException(msg, ex); diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa58f5a3af 100644 +index 5dc64d8c9aeae612fd31af0673f3530a9e777dfc..b598ad80bbcc256c1440a5ab79321b93ae9f12ed 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -60,7 +60,6 @@ public final class SimplePluginManager implements PluginManager { @@ -2972,7 +2962,7 @@ index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa public SimplePluginManager(@NotNull Server instance, @NotNull SimpleCommandMap commandMap) { server = instance; -@@ -711,12 +710,7 @@ public final class SimplePluginManager implements PluginManager { +@@ -723,12 +722,7 @@ public final class SimplePluginManager implements PluginManager { throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled"); } @@ -2986,7 +2976,7 @@ index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa } @NotNull -@@ -946,17 +940,7 @@ public final class SimplePluginManager implements PluginManager { +@@ -958,17 +952,7 @@ public final class SimplePluginManager implements PluginManager { @Override public boolean useTimings() { diff --git a/patches/api/0005-Bump-Dependencies.patch b/patches/api/0005-Bump-Dependencies.patch index 6c72a9ed..e165bd45 100644 --- a/patches/api/0005-Bump-Dependencies.patch +++ b/patches/api/0005-Bump-Dependencies.patch @@ -5,25 +5,23 @@ Subject: [PATCH] Bump Dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974e6cd660b 100644 +index a085f6fa2cfb3721752b38096a2c35fcdd114d02..b3410e3fcead1deec4c052bf813a243f55b3b0cd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -9,11 +9,11 @@ java { - withJavadocJar() - } - --val annotationsVersion = "24.0.1" -+val annotationsVersion = "24.1.0" // Leaf - Bump Dependencies +@@ -12,8 +12,10 @@ java { + val annotationsVersion = "24.1.0" val bungeeCordChatVersion = "1.20-R0.2" - val adventureVersion = "4.16.0" + val adventureVersion = "4.17.0-SNAPSHOT" -val slf4jVersion = "2.0.9" -val log4jVersion = "2.17.1" -+val slf4jVersion = "2.0.13" // Leaf - Bump Dependencies -+val log4jVersion = "2.23.1" // Leaf - Bump Dependencies ++// Leaf start - Bump Dependencies ++val slf4jVersion = "2.0.13" ++val log4jVersion = "2.23.1" ++// Leaf end - Bump Dependencies val apiAndDocs: Configuration by configurations.creating { attributes { attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) -@@ -28,7 +28,7 @@ configurations.api { +@@ -28,7 +30,7 @@ configurations.api { dependencies { // api dependencies are listed transitively to API consumers @@ -32,7 +30,7 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 api("com.google.code.gson:gson:2.10.1") // Paper start - adventure api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.18") { -@@ -41,7 +41,7 @@ dependencies { +@@ -41,7 +43,7 @@ dependencies { api("com.googlecode.json-simple:json-simple:1.1.1") { isTransitive = false // includes junit } @@ -41,7 +39,7 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion")) apiAndDocs("net.kyori:adventure-api") apiAndDocs("net.kyori:adventure-text-minimessage") -@@ -51,28 +51,30 @@ dependencies { +@@ -51,28 +53,32 @@ dependencies { apiAndDocs("net.kyori:adventure-text-logger-slf4j") api("org.apache.logging.log4j:log4j-api:$log4jVersion") api("org.slf4j:slf4j-api:$slf4jVersion") @@ -55,8 +53,10 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 api("org.apache.maven:maven-resolver-provider:3.9.6") // Paper - make API dependency for Paper Plugins - compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") - compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") ++ // Leaf start - Bump Dependencies + compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.19") + compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.19") ++ // Leaf end - Bump Dependencies val annotations = "org.jetbrains:annotations:$annotationsVersion" // Paper - we don't want Java 5 annotations... compileOnly(annotations) @@ -70,15 +70,15 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 // Paper end - testImplementation("org.apache.commons:commons-lang3:3.12.0") -- testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") +- testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") + // Leaf start - Bump Dependencies + testImplementation("org.apache.commons:commons-lang3:3.14.0") -+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") -+ // Leaf end ++ testImplementation("org.junit.jupiter:junit-jupiter:5.11.0-M1") ++ // Leaf end - Bump Dependencies testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.mockito:mockito-core:5.11.0") testImplementation("org.ow2.asm:asm-tree:9.7") -@@ -143,12 +145,12 @@ tasks.withType { +@@ -143,12 +149,12 @@ tasks.withType { options.use() options.isDocFilesSubDirs = true options.links( @@ -93,9 +93,9 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 "https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1", // Paper end // Paper start -@@ -159,9 +161,9 @@ tasks.withType { - "https://jd.advntr.dev/text-serializer-plain/$adventureVersion/", - "https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/", +@@ -159,9 +165,9 @@ tasks.withType { + //"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/", + //"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/", "https://javadoc.io/doc/org.slf4j/slf4j-api/$slf4jVersion/", - "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/$log4jVersion/", + "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/2.20.0", // Leaf - Bump Dependencies @@ -105,13 +105,15 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974 ) options.tags("apiNote:a:API Note:") -@@ -204,6 +206,9 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks. +@@ -204,6 +210,11 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks. jarToScan.set(tasks.jar.flatMap { it.archiveFile }) classpath.from(configurations.compileClasspath) } ++// Leaf start - Bump Dependencies +repositories { + mavenCentral() +} ++// Leaf end - Bump Dependencies tasks.check { dependsOn(scanJar) } diff --git a/patches/api/0007-KeYi-Player-Skull-API.patch b/patches/api/0007-KeYi-Player-Skull-API.patch index 468c27ee..717de8ce 100644 --- a/patches/api/0007-KeYi-Player-Skull-API.patch +++ b/patches/api/0007-KeYi-Player-Skull-API.patch @@ -7,21 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 6a9ce422d1def472ef4bbd3cc716426385be0cc4..89d124342522743206f8065a32f6e36b954b3b73 100644 +index 2ba39b38a97333f867bcabdf593448ca14255703..fbe4f03bec652e096c46496f1f52080ce43982eb 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -9,6 +9,10 @@ import java.util.Date; - import java.util.Map; - import java.util.UUID; - import org.bukkit.BanEntry; -+// Leaf start - KeYi - Player Skull API -+import java.util.concurrent.CompletableFuture; -+import net.kyori.adventure.text.Component; -+// Leaf start - KeYi - import org.bukkit.DyeColor; - import org.bukkit.Effect; - import org.bukkit.GameMode; -@@ -3881,4 +3885,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3925,4 +3925,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM sendDeathScreen(message); } // Purpur end diff --git a/patches/api/0008-Slice-Smooth-Teleports.patch b/patches/api/0008-Slice-Smooth-Teleports.patch index 0f8d9512..1f2aa941 100644 --- a/patches/api/0008-Slice-Smooth-Teleports.patch +++ b/patches/api/0008-Slice-Smooth-Teleports.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/Cryptite/Slice diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 69ba1660dae4ac69ec4e92f94dd6f95e9f70427d..dbd5e9faaf92d718c20ceaf076f2afd867232116 100644 +index fbe4f03bec652e096c46496f1f52080ce43982eb..55a578e216cbc160d98d5f5675d8e3c52fa8c178 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3588,6 +3588,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3628,6 +3628,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM String getClientBrandName(); // Paper end diff --git a/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch b/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch index 174c7403..f524b260 100644 --- a/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch +++ b/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch @@ -9,32 +9,24 @@ Add JVM flag `-DLeaf.library-download-repo=link` to choose library download repo e.g. `-DLeaf.library-download-repo=https://maven.aliyun.com/repository/public` diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -index 78a6e7a31a81bc82d3e3687661e16c6d8ebc4617..d1052c9e8f64619170548336b25a62c863c5ee2b 100644 +index 72b20fa06b461d89f0eeff7b2fbbbe89bae0027c..1e8720e1bf492e2cf1a1638071514e62ac66391d 100644 --- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -@@ -6,7 +6,6 @@ import java.net.MalformedURLException; - import java.net.URL; - import java.net.URLClassLoader; - import java.util.ArrayList; --import java.util.Arrays; - import java.util.List; - import java.util.logging.Level; - import java.util.logging.Logger; -@@ -46,6 +45,7 @@ public class LibraryLoader +@@ -46,6 +46,7 @@ public class LibraryLoader private final RepositorySystem repository; private final DefaultRepositorySystemSession session; private final List repositories; -+ private final String REPO = System.getProperty("Leaf.library-download-repo") != null ? System.getProperty("Leaf.library-download-repo") : "https://repo.maven.apache.org/maven2"; // Leaf - Configurable maven repos ++ private final String repositoryAddress = System.getProperty("Leaf.library-download-repo") != null ? System.getProperty("Leaf.library-download-repo") : "https://repo.maven.apache.org/maven2"; // Leaf - Configurable maven repos + public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries + public static java.util.function.Function, List> REMAPPER; // Paper - remap libraries - public LibraryLoader(@NotNull Logger logger) - { -@@ -72,7 +72,17 @@ public class LibraryLoader - } ); +@@ -79,7 +80,17 @@ public class LibraryLoader + session.setSystemProperties( System.getProperties() ); session.setReadOnly(); - this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) ); + // Leaf start - Configurable maven repos -+ this.repositories = repository.newResolutionRepositories( session, List.of( new RemoteRepository.Builder( "central", "default", REPO ).build() ) ); ++ this.repositories = repository.newResolutionRepositories( session, List.of( new RemoteRepository.Builder( "central", "default", repositoryAddress ).build() ) ); + /* // Dreeam TODO + this.repositories = repository.newResolutionRepositories(session, List.of( + new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build(), @@ -43,7 +35,7 @@ index 78a6e7a31a81bc82d3e3687661e16c6d8ebc4617..d1052c9e8f64619170548336b25a62c8 + new RemoteRepository.Builder("huaweicloud", "default", "https://repo.huaweicloud.com/repository/maven/").build() + )); + */ -+ // Leaf end ++ // Leaf end - Configurable maven repos } @Nullable diff --git a/patches/generated-api/0001-Purpur-generated-api-Changes.patch b/patches/generated-api/0001-Purpur-generated-api-Changes.patch index 81094d2d..2783be27 100644 --- a/patches/generated-api/0001-Purpur-generated-api-Changes.patch +++ b/patches/generated-api/0001-Purpur-generated-api-Changes.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Purpur generated-api Changes Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b +Commit: a90a4730d672968428e371f024c8317b64eba9af diff --git a/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/com/destroystokyo/paper/entity/ai/VanillaGoal.java -index 069f2668f5229b0368b796e65eef1648fba0a097..9b991201a2f6cc9feccccf7f4e7bcded64117764 100644 +index 43f4deacef349502cbb207aafc4f9cb7a75177c5..6b692c24a62e2172116a6b9c371b1c0e2411c27e 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 { diff --git a/patches/server/0036-Fix-Make-log4j-compatible-with-future-release.patch b/patches/removed/server/0036-Fix-Make-log4j-compatible-with-future-release.patch similarity index 100% rename from patches/server/0036-Fix-Make-log4j-compatible-with-future-release.patch rename to patches/removed/server/0036-Fix-Make-log4j-compatible-with-future-release.patch diff --git a/patches/server/0053-LinearPurpur-Add-Linear-region-format.patch b/patches/removed/server/0053-LinearPurpur-Add-Linear-region-format.patch similarity index 100% rename from patches/server/0053-LinearPurpur-Add-Linear-region-format.patch rename to patches/removed/server/0053-LinearPurpur-Add-Linear-region-format.patch diff --git a/patches/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch b/patches/removed/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch similarity index 100% rename from patches/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch rename to patches/removed/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch diff --git a/patches/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch b/patches/removed/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch similarity index 100% rename from patches/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch rename to patches/removed/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch diff --git a/patches/server/0068-Fix-MC-172047.patch b/patches/removed/server/0068-Fix-MC-172047.patch similarity index 100% rename from patches/server/0068-Fix-MC-172047.patch rename to patches/removed/server/0068-Fix-MC-172047.patch diff --git a/patches/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch b/patches/removed/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch similarity index 100% rename from patches/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch rename to patches/removed/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch diff --git a/patches/server/0001-Rebrand.patch b/patches/server/0001-Rebrand.patch index c8a24a1b..07858171 100644 --- a/patches/server/0001-Rebrand.patch +++ b/patches/server/0001-Rebrand.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Rebrand diff --git a/build.gradle.kts b/build.gradle.kts -index c9784da0a87d61e80a41fb0358614053682e942b..960fe37a4cf0100b552401f835900c6d8b6af523 100644 +index e9b050f744391444714c8803835d78d0415f96ce..344b87ffcf53f21f8e1a25d1e35fa5246d37f99d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -15,7 +15,7 @@ val alsoShade: Configuration by configurations.creating +@@ -14,7 +14,7 @@ val alsoShade: Configuration by configurations.creating dependencies { // Gale start - project setup // Depend on own API @@ -17,7 +17,7 @@ index c9784da0a87d61e80a41fb0358614053682e942b..960fe37a4cf0100b552401f835900c6d // Depend on Paper MojangAPI implementation("io.papermc.paper:paper-mojangapi:${project.version}") { exclude("io.papermc.paper", "paper-api") -@@ -88,7 +88,7 @@ tasks.jar { +@@ -95,7 +95,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -72,11 +72,26 @@ index e45e6b44b2a8f2cdae6e0048a812b92126aa17ca..b5f3f213da8a40d5184098af017c8e26 .variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history")) .completer(new ConsoleCommandCompleter(this.server)) .option(LineReader.Option.COMPLETE_IN_WORD, true); +diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java +index 4f3cc14d48690bb183d09bb7a5ba1e23e8a0c08a..d8ebcd1c94ce0f78e9d16c603a79a492263990fd 100644 +--- a/src/main/java/net/minecraft/CrashReport.java ++++ b/src/main/java/net/minecraft/CrashReport.java +@@ -125,6 +125,10 @@ public class CrashReport { + StringBuilder stringbuilder = new StringBuilder(); + + stringbuilder.append("---- Minecraft Crash Report ----\n"); ++ // Leaf start - Purpur ++ stringbuilder.append("// "); ++ stringbuilder.append("// DO NOT REPORT THIS TO PAPER OR GALE! REPORT TO LEAF INSTEAD!"); ++ // Leaf end - Purpur + stringbuilder.append("// "); + stringbuilder.append(CrashReport.getErrorComment()); + stringbuilder.append("\n\n"); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index fbdc65a01b04abae4c3770666c6a77e0e85be502..9e7119152664e785e23f08e3a702f0bc60d817a0 100644 +index a77d650fd3b58cc883f284e1d2e41459ae0a77cd..ff4603d4749afdd3ff388c4b5d02ae6620140d63 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -940,7 +940,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Wed, 12 Oct 2022 10:42:15 -0400 Subject: [PATCH] Leaf Config -TODO - Dreeam: Add header comment, config hot-reload, world config +TODO - Dreeam: Add header comment, world config Co-authored-by: MrHua269 diff --git a/build.gradle.kts b/build.gradle.kts -index 91a7a0b81bf2b800847b27de890855c312aecfcb..a3e03a735131513324babe930dbf642acbcb5365 100644 +index 344b87ffcf53f21f8e1a25d1e35fa5246d37f99d..34335e3c6aeee7c29ce968170ce4d7b6c9872149 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -21,6 +21,9 @@ dependencies { +@@ -20,6 +20,9 @@ dependencies { exclude("io.papermc.paper", "paper-api") } // Gale end - project setup @@ -22,14 +22,15 @@ index 91a7a0b81bf2b800847b27de890855c312aecfcb..a3e03a735131513324babe930dbf642a implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 465a7787f15c934b2cef1a58e4b18f1ae9b4cae7..0b090797eb873b703730559049937163f2db8ecb 100644 +index 76a1b31a55b1838dc80b796f997edaddbcaa755c..bbeb88843f210abdf1cafed11394380cfcab0e09 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java -@@ -121,6 +121,7 @@ public class Main { +@@ -123,6 +123,8 @@ public class Main { Bootstrap.bootStrap(); Bootstrap.validate(); Util.startTimerHackThread(); + org.dreeam.leaf.config.LeafConfig.loadConfig(); // Leaf ++ org.dreeam.leaf.config.LeafConfig.setupLatch(); // Leaf Path path1 = Paths.get("server.properties"); DedicatedServerSettings dedicatedserversettings = new DedicatedServerSettings(optionset); // CraftBukkit - CLI argument support @@ -91,6 +92,20 @@ index 0000000000000000000000000000000000000000..f69663d0cfebcdb598ac808d06cb0695 + return this.baseKeyName; + } +} +diff --git a/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java b/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f7ab1ff5f298ff1e5e16fe5396d1e9e62a55fdfb +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java +@@ -0,0 +1,8 @@ ++package org.dreeam.leaf.config; ++ ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++ ++@Retention(RetentionPolicy.RUNTIME) ++public @interface HotReloadUnsupported { ++} diff --git a/src/main/java/org/dreeam/leaf/config/IConfigModule.java b/src/main/java/org/dreeam/leaf/config/IConfigModule.java new file mode 100644 index 0000000000000000000000000000000000000000..da1474fa0512e50bedc8dda787bf6a1214f1ce37 @@ -122,13 +137,14 @@ index 0000000000000000000000000000000000000000..da1474fa0512e50bedc8dda787bf6a12 +} diff --git a/src/main/java/org/dreeam/leaf/config/LeafConfig.java b/src/main/java/org/dreeam/leaf/config/LeafConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed490d5671ed +index 0000000000000000000000000000000000000000..b20ad36bb89e5226d94928832fdbcce7e096d6e2 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/config/LeafConfig.java -@@ -0,0 +1,193 @@ +@@ -0,0 +1,220 @@ +package org.dreeam.leaf.config; + +import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.File; @@ -141,11 +157,13 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49 +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.*; ++import java.util.concurrent.CompletableFuture; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; ++import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; + +public class LeafConfig { + public static final Logger LOGGER = LogManager.getLogger(LeafConfig.class.getName()); @@ -153,6 +171,30 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49 + private static final File baseConfigFile = new File(baseConfigFolder, "leaf_global_config.toml"); + private static final Set allInstanced = new HashSet<>(); + private static CommentedFileConfig configFileInstance; ++ public static boolean alreadyInited = false; ++ private static MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin(); ++ ++ public static void setupLatch() { ++ alreadyInited = true; ++ } ++ ++ public static void reload() { ++ dropAllInstanced(); ++ try { ++ loadConfig(); ++ } catch (Exception e) { ++ LOGGER.error(e); ++ } ++ } ++ ++ @Contract(" -> new") ++ public static @NotNull CompletableFuture reloadAsync() { ++ return new CompletableFuture<>(); ++ } ++ ++ public static void dropAllInstanced() { ++ allInstanced.clear(); ++ } + + public static void loadConfig() throws IOException { + baseConfigFolder.mkdirs(); @@ -164,7 +206,7 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49 + configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile); + + configFileInstance.load(); -+ configFileInstance.getComment(""" ++ configFileInstance.setComment("", """ + Leaf Config + Github Repo: https://github.com/Winds-Studio/Leaf + Discord: dreeam___ | QQ: 2682173972"""); // Leaf TODO - need to fix @@ -201,7 +243,7 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49 + for (Field field : fields) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { -+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null; ++ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInited && field.getAnnotation(HotReloadUnsupported.class) != null); + ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class); + + if (skipLoad || configInfo == null) { diff --git a/patches/server/0003-Leaf-Config-legacy-converter.patch b/patches/server/0003-Leaf-Config-legacy-converter.patch index 420f681d..69d5bb25 100644 --- a/patches/server/0003-Leaf-Config-legacy-converter.patch +++ b/patches/server/0003-Leaf-Config-legacy-converter.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaf Config legacy converter diff --git a/build.gradle.kts b/build.gradle.kts -index 722e9b39f03b1f41dcf9cd791324e5b6be6d45e8..6fbaa00e7bf665bab2c54e7b4c3e68a5cf14533d 100644 +index 34335e3c6aeee7c29ce968170ce4d7b6c9872149..663d5bfd7c541a193a1636e6f6f8ae5b656b080b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -24,6 +24,13 @@ dependencies { +@@ -23,6 +23,13 @@ dependencies { implementation("com.electronwill.night-config:toml:3.6.7") // Leaf - Night config @@ -17,27 +17,27 @@ index 722e9b39f03b1f41dcf9cd791324e5b6be6d45e8..6fbaa00e7bf665bab2c54e7b4c3e68a5 + implementation("com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4") { + exclude(group = "org.yaml", module = "snakeyaml") + } -+ // Leaf end ++ // Leaf end - Legacy config + // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") diff --git a/src/main/java/org/dreeam/leaf/config/LeafConfig.java b/src/main/java/org/dreeam/leaf/config/LeafConfig.java -index a2acd60fc5e34c9e2807589d1d7fed490d5671ed..b9351fbb5d003911d2fd554d4f1eb33fd1ada55d 100644 +index b20ad36bb89e5226d94928832fdbcce7e096d6e2..c8da60bfb123079e85dd2f4b1f8925513e018297 100644 --- a/src/main/java/org/dreeam/leaf/config/LeafConfig.java +++ b/src/main/java/org/dreeam/leaf/config/LeafConfig.java -@@ -21,7 +21,9 @@ import org.apache.logging.log4j.Logger; +@@ -24,7 +24,9 @@ import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; public class LeafConfig { public static final Logger LOGGER = LogManager.getLogger(LeafConfig.class.getName()); - private static final File baseConfigFolder = new File("leaf_config"); -+ public static long beginTime; -+ private static final File legacyConfig = new File("leaf.yml"); ++ public static long beginTime; // Leaf legacy config convert timer ++ private static final File legacyConfig = new File("leaf.yml"); // Leaf legacy config + public static final File baseConfigFolder = new File("leaf_config"); private static final File baseConfigFile = new File(baseConfigFolder, "leaf_global_config.toml"); private static final Set allInstanced = new HashSet<>(); private static CommentedFileConfig configFileInstance; -@@ -49,6 +51,7 @@ public class LeafConfig { +@@ -76,6 +78,7 @@ public class LeafConfig { } configFileInstance.save(); @@ -45,7 +45,7 @@ index a2acd60fc5e34c9e2807589d1d7fed490d5671ed..b9351fbb5d003911d2fd554d4f1eb33f } private static void loadAllModules() throws IllegalAccessException { -@@ -190,4 +193,21 @@ public class LeafConfig { +@@ -217,4 +220,21 @@ public class LeafConfig { } } } diff --git a/patches/server/0004-Pufferfish-Utils.patch b/patches/server/0004-Pufferfish-Utils.patch index ee082d52..a25bf0da 100644 --- a/patches/server/0004-Pufferfish-Utils.patch +++ b/patches/server/0004-Pufferfish-Utils.patch @@ -44,14 +44,15 @@ index 46954db7ecd35ac4018fdf476df7c8020d7ce6c8..1ad890a244bdf6df48a8db68cb43450e super(); diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java new file mode 100644 -index 0000000000000000000000000000000000000000..53f2df00c6809618a9ee3d2ea72e85e8052fbcf1 +index 0000000000000000000000000000000000000000..53aab67aea0a28c004c6106aa775443c30457141 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java -@@ -0,0 +1,16 @@ +@@ -0,0 +1,17 @@ +package gg.pufferfish.pufferfish; + +import java.util.logging.Level; +import java.util.logging.Logger; ++ +import org.bukkit.Bukkit; + +public class PufferfishLogger extends Logger { diff --git a/patches/server/0005-Pufferfish-Sentry.patch b/patches/server/0005-Pufferfish-Sentry.patch index d31aae01..2c70260c 100644 --- a/patches/server/0005-Pufferfish-Sentry.patch +++ b/patches/server/0005-Pufferfish-Sentry.patch @@ -8,10 +8,10 @@ Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java new file mode 100644 -index 0000000000000000000000000000000000000000..9ce570ddf314deda7a9980ab607af110a05aee16 +index 0000000000000000000000000000000000000000..7ba5790b4e73827daf14f08069190a8e8052f081 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java -@@ -0,0 +1,137 @@ +@@ -0,0 +1,130 @@ +package gg.pufferfish.pufferfish.sentry; + +import com.google.common.reflect.TypeToken; @@ -109,20 +109,13 @@ index 0000000000000000000000000000000000000000..9ce570ddf314deda7a9980ab607af110 + } + + private SentryLevel getLevel(Level level) { -+ switch (level.getStandardLevel()) { -+ case TRACE: -+ case DEBUG: -+ return SentryLevel.DEBUG; -+ case WARN: -+ return SentryLevel.WARNING; -+ case ERROR: -+ return SentryLevel.ERROR; -+ case FATAL: -+ return SentryLevel.FATAL; -+ case INFO: -+ default: -+ return SentryLevel.INFO; -+ } ++ return switch (level.getStandardLevel()) { ++ case TRACE, DEBUG -> SentryLevel.DEBUG; ++ case WARN -> SentryLevel.WARNING; ++ case ERROR -> SentryLevel.ERROR; ++ case FATAL -> SentryLevel.FATAL; ++ default -> SentryLevel.INFO; ++ }; + } + + private static class SentryFilter extends AbstractFilter { diff --git a/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch b/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch index 87964f63..939f1cc3 100644 --- a/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch +++ b/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch @@ -20,23 +20,23 @@ and, in my opinion, worth the low risk of minor mob-spawning-related inconsistencies. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 46a223d184bdc91058b90692df4002ed1da4516c..90eb43f08fe781aafe2f8ac7921bdf148178761b 100644 +index ff4603d4749afdd3ff388c4b5d02ae6620140d63..fffe9e1c307e83b0dcb6c40bf0820f9f9f5c4528 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -297,6 +297,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 2c8eb9294890955f71382ed3884874cc827bab5e..04406e7fcba1f399648a864d2961a30fb757f9f1 100644 +index c58b52acafdc43f41bcc786de56d3d75eb220678..01ebdd21c29651e53d8f649926564a4815be0a9d 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -350,6 +350,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -365,6 +365,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.info("JMX monitoring enabled"); } @@ -45,10 +45,10 @@ index 2c8eb9294890955f71382ed3884874cc827bab5e..04406e7fcba1f399648a864d2961a30f } } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 1a5f1c825598dbc05f446273632ed8c4a45ef43a..de511a1d43aa78ec79c12d78635175336f77b62c 100644 +index a2c5b824a3126f0c7970550f509db9407c66ee28..c8b898e8482f846641505531e8286d9d113c92f9 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -243,7 +243,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -246,7 +246,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end // Paper start - optimise chunk tick iteration public final it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet needsChangeBroadcasting = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); @@ -58,10 +58,10 @@ index 1a5f1c825598dbc05f446273632ed8c4a45ef43a..de511a1d43aa78ec79c12d7863517533 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) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e012047d3ce16d 100644 +index 94689992b4d159ab996e00ae20afa8fef0e84db2..af4fe64e190e73dcc5f2495d0b533547d8f57f1d 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -76,6 +76,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -74,6 +74,9 @@ public class ServerChunkCache extends ChunkSource { private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; // Paper end @@ -71,7 +71,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204 public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { this.level = world; this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); -@@ -510,6 +513,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -508,6 +511,7 @@ public class ServerChunkCache extends ChunkSource { // Paper start - Optional per player mob spawns int naturalSpawnChunkCount = k; if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled @@ -79,7 +79,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204 // re-set mob counts for (ServerPlayer player : this.level.players) { // Paper start - per player mob spawning backoff -@@ -524,17 +528,21 @@ public class ServerChunkCache extends ChunkSource { +@@ -522,14 +526,18 @@ public class ServerChunkCache extends ChunkSource { } // Paper end - per player mob spawning backoff } @@ -100,12 +100,8 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204 + //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously // Gale start - MultiPaper - skip unnecessary mob spawning computations } else { -- spawnercreature_d = null; -+ lastSpawnState = null; // Leaf - Pufferfish - Optimize mob spawning - } - // Gale end - MultiPaper - skip unnecessary mob spawning computations - -@@ -624,8 +632,8 @@ public class ServerChunkCache extends ChunkSource { + spawnercreature_d = null; +@@ -622,8 +630,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); @@ -116,7 +112,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204 } if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration -@@ -668,6 +676,40 @@ public class ServerChunkCache extends ChunkSource { +@@ -666,6 +674,40 @@ public class ServerChunkCache extends ChunkSource { this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing // Paper - optimise chunk tick iteration } diff --git a/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch index 12b544c5..0eeda541 100644 --- a/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch +++ b/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch @@ -3,6 +3,8 @@ From: Paul Sauve Date: Fri, 15 Jan 2021 19:05:01 -0600 Subject: [PATCH] Pufferfish: Dynamic Activation of Brain +Dreeam TODO: waiting Paper dealing with the newGoalRate + Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish @@ -30,10 +32,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index ab0ac738f3e3d231d8fbc663230892d3a5f07660..a26a756c35c77830a3407ae0dfbf8509141f30fa 100644 +index cf51f108753a19e3ab97a6df3e5cecaa4d39f293..cdcbd708b7ee74002428ca8a148d857912ce14ab 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -880,6 +880,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -886,6 +886,7 @@ public class ServerLevel extends Level implements WorldGenLevel { org.spigotmc.ActivationRange.activateEntities(this); // Spigot this.timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { @@ -42,26 +44,23 @@ index ab0ac738f3e3d231d8fbc663230892d3a5f07660..a26a756c35c77830a3407ae0dfbf8509 if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7e84b05e8e4261dd36db725ae83dc0a1b48613fd..3b7a00ab7ad3c1b9ce8ce323154d67cbbfb724f9 100644 +index 615193fbe7574d4d1d9e24a48655931edc2a35d3..b2396234112460925bc4f308f463d16e92efe679 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -504,6 +504,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - } - // Paper end - optimise entity tracking +@@ -427,6 +427,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private UUID originWorld; + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper - Expand Pose API ++ public boolean activatedPriorityReset = false; // Pufferfish - DAB ++ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) -+ // Pufferfish start -+ public boolean activatedPriorityReset = false; // DAB -+ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // golf score -+ // Pufferfish end -+ - public float getBukkitYaw() { - return this.yRot; - } + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 09e8445a3f8c6b3ebc852a75a9a25b41a51ba659..d86c34111ede6a1454dde5e7223d7caf2ab39ef3 100644 +index a46bf73c608641bf1f00fd55242de71a0f2ee06e..58298a1f85f462abc4f07deffe913abb1bac9f99 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -305,6 +305,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -316,6 +316,7 @@ public class EntityType implements FeatureElement, EntityTypeT private final boolean canSpawnFarFromPlayer; private final int clientTrackingRange; private final int updateInterval; @@ -70,10 +69,10 @@ index 09e8445a3f8c6b3ebc852a75a9a25b41a51ba659..d86c34111ede6a1454dde5e7223d7caf private String descriptionId; @Nullable diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index a676228a7f4d8d4b7e54a641c1df1f1b0d262f10..43beb25bb42f19832da83f6f7f022cb5c85830c1 100644 +index e0e7c35fa9c9395eec5b4504e250ee2d58f98e30..c9240785d65227b33f2b1cce28cb3de9d854ad8b 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -228,10 +228,10 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -242,10 +242,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti @Override public void inactiveTick() { super.inactiveTick(); @@ -86,8 +85,8 @@ index a676228a7f4d8d4b7e54a641c1df1f1b0d262f10..43beb25bb42f19832da83f6f7f022cb5 this.targetSelector.tick(); } } -@@ -906,10 +906,14 @@ public abstract class Mob extends LivingEntity implements Targeting { - int i = this.level().getServer().getTickCount() + this.getId(); +@@ -963,10 +963,14 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti + int i = this.tickCount + this.getId(); if (i % 2 != 0 && this.tickCount > 1) { + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking @@ -119,29 +118,30 @@ index 758f62416ca9c02351348ac0d41deeb4624abc0e..69130969c9a434ec2361e573c9a1ec9f } } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index fc16161d352221be549760dcdd8c62dfba6a6798..011e04a06f4583722d97e4bc847bd8445910692a 100644 +index 8ac1a3b86bf0eee6a27985d6b9dbc98b6fedbb15..95d20cd10ef0b3da32a6168c5d4a9bc4abc63e22 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -50,9 +50,12 @@ public class GoalSelector { +@@ -39,9 +39,13 @@ public class GoalSelector { } // Paper start - public boolean inactiveTick() { + public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start + if (inactive && !org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled) tickRate = 4; // reset to Paper's -+ tickRate = Math.min(tickRate, this.newGoalRate); ++ tickRate = Math.min(tickRate, 3); // Dreeam TODO - Waiting Paper this.curRate++; -- return this.curRate % this.newGoalRate == 0; +- return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct ++ //return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct + return this.curRate % tickRate == 0; + // Pufferfish end } public boolean hasTasks() { for (WrappedGoal task : this.availableGoals) { diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -index 26731a659fe3c40fc20135d473bacf105cc15300..c521ff04be40bfa892021f67acc1b324551fcd5e 100644 +index 29802fa506042c80bd1a03cf88f4ab326dfb94b5..34c1df5bd7655bfbcba3ae872a8eec621ace5835 100644 --- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -@@ -221,8 +221,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS +@@ -215,8 +215,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS return 0.4F; } @@ -153,10 +153,10 @@ index 26731a659fe3c40fc20135d473bacf105cc15300..c521ff04be40bfa892021f67acc1b324 AllayAi.updateActivity(this); super.customServerAiStep(); 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 207d41b91bc02d94c5b40799619f7314ef84e41d..d0c624a6a000c2a41e41d14dd785a7bf9612afe8 100644 +index 8a14e3c2bd2162e36634f532fa86a7fba0548541..d339e9c0b81a50d20048375bd8b4141618fc1d2a 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 -@@ -275,8 +275,10 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { - } +@@ -181,8 +181,10 @@ public class Frog extends Animal implements VariantHolder> { + .ifPresent(this::setVariant); } + private int behaviorTick = 0; // Pufferfish @@ -183,10 +183,10 @@ index dfb1f7db2db231049cebf0283ab879618eddaba6..791791fa03c402998fa99b5da9e9f969 FrogAi.updateActivity(this); super.customServerAiStep(); 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 1ee12f16e7013521a288a3160dcc424c4e385204..257687004b03e17cf3f5c0ea4c4cfeb7f34033e4 100644 +index 53dbe9d296a89d23b19f2551b20b464731ee800e..40dad395aabb04c21ac26fadce823ce8b4f79b3a 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 -@@ -80,8 +80,10 @@ public class Tadpole extends AbstractFish { +@@ -83,8 +83,10 @@ public class Tadpole extends AbstractFish { return SoundEvents.TADPOLE_FLOP; } @@ -198,10 +198,10 @@ index 1ee12f16e7013521a288a3160dcc424c4e385204..257687004b03e17cf3f5c0ea4c4cfeb7 TadpoleAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index c6ff7c756aff281e7de094c05749740370988fe5..d75178611f2c74af45e39c9e37770e2c56773b1d 100644 +index 55d2144af223a2813b784e6e249fe94f610ef079..1bf1e2714f210188202a97219765428f9cf2c956 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -191,8 +191,10 @@ public class Goat extends Animal { +@@ -190,8 +190,10 @@ public class Goat extends Animal { return (Brain) super.getBrain(); // CraftBukkit - decompile error } @@ -213,10 +213,10 @@ index c6ff7c756aff281e7de094c05749740370988fe5..d75178611f2c74af45e39c9e37770e2c GoatAi.updateActivity(this); 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 6b0f5aa9e49c7ff8784ae7a016c4403acf98ca1e..fde1a076d1a490cf7bdea7f89a8714b4661a0d7d 100644 +index 910c3df3e8232db8b7140c51df010f0a9bdcad68..837ae63b1621a4fabba4a44145279d5f95f57f6b 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -155,8 +155,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { +@@ -153,8 +153,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { return (Brain)super.getBrain(); } @@ -228,10 +228,10 @@ index 6b0f5aa9e49c7ff8784ae7a016c4403acf98ca1e..fde1a076d1a490cf7bdea7f89a8714b4 HoglinAi.updateActivity(this); if (this.isConverting()) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index 104f3ed9230f6397bfe306b7fbfb9893b7c8e94d..2eeb23ce4125b2538e92e19bf73f55398d2dbfc0 100644 +index 74ffc0c8ac95590c39e86893bb4f270eb63efd49..5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -300,8 +300,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -294,8 +294,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento return !this.cannotHunt; } @@ -243,10 +243,10 @@ index 104f3ed9230f6397bfe306b7fbfb9893b7c8e94d..2eeb23ce4125b2538e92e19bf73f5539 PiglinAi.updateActivity(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 b73bccfcb1b94936f500926a06a28a6a134bbc33..5cad15c512919ce6b0cae9f45e9011dd66134622 100644 +index f41898080a0cce6e1c2d50c3a7f1a0d67df5605a..7350e339c673c3c59bc36843f03f86ab1ef5e925 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 -@@ -273,10 +273,12 @@ public class Warden extends Monster implements VibrationSystem { +@@ -271,10 +271,12 @@ public class Warden extends Monster implements VibrationSystem { } @@ -260,7 +260,7 @@ index b73bccfcb1b94936f500926a06a28a6a134bbc33..5cad15c512919ce6b0cae9f45e9011dd super.customServerAiStep(); if ((this.tickCount + this.getId()) % 120 == 0) { 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 d88cebe9a348ec99bff05c650d101c80cc38c747..34812d4ab115f31a6ad1cf8cbc345dda4339c075 100644 +index de41f5b57cb4220daf312cc8724cc32d3dd6f7a6..e32c928dc21def1df0f6d334405cff5dc8e999cd 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -145,6 +145,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler diff --git a/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch b/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch index aae6cf6a..198f55d8 100644 --- a/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch +++ b/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch @@ -7,10 +7,10 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 43beb25bb42f19832da83f6f7f022cb5c85830c1..1c729ea3e40b12ddb95294c666f1568bd69ce4c0 100644 +index c9240785d65227b33f2b1cce28cb3de9d854ad8b..ad08008a9d3f50bab1ae05603aab4cf3be8e2d54 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -224,11 +224,13 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -238,11 +238,13 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti return this.lookControl; } diff --git a/patches/server/0009-Pufferfish-Entity-TTL.patch b/patches/server/0009-Pufferfish-Entity-TTL.patch index f62c375e..3645a43a 100644 --- a/patches/server/0009-Pufferfish-Entity-TTL.patch +++ b/patches/server/0009-Pufferfish-Entity-TTL.patch @@ -7,16 +7,16 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1482310673c2c2ac9180ea80a96c24d4094e11c9..f146fb4a599d36e0a9492936312e609cbbfed641 100644 +index b2396234112460925bc4f308f463d16e92efe679..9c20cead889a736aab17ef8ef1f3c932b0dd37f1 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -827,6 +827,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -868,6 +868,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void tick() { + // Pufferfish start - entity TTL + if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) { -+ discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur ++ discard(); + return; + } + // Pufferfish end - entity TTL @@ -24,10 +24,10 @@ index 1482310673c2c2ac9180ea80a96c24d4094e11c9..f146fb4a599d36e0a9492936312e609c } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index d86c34111ede6a1454dde5e7223d7caf2ab39ef3..dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994 100644 +index 58298a1f85f462abc4f07deffe913abb1bac9f99..e6edbe6177b168d85759bd9c414dc87ea8a394fe 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -306,6 +306,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -317,6 +317,7 @@ public class EntityType implements FeatureElement, EntityTypeT private final int clientTrackingRange; private final int updateInterval; public boolean dabEnabled = false; // Pufferfish diff --git a/patches/server/0010-Purpur-Server-Changes.patch b/patches/server/0010-Purpur-Server-Changes.patch index fd62f65e..76c8e771 100644 --- a/patches/server/0010-Purpur-Server-Changes.patch +++ b/patches/server/0010-Purpur-Server-Changes.patch @@ -1,41 +1,41 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Github Actions -Date: Mon, 25 Sep 2023 03:15:20 +0000 +Date: Mon, 29 Apr 2024 09:05:40 +0000 Subject: [PATCH] Purpur Server Changes TODO - Dreeam: Check TODOs in ServerGamePacketListenerImpl & Tadpole +Fix-pufferfish-issues.patch Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b +Commit: a90a4730d672968428e371f024c8317b64eba9af Patches below are removed in this patch: -Metrics change in Purpur-config-files.patch -Brand change in Rebrand.patch -some code in Fix-pufferfish-issues.patch +Metrics changes in Purpur-config-files.patch +Brand changes in Rebrand.patch +Fix-pufferfish-issues.patch Fix-decompile-errors.patch Alternative-Keepalive-Handling.patch Logger-settings-suppressing-pointless-logs.patch +Add-log-suppression-for-LibraryLoader.patch Fix-outdated-server-showing-in-ping-before-server-fu.patch Fix-cow-rotation-when-shearing-mooshroom.patch End-gateway-should-check-if-entity-can-use-portal.patch Skip-events-if-there-s-no-listeners.patch Add-5-second-tps-average-in-tps.patch Arrows-should-not-reset-despawn-counter.patch -Add-toggle-for-sand-duping-fix.patch Halloween-options-and-optimizations.patch MC-238526-Fix-spawner-not-spawning-water-animals-cor.patch Remove-Timings.patch Remove-Mojang-Profiler.patch MC-121706-Fix-mobs-not-looking-up-and-down-when-stra.patch -Fire-Immunity-API.patch diff --git a/build.gradle.kts b/build.gradle.kts -index a52369f6e9588568cb0e8ee45ce59bcb685cc502..0d72b6e0a9d9c12b7d4555aa85dcedde9123c5c1 100644 +index 663d5bfd7c541a193a1636e6f6f8ae5b656b080b..2e0bb52941718f4ae2600e293bbe4126d0889f40 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -66,6 +66,12 @@ dependencies { +@@ -63,6 +63,12 @@ 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") @@ -46,9 +46,9 @@ index a52369f6e9588568cb0e8ee45ce59bcb685cc502..0d72b6e0a9d9c12b7d4555aa85dcedde + // Purpur end + testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test - testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") testImplementation("org.hamcrest:hamcrest:2.2") -@@ -177,7 +183,7 @@ fun TaskContainer.registerRunTask( +@@ -164,7 +170,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -148,8 +148,33 @@ index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8a + return new HighlightErrorConverter(formatters); + } +} +diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +index 03f5ec3c4f8eac9cecfef0f257b90090aece5017..77ee490b58f60cfea946cca4e335882dd324bd47 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java ++++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +@@ -4,6 +4,7 @@ import com.google.common.base.Charsets; + import com.google.common.io.Resources; + import com.google.gson.Gson; + import com.google.gson.JsonArray; ++import com.google.gson.JsonElement; + import com.google.gson.JsonObject; + import com.google.gson.JsonSyntaxException; + import org.galemc.gale.version.AbstractPaperVersionFetcher; +@@ -44,11 +45,7 @@ public class PaperVersionFetcher extends AbstractPaperVersionFetcher { + Charsets.UTF_8 + ).openBufferedStream()) { + JsonObject json = new Gson().fromJson(reader, JsonObject.class); +- JsonArray builds = json.getAsJsonArray("builds"); +- int latest = StreamSupport.stream(builds.spliterator(), false) +- .mapToInt(e -> e.getAsInt()) +- .max() +- .getAsInt(); ++ int latest = json.getAsJsonObject("builds").getAsJsonPrimitive("latest").getAsInt(); // Purpur + return latest - jenkinsBuild; + } catch (JsonSyntaxException ex) { + ex.printStackTrace(); 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 59699c59fdfc611177fdb3136f84ab539b17d9c9..4819c043e193603581598c91d44d407a08ecd5fb 100644 +index c72d6bccf7d72d08d388c65936a89c92261c7860..ee746753515c9cea8dd246f4f56e6781956726c1 100644 --- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -137,6 +137,10 @@ public class MobGoalHelper { @@ -303,10 +328,10 @@ index a8e813ca89b033f061e695288b3383bdcf128531..1ab65af9359d19530bba7f985a604d2a } if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) { diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java -index 708e5bb9bbf0476fcc2c4b92c6830b094703b43e..6141f716b15ad47ac2ac4c9ce92a3897b3ad8807 100644 +index 6f14cb9a73faa1d0ae2939d08809d9f6c2a99e1d..4e98745670032038f7b4f8e1adabc1e00e7f15bf 100644 --- a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java +++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java -@@ -104,6 +104,7 @@ public class PluginInitializerManager { +@@ -112,6 +112,7 @@ public class PluginInitializerManager { @SuppressWarnings("unchecked") java.util.List files = ((java.util.List) optionSet.valuesOf("add-plugin")).stream().map(File::toPath).toList(); io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.PluginFlagProviderSource.INSTANCE, files); @@ -436,7 +461,7 @@ index 0000000000000000000000000000000000000000..cb78dac8e072b5cb3c6e52e17c9ecdf7 + } +} diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index f341813e9713e39bfe142ca34b751de3d8efd25b..546ff84046856ecfe0f2a07d3ba3f886f8df4dca 100644 +index e6c7f62ed379a78645933670299e4fcda8540ed1..7475aaac2673729091eabc741c8ebb561aeec8f1 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java @@ -230,6 +230,19 @@ public class CommandSourceStack implements ExecutionCommandSource 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 8d65cdb013706a932c2c73231108b2810b99e1c7..5b1938fc849db743e65cd7eed0f83ba059b9525e 100644 +index a024c697a65bbab27408da1d6a75e531d9719b47..e4fab82b369f2c2ea0d8c8acd814d06140d551fc 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -@@ -104,7 +104,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { +@@ -105,7 +105,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 ++ 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.LOOTING, CraftItemStack.asNMSCopy(craftItem)))); // Purpur if (event.isCancelled()) { // Paper end - Add drops to shear events continue; diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 63b303a68edd7d39f85c8cb56760b2bf46dcb67a..9e5a7fb07edbdf234bddcab13afd3dde8c43197b 100644 +index 6da6a7befa2dc8988900abee03d24ba894939932..8c9e214f6d77b3118750f63398a5f3881989cb42 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -571,11 +571,20 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -608,11 +608,20 @@ public class Connection extends SimpleChannelInboundHandler> { private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world private static int joinAttemptsThisTick; // Paper - Buffer joins to world private static int currTick; // Paper - Buffer joins to world @@ -657,44 +681,13 @@ index 63b303a68edd7d39f85c8cb56760b2bf46dcb67a..9e5a7fb07edbdf234bddcab13afd3dde Connection.joinAttemptsThisTick = 0; } // Paper end - Buffer joins to world -diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -index b863249ff7e13cf4939c8961601f0564c62fd661..bdcfd80f937c34956911373905d66424bbff8e1d 100644 ---- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java -+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -@@ -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(); - -+ public static boolean hasItemSerializeEvent = false; // Purpur -+ - public FriendlyByteBuf(ByteBuf parent) { - this.source = parent; - } -@@ -640,6 +642,17 @@ public class FriendlyByteBuf extends ByteBuf { - this.writeBoolean(false); - } else { - this.writeBoolean(true); -+ // Purpur start -+ if (hasItemSerializeEvent) { -+ var event = new org.purpurmc.purpur.event.packet.NetworkItemSerializeEvent(stack.asBukkitCopy()); -+ event.callEvent(); -+ ItemStack newStack = ItemStack.fromBukkitCopy(event.getItemStack()); -+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative && !ItemStack.matches(stack, newStack)) { -+ stack.save(newStack.getOrCreateTagElement("Purpur.OriginalItem")); -+ } -+ stack = newStack; -+ } -+ // Purpur end - Item item = stack.getItem(); - - this.writeId(BuiltInRegistries.ITEM, item); 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 +index 76ef195a5074006b009acd9cc1744667c6aecbb9..659577549e132754281df76a7a1bfd884443c56a 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java -@@ -5,7 +5,7 @@ import net.minecraft.network.protocol.Packet; - - public class ClientboundSetTimePacket implements Packet { +@@ -10,7 +10,7 @@ public class ClientboundSetTimePacket implements Packet processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; -@@ -286,12 +287,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur - Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; move down - while (iterator.hasNext()) { - ServerLevel worldserver = (ServerLevel) iterator.next(); - worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent +@@ -1746,6 +1766,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - Add EntityMoveEvent -+ worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur 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.updateLagCompensationTick(); // Paper - lag compensation ++ worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur + /* Drop global time updates + if (this.tickCount % 20 == 0) { diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index b954c85f4aaf58f36fbeee67691a18b03c398767..b7c6717efcefe4efae3fd69ebaa3697bfd3dc9c8 100644 +index e3c6e5cf297d32c62bc6bb9f8682a665e98470a1..2d3f733c70ff63f7d0d272b205496ad1e0811e3d 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -250,6 +250,7 @@ public class PlayerAdvancements { @@ -837,7 +807,7 @@ index b954c85f4aaf58f36fbeee67691a18b03c398767..b7c6717efcefe4efae3fd69ebaa3697b // Paper end } diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index 15bfe2e58d16864af29b04c17181ebf45fa21eba..f2e6b3a2b9502ba1652bd0debd4d8d0c84dc9c41 100644 +index 84f1ba6275f04624f46ccd772924b5e075e7b205..bfb455fb74f0a9645212f90acb54f68d1c7d9772 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -70,7 +70,7 @@ public class EnchantCommand { @@ -853,8 +823,8 @@ index 15bfe2e58d16864af29b04c17181ebf45fa21eba..f2e6b3a2b9502ba1652bd0debd4d8d0c ItemStack itemStack = livingEntity.getMainHandItem(); if (!itemStack.isEmpty()) { if (enchantment2.canEnchant(itemStack) -- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantments(itemStack).keySet(), enchantment2)) { -+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantments(itemStack).keySet(), enchantment2) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment2))) { // Purpur +- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2)) { ++ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment2))) { // Purpur itemStack.enchant(enchantment2, level); i++; } else if (targets.size() == 1) { @@ -882,22 +852,22 @@ index d1da3600dc07107309b20ebe6e7c0c4da0e8de76..244b4719c689f153fa36381a60acc280 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 1b459a8ee8a6bc039e742d65796bc76660a1c765..599172b994d75484f7c7e0ce6d3d3d771c1c44d0 100644 +index 47355158e5e762540a10dc67b23092a0fc53bce3..9f1c8a62bda242781a0966fa2fc01534261423c7 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 { +@@ -92,6 +92,7 @@ public class GiveCommand { boolean flag = entityplayer.getInventory().add(itemstack1); ItemEntity entityitem; + 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); // CraftBukkit - SPIGOT-2942: Add boolean to call event + entityitem = entityplayer.drop(itemstack, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event + if (entityitem != null) { diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173a33c0adf 100644 +index 01ebdd21c29651e53d8f649926564a4815be0a9d..615a9dfe30d51bf0aeaec301e2c5a2c7fd98c5d2 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -98,6 +98,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -109,6 +109,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface return; } // Paper start - Use TerminalConsoleAppender @@ -905,7 +875,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173 new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); /* jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader; -@@ -223,6 +224,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -236,6 +237,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command GaleCommands.registerCommands(this); // Gale - Gale commands - register commands com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics @@ -921,7 +891,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173 com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // Paper - init PaperBrigadierProvider -@@ -279,6 +289,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -292,6 +302,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface if (true) throw new IllegalStateException("Failed to bind to port", ioexception); // Paper - Propagate failed to bind to port error return false; } @@ -952,7 +922,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173 // CraftBukkit start // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up -@@ -351,6 +385,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -366,6 +400,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish @@ -962,10 +932,10 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173 } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index aa46e6e22998c62c89a56fbcabc13fdf58dd7dba..ee22ca05dccba4914d32125586299c1b7433a532 100644 +index 4323ffee716380bd67eb04a4a7bb62bc4ba2f7df..307a7596024528ad194eb01d6468aff1f5fe02cf 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -@@ -57,6 +57,7 @@ public class DedicatedServerProperties extends Settings> trackedDataValues; // CraftBukkit start - private final Set trackedPlayers; -+ public final Set trackedPlayers; // Purpur - package -> public ++ public final Set trackedPlayers; // Purpur - private -> public 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 a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba120824a80ab1 100644 +index cdcbd708b7ee74002428ca8a148d857912ce14ab..bda8c6af98945d3e5fa671b9b3bc016d7b384dc3 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 { +@@ -219,6 +219,8 @@ public class ServerLevel extends Level implements WorldGenLevel { private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; @@ -1136,7 +1106,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 private final RandomSequences randomSequences; public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick -@@ -223,6 +225,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -228,6 +230,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) @@ -1144,7 +1114,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately -@@ -708,7 +711,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -714,7 +717,24 @@ public class ServerLevel extends Level implements WorldGenLevel { this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; @@ -1170,7 +1140,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 this.serverLevelData = iworlddataserver; ChunkGenerator chunkgenerator = worlddimension.generator(); // CraftBukkit start -@@ -770,6 +790,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -776,6 +796,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 @@ -1178,7 +1148,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 } // Paper start -@@ -816,7 +837,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -822,7 +843,7 @@ public class ServerLevel extends Level implements WorldGenLevel { int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); long j; @@ -1187,16 +1157,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 // CraftBukkit start j = this.levelData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime()); -@@ -907,7 +928,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); - MinecraftServer.LOGGER.error(msg, throwable); - getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); -- entity.discard(); -+ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur - // Paper end - } - // Gale end - Airplane - remove lambda from ticking guard - copied from guardEntityTick -@@ -938,6 +959,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -944,6 +965,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)) { @@ -1210,7 +1171,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -946,8 +974,22 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -952,8 +980,22 @@ public class ServerLevel extends Level implements WorldGenLevel { public void setDayTime(long timeOfDay) { this.serverLevelData.setDayTime(timeOfDay); @@ -1233,7 +1194,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { Iterator iterator = this.customSpawners.iterator(); -@@ -990,10 +1032,18 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -996,10 +1038,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 - Configurable spawn chances for skeleton horses if (flag1) { @@ -1254,7 +1215,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 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 -@@ -1113,7 +1163,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1119,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { return holder.is(PoiTypes.LIGHTNING_ROD); }, (blockposition1) -> { return blockposition1.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition1.getX(), blockposition1.getZ()) - 1; @@ -1263,7 +1224,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 return optional.map((blockposition1) -> { return blockposition1.above(1); -@@ -1162,11 +1212,27 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1168,11 +1218,27 @@ public class ServerLevel extends Level implements WorldGenLevel { if (this.canSleepThroughNights()) { if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) { int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); @@ -1292,7 +1253,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); } -@@ -1306,6 +1372,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1312,6 +1378,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @VisibleForTesting public void resetWeatherCycle() { // CraftBukkit start @@ -1300,7 +1261,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents // 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.... -@@ -1313,6 +1380,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1319,6 +1386,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setRainTime(0); } // CraftBukkit end @@ -1308,7 +1269,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents // CraftBukkit start // If we stop due to everyone sleeping we should reset the weather duration to some other random value. -@@ -2820,7 +2888,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2771,7 +2839,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 - Fix merchant inventory not closing on entity removal @@ -1318,10 +1279,10 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208 } // Paper end - Fix merchant inventory not closing on entity removal diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7d0766951 100644 +index f4829e31111bb640901e8143ed3afa4de3e28b7d..ada4956a0b204cb098e90979aff14db32455f481 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -282,6 +282,10 @@ public class ServerPlayer extends Player { +@@ -299,6 +299,10 @@ public class ServerPlayer extends Player { public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -1332,19 +1293,19 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 // 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)); -@@ -569,6 +573,9 @@ public class ServerPlayer extends Player { - } +@@ -609,6 +613,9 @@ public class ServerPlayer extends Player { + }); } -+ if (nbt.contains("Purpur.RamBar")) { this.ramBar = nbt.getBoolean("Purpur.RamBar"); } // Purpur + if (nbt.contains("Purpur.TPSBar")) { this.tpsBar = nbt.getBoolean("Purpur.TPSBar"); } // Purpur + if (nbt.contains("Purpur.CompassBar")) { this.compassBar = nbt.getBoolean("Purpur.CompassBar"); } // Purpur ++ if (nbt.contains("Purpur.RamBar")) { this.ramBar = nbt.getBoolean("Purpur.RamBar"); } // Purpur } @Override -@@ -635,6 +642,9 @@ public class ServerPlayer extends Player { +@@ -685,6 +692,9 @@ public class ServerPlayer extends Player { + }); } - this.getBukkitEntity().setExtraData(nbt); // CraftBukkit + nbt.putBoolean("Purpur.RamBar", this.ramBar); // Purpur + nbt.putBoolean("Purpur.TPSBar", this.tpsBar); // Purpur @@ -1352,9 +1313,9 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 } // CraftBukkit start - World fallback code, either respawn location or global spawn -@@ -763,6 +773,15 @@ public class ServerPlayer extends Player { - this.trackStartFallingPosition(); +@@ -814,6 +824,15 @@ public class ServerPlayer extends Player { this.trackEnteredOrExitedLavaOnVehicle(); + this.updatePlayerAttributes(); this.advancements.flushDirty(this); + + // Purpur start @@ -1367,8 +1328,8 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 + // Purpur end } - public void doTick() { -@@ -1000,6 +1019,7 @@ public class ServerPlayer extends Player { + private void updatePlayerAttributes() { +@@ -1077,6 +1096,7 @@ public class ServerPlayer extends Player { })); PlayerTeam scoreboardteam = this.getTeam(); @@ -1376,7 +1337,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 if (scoreboardteam != null && scoreboardteam.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { if (scoreboardteam.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent); -@@ -1103,6 +1123,16 @@ public class ServerPlayer extends Player { +@@ -1180,6 +1200,16 @@ public class ServerPlayer extends Player { if (this.isInvulnerableTo(source)) { return false; } else { @@ -1393,7 +1354,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL); if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { -@@ -1246,6 +1276,7 @@ public class ServerPlayer extends Player { +@@ -1323,6 +1353,7 @@ public class ServerPlayer extends Player { playerlist.sendPlayerPermissionLevel(this); worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); @@ -1401,7 +1362,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 // CraftBukkit end this.setServerLevel(worldserver); -@@ -1401,7 +1432,7 @@ public class ServerPlayer extends Player { +@@ -1478,7 +1509,7 @@ public class ServerPlayer extends Player { return entitymonster.isPreventingPlayerRest(this); }); @@ -1410,7 +1371,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1441,7 +1472,19 @@ public class ServerPlayer extends Player { +@@ -1518,7 +1549,19 @@ public class ServerPlayer extends Player { }); if (!this.serverLevel().canSleepThroughNights()) { @@ -1431,15 +1392,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 } ((ServerLevel) this.level()).updateSleepingPlayerList(); -@@ -1546,6 +1589,7 @@ public class ServerPlayer extends Player { - - @Override - public void openTextEdit(SignBlockEntity sign, boolean front) { -+ if (level().purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled, front)); // Purpur - this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); - this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); - } -@@ -1880,6 +1924,26 @@ public class ServerPlayer extends Player { +@@ -1974,6 +2017,26 @@ public class ServerPlayer extends Player { this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -1466,7 +1419,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2207,8 +2271,68 @@ public class ServerPlayer extends Player { +@@ -2299,8 +2362,68 @@ public class ServerPlayer extends Player { public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -1535,7 +1488,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 public ServerStatsCounter getStats() { return this.stats; } -@@ -2760,4 +2884,50 @@ public class ServerPlayer extends Player { +@@ -2868,4 +2991,50 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -1587,10 +1540,10 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7 + // 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 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7fca3c856a 100644 +index 5cedce1f432f6b809b25269242a16477682c824f..6d194797d8fe2cd6e5652d596f4bc66ffc3b6375 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 { +@@ -400,6 +400,7 @@ public class ServerPlayerGameMode { } else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction return false; } @@ -1598,24 +1551,24 @@ index 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7f } // CraftBukkit end -@@ -516,6 +517,7 @@ public class ServerPlayerGameMode { +@@ -512,6 +513,7 @@ public class ServerPlayerGameMode { public InteractionHand interactHand; public ItemStack interactItemStack; public InteractionResult useItemOn(ServerPlayer player, Level world, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) { + if (shiftClickMended(stack)) return InteractionResult.SUCCESS; // Purpur BlockPos blockposition = hitResult.getBlockPos(); BlockState iblockdata = world.getBlockState(blockposition); - InteractionResult enuminteractionresult = InteractionResult.PASS; -@@ -577,7 +579,7 @@ public class ServerPlayerGameMode { - boolean flag1 = player.isSecondaryUseActive() && flag; + boolean cancelledBlock = false; +@@ -573,7 +575,7 @@ public class ServerPlayerGameMode { ItemStack itemstack1 = stack.copy(); + InteractionResult enuminteractionresult; - if (!flag1) { + if (!flag1 || (player.level().purpurConfig.composterBulkProcess && iblockdata.is(Blocks.COMPOSTER))) { // Purpur - enuminteractionresult = iblockdata.use(world, player, hand, hitResult); + ItemInteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult); - if (enuminteractionresult.consumesAction()) { -@@ -618,4 +620,18 @@ public class ServerPlayerGameMode { + if (iteminteractionresult.consumesAction()) { +@@ -621,4 +623,18 @@ public class ServerPlayerGameMode { public void setLevel(ServerLevel world) { this.level = world; } @@ -1635,10 +1588,10 @@ index 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7f + // Purpur end } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d4c833223 100644 +index 83196467cf7152ba756f5f6d179ee17c00a4325f..5972362c1c968dbabb799824227c6ae3aef0b61e 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -64,6 +64,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -86,6 +86,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private static final long KEEPALIVE_LIMIT = KEEPALIVE_LIMIT_IN_SECONDS * 1000; // Gale end - Purpur - send multiple keep-alive packets protected static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support @@ -1646,7 +1599,7 @@ index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -157,6 +158,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -189,6 +190,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 } @@ -1661,12 +1614,12 @@ index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d try { String channels = payload.toString(com.google.common.base.Charsets.UTF_8); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c60dbdf45 100644 +index 5d02133cffb226ea7e48f517c1414ee7933b300f..45cf2c58fac237fe169a4be75c9a445a002389dd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -335,6 +335,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } - // Gale end - make max interaction distance configurable +@@ -336,6 +336,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private boolean justTeleported = false; + // CraftBukkit end + // Purpur start + private final com.google.common.cache.LoadingCache kickPermissionCache = com.google.common.cache.CacheBuilder.newBuilder() @@ -1685,7 +1638,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c @Override public void tick() { if (this.ackBlockChangesUpTo > -1) { -@@ -402,6 +416,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -403,6 +417,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 @@ -1698,7 +1651,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } -@@ -649,10 +669,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -662,6 +682,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -1707,11 +1660,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -- - // If the event is cancelled we move the player back to their old location. - if (event.isCancelled()) { - this.teleport(from); -@@ -722,6 +743,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -735,6 +757,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 @@ -1719,12 +1668,12 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c return; } -@@ -1158,10 +1180,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1170,10 +1193,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; + // Purpur start -+ int slot = packet.getSlot(); ++ int slot = packet.slot(); + ItemStack itemstack = Inventory.isHotbarSlot(slot) || slot == Inventory.SLOT_OFFHAND ? this.player.getInventory().getItem(slot) : ItemStack.EMPTY; + // Purpur end for (String testString : pageList) { @@ -1735,7 +1684,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1185,6 +1212,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1197,6 +1225,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()); @@ -1743,74 +1692,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1238,13 +1266,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - itemstack1.setTag(nbttagcompound.copy()); - } - -+ // Purpur start -+ boolean hasPerm = getCraftPlayer().hasPermission("purpur.book.color.edit") || getCraftPlayer().hasPermission("purpur.book.color.sign"); - itemstack1.addTagElement("author", StringTag.valueOf(this.player.getName().getString())); - if (this.player.isTextFilteringEnabled()) { -- itemstack1.addTagElement("title", StringTag.valueOf(title.filteredOrEmpty())); -+ itemstack1.addTagElement("title", StringTag.valueOf(color(title.filteredOrEmpty(), hasPerm))); - } else { -- itemstack1.addTagElement("filtered_title", StringTag.valueOf(title.filteredOrEmpty())); -- itemstack1.addTagElement("title", StringTag.valueOf(title.raw())); -+ itemstack1.addTagElement("filtered_title", StringTag.valueOf(color(title.filteredOrEmpty(), hasPerm))); -+ itemstack1.addTagElement("title", StringTag.valueOf(color(title.raw(), hasPerm))); - } -+ // Purpur end - - this.updateBookPages(pages, (s) -> { - return Component.Serializer.toJson(Component.literal(s)); -@@ -1256,10 +1287,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - private void updateBookPages(List list, UnaryOperator unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit - ListTag nbttaglist = new ListTag(); - -+ // Purpur start -+ boolean hasPerm = getCraftPlayer().hasPermission("purpur.book.color.edit"); - if (this.player.isTextFilteringEnabled()) { -- Stream stream = list.stream().map((filteredtext) -> { // CraftBukkit - decompile error -- return StringTag.valueOf((String) unaryoperator.apply(filteredtext.filteredOrEmpty())); -+ Stream stream = list.stream().map(s -> color(s.filteredOrEmpty(), hasPerm, false)).map((s) -> { // CraftBukkit - decompile error -+ return StringTag.valueOf((String) unaryoperator.apply(s)); - }); -+ // Purpur end - - Objects.requireNonNull(nbttaglist); - stream.forEach(nbttaglist::add); -@@ -1269,11 +1303,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - - for (int j = list.size(); i < j; ++i) { - FilteredText filteredtext = (FilteredText) list.get(i); -- String s = filteredtext.raw(); -+ String s = color(filteredtext.raw(), hasPerm, false); // Purpur - - nbttaglist.add(StringTag.valueOf((String) unaryoperator.apply(s))); - if (filteredtext.isFiltered()) { -- nbttagcompound.putString(String.valueOf(i), (String) unaryoperator.apply(filteredtext.filteredOrEmpty())); -+ nbttagcompound.putString(String.valueOf(i), (String) unaryoperator.apply((String) color(filteredtext.filteredOrEmpty(), hasPerm, false))); // Purpur - } - } - -@@ -1286,6 +1320,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(this.player, slot, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) - } - -+ // Purpur start -+ private String color(String str, boolean hasPerm) { -+ return color(str, hasPerm, true); -+ } -+ -+ private String color(String str, boolean hasPerm, boolean parseHex) { -+ return hasPerm ? org.bukkit.ChatColor.color(str, parseHex) : str; -+ } -+ // Purpur end -+ - @Override - public void handleEntityTagQuery(ServerboundEntityTagQuery packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -@@ -1335,8 +1379,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1315,8 +1344,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1828,16 +1710,16 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c } else { ServerLevel worldserver = this.player.serverLevel(); -@@ -1520,7 +1572,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - if (!event.isAllowed()) { +@@ -1503,7 +1540,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl movedWrongly = true; if (event.getLogWarning()) + // Paper end - ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); + ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), d11); // Purpur - } + } // Paper } -@@ -1587,6 +1639,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1571,6 +1608,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -1846,8 +1728,8 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -@@ -1622,6 +1676,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.player.resetFallDistance(); +@@ -1612,6 +1651,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.player.resetCurrentImpulseContext(); } + // Purpur Start @@ -1860,30 +1742,32 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c 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(); -@@ -1661,6 +1722,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1651,6 +1697,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return false; } // Paper end - optimise out extra getCubes + + // Purpur start + public boolean isScissor(ItemStack stack) { -+ return stack.is(Items.SHEARS) && (stack.getTag() == null || stack.getTag().getInt("CustomModelData") == 0); ++ if (!stack.is(Items.SHEARS)) return false; ++ net.minecraft.world.item.component.CustomModelData customModelData = stack.get(net.minecraft.core.component.DataComponents.CUSTOM_MODEL_DATA); ++ return customModelData == null || customModelData.value() == 0; + } + // Purpur end + 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)); -@@ -1671,7 +1739,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1661,7 +1716,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl do { if (!iterator.hasNext()) { - return false; -+ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur // Leaf TODO - Need check this ++ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur } voxelshape1 = (VoxelShape) iterator.next(); -@@ -2006,6 +2074,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1999,6 +2054,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean cancelled; if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) { @@ -1891,15 +1775,15 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2728,6 +2797,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2783,6 +2839,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = entity.getBoundingBox(); - if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < ServerGamePacketListenerImpl.getMaxInteractionDistanceSquared(this.player.level())) { // Gale - make max interaction distance configurable + if (this.player.canInteractWithEntity(axisalignedbb, 1.0D)) { + if (entity instanceof Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); -@@ -2741,6 +2811,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2796,6 +2853,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); @@ -1907,25 +1791,12 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c + // 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. -@@ -3328,6 +3400,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } - } - } -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative) { -+ var tag = itemstack.getTagElement("Purpur.OriginalItem"); -+ if (tag != null) itemstack = ItemStack.of(tag); -+ } -+ // Purpur end - - boolean flag1 = packet.getSlotNum() >= 1 && packet.getSlotNum() <= 45; - boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty(); + entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it. diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index e072edfb1f51f3e219e6deb10b19b4b2502ea87f..4bd1d7c4328e13ae3e173836ced22125857bcae1 100644 +index a2c9ca5bab0b78fdddcfb110aed9718f9ac99c06..52c5ce7339029d7cc3bb1164131a9f96598760c0 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -285,7 +285,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -330,7 +330,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 { @@ -1935,10 +1806,10 @@ index e072edfb1f51f3e219e6deb10b19b4b2502ea87f..4bd1d7c4328e13ae3e173836ced22125 } } catch (AuthenticationUnavailableException authenticationunavailableexception) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b 100644 +index 0e570a7320eb6c65cb5d43fd7912d17a54b64eb3..743e1487048f70ed577452c27c7919d74d26ab19 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -503,6 +503,7 @@ public abstract class PlayerList { +@@ -502,6 +502,7 @@ public abstract class PlayerList { scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end - Configurable player collision @@ -1946,7 +1817,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f if (GaleGlobalConfiguration.get().logToConsole.playerLoginLocations) { // Gale - JettPack - make logging login location configurable PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); // Gale start - JettPack - make logging login location configurable -@@ -621,6 +622,7 @@ public abstract class PlayerList { +@@ -619,6 +620,7 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) { // Paper end - Fix kick event leave message not being sent @@ -1954,7 +1825,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -776,7 +778,7 @@ public abstract class PlayerList { +@@ -775,7 +777,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; @@ -1963,7 +1834,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -1128,6 +1130,20 @@ public abstract class PlayerList { +@@ -1127,6 +1129,20 @@ public abstract class PlayerList { } // CraftBukkit end @@ -1984,7 +1855,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -1231,6 +1247,7 @@ public abstract class PlayerList { +@@ -1230,6 +1246,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + permissionLevel); } @@ -1992,7 +1863,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f player.connection.send(new ClientboundEntityEventPacket(player, b0)); } -@@ -1239,6 +1256,27 @@ public abstract class PlayerList { +@@ -1238,6 +1255,27 @@ public abstract class PlayerList { player.getBukkitEntity().recalculatePermissions(); // CraftBukkit this.server.getCommands().sendCommands(player); } // Paper - Add sendOpLevel API @@ -2042,17 +1913,32 @@ index 823efad652d8ff9e96b99375b102fef6f017716e..caa8a69bde0c212c36dd990a67836ac2 ++this.sleepingPlayers; } // CraftBukkit start +diff --git a/src/main/java/net/minecraft/util/StringUtil.java b/src/main/java/net/minecraft/util/StringUtil.java +index 0bd191acb9596d3aa21c337230d26f09d26f6888..20211f40aeeade9217ece087688974bdf55afc56 100644 +--- a/src/main/java/net/minecraft/util/StringUtil.java ++++ b/src/main/java/net/minecraft/util/StringUtil.java +@@ -69,6 +69,7 @@ public class StringUtil { + + // Paper start - Username validation + public static boolean isReasonablePlayerName(final String name) { ++ if (true) return org.purpurmc.purpur.PurpurConfig.usernameValidCharactersPattern.matcher(name).matches(); // Purpur + if (name.isEmpty() || name.length() > 16) { + return false; + } diff --git a/src/main/java/net/minecraft/world/damagesource/CombatRules.java b/src/main/java/net/minecraft/world/damagesource/CombatRules.java -index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2a3a08b88 100644 +index ddc880ac0c8378bc1132be5deba746c1484c941c..7a8e4b9a9f2e1e5a9c38ad330c75df1f880d3e8b 100644 --- a/src/main/java/net/minecraft/world/damagesource/CombatRules.java +++ b/src/main/java/net/minecraft/world/damagesource/CombatRules.java -@@ -11,12 +11,12 @@ public class CombatRules { +@@ -12,7 +12,7 @@ public class CombatRules { - public static float getDamageAfterAbsorb(float damage, float armor, float armorToughness) { - float f = 2.0F + armorToughness / 4.0F; + public static float getDamageAfterAbsorb(float damage, DamageSource source, float armor, float armorToughnesss) { + float f = 2.0F + armorToughnesss / 4.0F; - float g = Mth.clamp(armor - damage / f, armor * 0.2F, 20.0F); + float g = Mth.clamp(armor - damage / f, armor * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur - return damage * (1.0F - g / 25.0F); + float h = g / 25.0F; + float i = EnchantmentHelper.calculateArmorBreach(source.getEntity(), h); + float j = 1.0F - i; +@@ -20,7 +20,7 @@ public class CombatRules { } public static float getDamageAfterMagicAbsorb(float damageDealt, float protection) { @@ -2062,19 +1948,19 @@ index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2 } } diff --git a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java -index 7056c8ca7a87748f14142c6af274aae492f29f1c..bf06bb78d060bb54d9aaade3605d42ce837d598b 100644 +index 99a7e9eb75231c15bd8bb24fbb4e296bc9fdedff..4fb025a63628eb60509d90b680922a0220104bcb 100644 --- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java +++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java -@@ -53,7 +53,7 @@ public class CombatTracker { +@@ -54,7 +54,7 @@ public class CombatTracker { private Component getMessageForAssistedFall(Entity attacker, Component attackerDisplayName, String itemDeathTranslationKey, String deathTranslationKey) { ItemStack itemStack = attacker instanceof LivingEntity livingEntity ? livingEntity.getMainHandItem() : ItemStack.EMPTY; -- return !itemStack.isEmpty() && itemStack.hasCustomHoverName() -+ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.hasCustomHoverName()) // Purpur +- return !itemStack.isEmpty() && itemStack.has(DataComponents.CUSTOM_NAME) ++ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.has(DataComponents.CUSTOM_NAME)) // Purpur ? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName()) : Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName); } -@@ -97,6 +97,13 @@ public class CombatTracker { +@@ -98,6 +98,13 @@ public class CombatTracker { Component component = ComponentUtils.wrapInSquareBrackets(Component.translatable(string + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE); return Component.translatable(string + ".message", this.mob.getDisplayName(), component); } else { @@ -2089,10 +1975,10 @@ index 7056c8ca7a87748f14142c6af274aae492f29f1c..bf06bb78d060bb54d9aaade3605d42ce } } diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c0190658fc7881b 100644 +index 359a2f0492a9b938a4f015c546e100e0092ae1d4..25e614be19b2b29b36af136b823f27f85e1650fa 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -@@ -27,6 +27,8 @@ public class DamageSource { +@@ -29,6 +29,8 @@ public class DamageSource { private boolean withSweep = false; private boolean melting = false; private boolean poison = false; @@ -2101,7 +1987,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065 @Nullable private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API -@@ -57,6 +59,26 @@ public class DamageSource { +@@ -59,6 +61,26 @@ public class DamageSource { return this.poison; } @@ -2128,7 +2014,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065 // Paper start - fix DamageSource API public @Nullable Entity getCustomEventDamager() { return (this.customEventDamager != null) ? this.customEventDamager : this.directEntity; -@@ -100,6 +122,8 @@ public class DamageSource { +@@ -101,6 +123,8 @@ public class DamageSource { damageSource.withSweep = this.isSweep(); damageSource.poison = this.isPoison(); damageSource.melting = this.isMelting(); @@ -2137,12 +2023,12 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065 return damageSource; } // CraftBukkit end -@@ -172,10 +196,19 @@ public class DamageSource { +@@ -173,10 +197,19 @@ public class DamageSource { ItemStack itemstack1 = itemstack; -- return !itemstack1.isEmpty() && itemstack1.hasCustomHoverName() ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent); -+ return !itemstack1.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemstack1.hasCustomHoverName()) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent); +- return !itemstack1.isEmpty() && itemstack1.has(DataComponents.CUSTOM_NAME) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent); ++ return !itemstack1.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemstack1.has(DataComponents.CUSTOM_NAME)) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent); } } @@ -2159,7 +2045,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065 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 a47473c9875c70c52b9a61e0156e55961f34c694..b88fed81a7df6c81521f74425bd81443b4841137 100644 +index a1c53f04c2dd505e6af72e512e111d7994786035..5ffe772e29dfd422b664e8123e7f5cf396158674 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java @@ -44,11 +44,15 @@ public class DamageSources { @@ -2178,206 +2064,68 @@ index a47473c9875c70c52b9a61e0156e55961f34c694..b88fed81a7df6c81521f74425bd81443 // CraftBukkit end this.inFire = this.source(DamageTypes.IN_FIRE); this.lightningBolt = this.source(DamageTypes.LIGHTNING_BOLT); -@@ -277,4 +281,13 @@ public class DamageSources { - public DamageSource genericKill() { - return this.genericKill; +@@ -97,6 +101,15 @@ public class DamageSources { } + // CraftBukkit end + + // Purpur start + public DamageSource scissors() { + return this.scissors; + } -+ + public DamageSource stonecutter() { + return this.stonecutter; + } + // Purpur end - } ++ + public DamageSource inFire() { + return this.inFire; + } diff --git a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java -index 3aad6bd0a1fb7bb3f9b7dab2c10c875864900750..31bd845130e363dd11c225dfd1e9dd896aea8aac 100644 +index a476b56ed98d0a1afc6a396ce29424df78f24ada..5119ff3414fbd9a1ae0a8db0fd15bd3c57c8e148 100644 --- a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java -@@ -15,7 +15,7 @@ class HungerMobEffect extends MobEffect { - if (entity instanceof Player) { - Player entityhuman = (Player) entity; - +@@ -12,7 +12,7 @@ class HungerMobEffect extends MobEffect { + @Override + public boolean applyEffectTick(LivingEntity entity, int amplifier) { + if (entity instanceof Player entityhuman) { - entityhuman.causeFoodExhaustion(0.005F * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent + entityhuman.causeFoodExhaustion(entity.level().purpurConfig.humanHungerExhaustionAmount * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur } - } -diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java -index 5c9a0c91ae53b575d325a294c702668d30252fcf..0758ddbd37a519d03ae134731368f4a69c2f8aab 100644 ---- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java -+++ b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java -@@ -36,6 +36,7 @@ public class MobEffectInstance implements Comparable { - private boolean showIcon; - @Nullable - public MobEffectInstance hiddenEffect; -+ private org.bukkit.NamespacedKey key; // Purpur - add key - private final Optional factorData; - - public MobEffectInstance(MobEffect type) { -@@ -54,8 +55,14 @@ 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 showParticles, boolean showIcon, @Nullable org.bukkit.NamespacedKey key) { -+ this(type, duration, amplifier, ambient, showParticles, showIcon, null, key, type.createFactorData()); -+ } -+ // Purpur end -+ - public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon) { -- this(type, duration, amplifier, ambient, showParticles, showIcon, null, type.createFactorData()); -+ this(type, duration, amplifier, ambient, showParticles, showIcon, null, null, type.createFactorData()); // Purpur - } - - public MobEffectInstance( -@@ -66,6 +73,7 @@ public class MobEffectInstance implements Comparable { - boolean showParticles, - boolean showIcon, - @Nullable MobEffectInstance hiddenEffect, -+ @Nullable org.bukkit.NamespacedKey key, // Purpur - Optional factorCalculationData - ) { - this.effect = type; -@@ -74,6 +82,7 @@ public class MobEffectInstance implements Comparable { - this.ambient = ambient; - this.visible = showParticles; - this.showIcon = showIcon; -+ this.key = key; // Purpur - add key - this.hiddenEffect = hiddenEffect; - this.factorData = factorCalculationData; - } -@@ -94,6 +103,7 @@ public class MobEffectInstance implements Comparable { - this.ambient = that.ambient; - this.visible = that.visible; - this.showIcon = that.showIcon; -+ this.key = that.key; // Purpur - add key - } - - public boolean update(MobEffectInstance that) { -@@ -138,6 +148,13 @@ public class MobEffectInstance implements Comparable { - bl = true; - } - -+ // Purpur start -+ if (that.key != this.key) { -+ this.key = that.key; -+ bl = true; -+ } -+ // Purpur end -+ - return bl; - } - -@@ -181,6 +198,17 @@ public class MobEffectInstance implements Comparable { - return this.showIcon; - } - -+ // Purpur start -+ public boolean hasKey() { -+ return this.key != null; -+ } -+ -+ @Nullable -+ public org.bukkit.NamespacedKey getKey() { -+ return this.key; -+ } -+ // Purpur end -+ - public boolean tick(LivingEntity entity, Runnable overwriteCallback) { - if (this.hasRemainingDuration()) { - int i = this.isInfiniteDuration() ? entity.tickCount : this.duration; -@@ -237,6 +265,12 @@ public class MobEffectInstance implements Comparable { - string = string + ", Show Icon: false"; - } - -+ // Purpur start -+ if (this.hasKey()) { -+ string = string + ", Key: " + this.key; -+ } -+ // Purpur end -+ - return string; - } - -@@ -251,6 +285,7 @@ public class MobEffectInstance implements Comparable { - && this.duration == mobEffectInstance.duration - && this.amplifier == mobEffectInstance.amplifier - && this.ambient == mobEffectInstance.ambient -+ && this.key == mobEffectInstance.key // Purpur - add key - && this.effect.equals(mobEffectInstance.effect); - } - -@@ -275,6 +310,11 @@ public class MobEffectInstance implements Comparable { - nbt.putBoolean("ambient", this.isAmbient()); - nbt.putBoolean("show_particles", this.isVisible()); - nbt.putBoolean("show_icon", this.showIcon()); -+ // Purpur start -+ if (this.key != null) { -+ nbt.putString("key", this.key.toString()); -+ } -+ // Purpur end - if (this.hiddenEffect != null) { - CompoundTag compoundTag = new CompoundTag(); - this.hiddenEffect.save(compoundTag); -@@ -311,6 +351,13 @@ public class MobEffectInstance implements Comparable { - bl3 = nbt.getBoolean("show_icon"); - } - -+ // Purpur start -+ org.bukkit.NamespacedKey key = null; -+ if (nbt.contains("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")); -@@ -325,7 +372,7 @@ public class MobEffectInstance implements Comparable { - optional = Optional.empty(); - } - -- return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, optional); -+ return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, key, optional); // Purpur - add key - } - - @Override + return true; diff --git a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java -index 196204a8661c7750408997e052ec706f44161fc6..393cd9fac5b2fd39e4248d0abd4930e6b2ff73a4 100644 +index 3e7a703632251e0a5234259e3702b58b332e5ef0..f2cc43fbccb5d2ba012b350268065c2cfe014faf 100644 --- a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java -@@ -11,8 +11,8 @@ class PoisonMobEffect extends MobEffect { +@@ -10,8 +10,8 @@ class PoisonMobEffect extends MobEffect { + @Override - public void applyEffectTick(LivingEntity entity, int amplifier) { - super.applyEffectTick(entity, amplifier); + public boolean applyEffectTick(LivingEntity entity, int amplifier) { - if (entity.getHealth() > 1.0F) { - entity.hurt(entity.damageSources().poison(), 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON + if (entity.getHealth() > entity.level().purpurConfig.entityMinimalHealthPoison) { // Purpur + entity.hurt(entity.damageSources().poison(), entity.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON // Purpur } - } + return true; diff --git a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java -index 551b20f86347aeca4824b7a424ad7de7c0ff072e..06bb4ad98aa9ca38b8d423681b1ad4b821f5e47d 100644 +index 4dba3e813e054951cbfbe0b323c1f5d973469cc0..426f61d55b9692cf085368df4e4df6f6997aa420 100644 --- a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java -@@ -12,7 +12,7 @@ class RegenerationMobEffect extends MobEffect { - public void applyEffectTick(LivingEntity entity, int amplifier) { - super.applyEffectTick(entity, amplifier); +@@ -11,7 +11,7 @@ class RegenerationMobEffect extends MobEffect { + @Override + public boolean applyEffectTick(LivingEntity entity, int amplifier) { if (entity.getHealth() < entity.getMaxHealth()) { - entity.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit + entity.heal(entity.level().purpurConfig.entityHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur } - } + return true; diff --git a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java -index b994ae09621934df2cdd6a83a7d8ecb44649fb16..c2b812c992db1ac9cd391da902c8d819a6ec2e6d 100644 +index 7b415dca88f50dc472fe4be96e5ef0996f117913..2bb872f29350d15db46b32c686aef78fc1b6fa29 100644 --- a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java -@@ -23,7 +23,7 @@ class SaturationMobEffect extends InstantenousMobEffect { +@@ -20,7 +20,7 @@ class SaturationMobEffect extends InstantenousMobEffect { int oldFoodLevel = entityhuman.getFoodData().foodLevel; org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, amplifier + 1 + oldFoodLevel); if (!event.isCancelled()) { @@ -2387,41 +2135,40 @@ index b994ae09621934df2cdd6a83a7d8ecb44649fb16..c2b812c992db1ac9cd391da902c8d819 ((CraftPlayer) entityhuman.getBukkitEntity()).sendHealthUpdate(); diff --git a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java -index cc45fd864185a7842c465e26304b36f7c744bb93..434390a6b88eac7bd41ad6b05d223c78571885fb 100644 +index f43bf280999ff3860cc702def50cc62b131eb1bd..66d9e99a351f5fc6cf58be3bee4397d92c932d64 100644 --- a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java -@@ -10,7 +10,7 @@ class WitherMobEffect extends MobEffect { +@@ -9,7 +9,7 @@ class WitherMobEffect extends MobEffect { + @Override - public void applyEffectTick(LivingEntity entity, int amplifier) { - super.applyEffectTick(entity, amplifier); + public boolean applyEffectTick(LivingEntity entity, int amplifier) { - entity.hurt(entity.damageSources().wither(), 1.0F); + entity.hurt(entity.damageSources().wither(), entity.level().purpurConfig.entityWitherDegenerationAmount); // Purpur + return true; } - @Override diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e03bcde31 100644 +index 9c20cead889a736aab17ef8ef1f3c932b0dd37f1..88ef23e08df880d90fbf879f901c8c7afab90526 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -160,7 +160,7 @@ import org.bukkit.plugin.PluginManager; +@@ -163,7 +163,7 @@ import org.bukkit.plugin.PluginManager; // CraftBukkit end - public abstract class Entity implements Nameable, EntityAccess, CommandSource, ScoreHolder { + public abstract class Entity implements SyncedDataHolder, 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 - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation -@@ -338,7 +338,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -341,6 +341,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public double xOld; public double yOld; public double zOld; -- private float maxUpStep; -+ public float maxUpStep; // Purpur - private -> public ++ public float maxUpStep; // Purpur public boolean noPhysics; public final RandomSource random; public int tickCount; -@@ -380,7 +380,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -382,7 +383,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private final Set tags; private final double[] pistonDeltas; private long pistonDeltasGameTime; @@ -2430,7 +2177,15 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; -@@ -562,6 +562,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -429,6 +430,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public boolean fixedPose = false; // Paper - Expand Pose API + public boolean activatedPriorityReset = false; // Pufferfish - DAB + public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) ++ public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); +@@ -561,6 +563,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } @@ -2456,7 +2211,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e public final boolean hardCollides() { return this.hardCollides; } -@@ -582,7 +601,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -581,7 +602,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -2465,7 +2220,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -920,10 +939,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -961,10 +982,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void checkBelowWorld() { // Paper start - Configurable nether ceiling damage @@ -2478,7 +2233,16 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e this.onBelowWorld(); } -@@ -1896,7 +1916,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -1879,7 +1901,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public boolean fireImmune() { +- return this.getType().fireImmune(); ++ return this.immuneToFire != null ? immuneToFire : this.getType().fireImmune(); // Purpur - add fire immune API + } + + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { +@@ -1952,7 +1974,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.isInWater() || flag; } @@ -2486,8 +2250,32 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e + public void updateInWaterStateAndDoWaterCurrentPushing() { // Purpur - package-private -> public Entity entity = this.getVehicle(); - if (entity instanceof Boat) { -@@ -3050,6 +3070,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + if (entity instanceof Boat entityboat) { +@@ -2584,6 +2606,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + nbttagcompound.putBoolean("Paper.FreezeLock", true); + } + // Paper end ++ // Purpur start ++ if (immuneToFire != null) { ++ nbttagcompound.putBoolean("Purpur.FireImmune", immuneToFire); ++ } ++ // Purpur end + return nbttagcompound; + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); +@@ -2731,6 +2758,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + 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"); +@@ -3109,6 +3141,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.passengers = ImmutableList.copyOf(list); } @@ -2501,7 +2289,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3089,6 +3116,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -3148,6 +3187,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // CraftBukkit end @@ -2516,7 +2304,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -3168,12 +3203,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -3226,12 +3273,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Vec3.directionFromRotation(this.getRotationVector()); } @@ -2533,7 +2321,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e } this.isInsidePortal = true; -@@ -3412,7 +3450,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -3456,7 +3506,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public int getMaxAirSupply() { @@ -2542,7 +2330,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e } public int getAirSupply() { -@@ -3877,7 +3915,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -3923,7 +3973,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean canChangeDimensions() { @@ -2551,7 +2339,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e } public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { -@@ -4180,6 +4218,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -4224,6 +4274,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return SlotAccess.NULL; } @@ -2572,7 +2360,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e @Override public void sendSystemMessage(Component message) {} -@@ -4457,6 +4509,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -4511,6 +4575,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.yRotO = this.getYRot(); } @@ -2585,11 +2373,19 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { if (false && this.touchingUnloadedChunk()) { // Gale - Airplane - reduce entity fluid lookups if no fluids - cost of a lookup here is the same cost as below, so skip return false; -@@ -5035,4 +5093,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -4919,7 +4989,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public float maxUpStep() { +- return 0.0F; ++ return maxUpStep; + } + + public void onExplosionHit(@Nullable Entity entity) {} +@@ -5091,4 +5161,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end - Expose entity id counter -+ + // Purpur start + @Nullable + private Player rider = null; @@ -2644,19 +2440,20 @@ index d8cc5614502db7025349e085381b6b32ad32296a..f1b9e83206cc67e6ef29ebe088351b0a private EntitySelector() {} // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42e520f6ae 100644 +index e6edbe6177b168d85759bd9c414dc87ea8a394fe..32a1b5a1d01fd4dc603a76fde259f3a0d4749fad 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -313,13 +313,24 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -324,7 +324,8 @@ public class EntityType implements FeatureElement, EntityTypeT private Component description; @Nullable - private ResourceLocation lootTable; + private ResourceKey lootTable; - private final EntityDimensions dimensions; + private EntityDimensions dimensions; // Purpur - remove final + public void setDimensions(EntityDimensions dimensions) { this.dimensions = dimensions; } // Purpur + private final float spawnDimensionsScale; private final FeatureFlagSet requiredFeatures; - private static EntityType register(String id, EntityType.Builder type) { // CraftBukkit - decompile error +@@ -332,6 +333,16 @@ public class EntityType implements FeatureElement, EntityTypeT return (EntityType) Registry.register(BuiltInRegistries.ENTITY_TYPE, id, (EntityType) type.build(id)); // CraftBukkit - decompile error } @@ -2673,7 +2470,7 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42 public static ResourceLocation getKey(EntityType type) { return BuiltInRegistries.ENTITY_TYPE.getKey(type); } -@@ -531,6 +542,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -539,6 +550,16 @@ public class EntityType implements FeatureElement, EntityTypeT return this.category; } @@ -2690,7 +2487,7 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42 public String getDescriptionId() { if (this.descriptionId == null) { this.descriptionId = Util.makeDescriptionId("entity", BuiltInRegistries.ENTITY_TYPE.getKey(this)); -@@ -598,6 +619,12 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -606,6 +627,12 @@ public class EntityType implements FeatureElement, EntityTypeT entity.load(nbt); }, () -> { EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); @@ -2704,10 +2501,10 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42 } diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31330198c4 100644 +index a207a31d80a302dbdfe80f8727222542d3a78da2..f5debc8ddc496cd3e2d8b253511ee5cc9a723b38 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -314,7 +314,7 @@ public class ExperienceOrb extends Entity { +@@ -320,7 +320,7 @@ public class ExperienceOrb extends Entity { public void playerTouch(Player player) { if (!this.level().isClientSide) { if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent @@ -2716,7 +2513,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31 player.take(this, 1); int i = this.repairPlayerItems(player, this.value); -@@ -332,7 +332,7 @@ public class ExperienceOrb extends Entity { +@@ -338,7 +338,7 @@ public class ExperienceOrb extends Entity { } private int repairPlayerItems(Player player, int amount) { @@ -2725,7 +2522,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31 if (entry != null) { ItemStack itemstack = (ItemStack) entry.getValue(); -@@ -360,13 +360,15 @@ public class ExperienceOrb extends Entity { +@@ -366,13 +366,15 @@ public class ExperienceOrb extends Entity { } } @@ -2744,7 +2541,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31 public int getValue() { return this.value; diff --git a/src/main/java/net/minecraft/world/entity/GlowSquid.java b/src/main/java/net/minecraft/world/entity/GlowSquid.java -index 5de938f4a7f16fd3caff783564cbb7e6b2924f9a..09181e9a0d4ceac30d20f4ff488a85b0ab5b1d04 100644 +index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..3e2ea26c23e88c395856b65001f2895db6a52bd4 100644 --- a/src/main/java/net/minecraft/world/entity/GlowSquid.java +++ b/src/main/java/net/minecraft/world/entity/GlowSquid.java @@ -23,6 +23,39 @@ public class GlowSquid extends Squid { @@ -2788,10 +2585,10 @@ index 5de938f4a7f16fd3caff783564cbb7e6b2924f9a..09181e9a0d4ceac30d20f4ff488a85b0 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 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f8797fdddf76 100644 +index d688c41ccfec36ab1715f4ae70fbd1adde3525a8..8fdcb4d25f7398aad76f907be60c146413667353 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 { +@@ -228,9 +228,9 @@ public abstract class LivingEntity extends Entity implements Attackable { protected int deathScore; public float lastHurt; public boolean jumping; @@ -2804,15 +2601,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 protected int lerpSteps; protected double lerpX; protected double lerpY; -@@ -253,6 +253,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 - Restore vanilla drops behavior - public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; -@@ -262,6 +263,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -273,6 +273,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 - Friction API @@ -2820,17 +2609,17 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 @Override public float getBukkitYaw() { -@@ -286,7 +288,8 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.effectsDirty = true; +@@ -299,7 +300,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.useItem = ItemStack.EMPTY; this.lastClimbablePos = Optional.empty(); + this.appliedScale = 1.0F; - this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type)); + this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type), this); // Purpur + this.initAttributes(); // Purpur 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 { +@@ -314,6 +316,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())))); } @@ -2839,33 +2628,15 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 public Brain getBrain() { return this.brain; } -@@ -337,6 +342,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -349,6 +353,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); + 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).add(Attributes.STEP_HEIGHT).add(Attributes.SCALE).add(Attributes.GRAVITY).add(Attributes.SAFE_FALL_DISTANCE).add(Attributes.FALL_DAMAGE_MULTIPLIER).add(Attributes.JUMP_STRENGTH); } + public boolean shouldSendAttribute(Attribute attribute) { return true; } // Purpur @Override protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { -@@ -349,7 +355,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.tryAddSoulSpeed(); - } - -- if (!this.level().isClientSide && this.fallDistance > 3.0F && onGround && !state.isAir()) { -+ if (!this.level().isClientSide && this.fallDistance > this.safeFallDistance && onGround && !state.isAir()) { // Purpur - double d1 = this.getX(); - double d2 = this.getY(); - double d3 = this.getZ(); -@@ -364,7 +370,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - d3 = (double) landedPosition.getZ() + 0.5D + d5 / d6 * 0.5D; - } - -- float f = (float) Mth.ceil(this.fallDistance - 3.0F); -+ float f = (float) Mth.ceil(this.fallDistance - this.safeFallDistance); // Purpur - double d7 = Math.min((double) (0.2F + f / 15.0F), 2.5D); - int i = (int) (150.0D * d7); - -@@ -424,6 +430,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -437,6 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable { double d1 = this.level().getWorldBorder().getDamagePerBlock(); if (d1 > 0.0D) { @@ -2873,7 +2644,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 this.hurt(this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d0 * d1))); } } -@@ -435,7 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -448,7 +454,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (flag1) { this.setAirSupply(this.decreaseAirSupply(this.getAirSupply())); @@ -2882,7 +2653,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 this.setAirSupply(0); Vec3 vec3d = this.getDeltaMovement(); -@@ -447,7 +454,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -460,7 +466,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); } @@ -2891,7 +2662,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } } -@@ -804,6 +811,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -835,6 +841,7 @@ public abstract class LivingEntity extends Entity implements Attackable { dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { nbt.put("Brain", nbtbase); }); @@ -2899,7 +2670,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } @Override -@@ -890,6 +898,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -922,6 +929,11 @@ public abstract class LivingEntity extends Entity implements Attackable { this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain"))); } @@ -2911,21 +2682,22 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } // CraftBukkit start -@@ -1033,10 +1046,31 @@ public abstract class LivingEntity extends Entity implements Attackable { - +@@ -1056,9 +1068,28 @@ public abstract class LivingEntity extends Entity implements Attackable { if (entity != null) { EntityType entitytypes = entity.getType(); -+ // Gale start - Petal - reduce skull ItemStack lookups for reduced visibility + +- if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL) || entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD) || entitytypes == EntityType.PIGLIN && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.PIGLIN_BRUTE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // Gale - Petal - reduce skull ItemStack lookups for reduced visibility +- d0 *= 0.5D; + // Purpur start -+ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) { ++ if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) { + d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent; -+ } else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) { ++ } else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) { + d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent; -+ } else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { ++ } else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) { + d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent; -+ } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD)) { ++ } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) { + d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent; -+ } + } + // Purpur end + + // Purpur start @@ -2936,24 +2708,20 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 + d0 *= this.level().purpurConfig.mobsBlindnessMultiplier; + } + } - -- if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL) || entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD) || entitytypes == EntityType.PIGLIN && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.PIGLIN_BRUTE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // Gale - Petal - reduce skull ItemStack lookups for reduced visibility -- d0 *= 0.5D; - } ++ } + // Purpur end -+ // Gale end } return d0; -@@ -1096,6 +1130,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1117,6 +1148,7 @@ public abstract class LivingEntity extends Entity implements Attackable { for (flag = false; iterator.hasNext(); flag = true) { // CraftBukkit start MobEffectInstance effect = (MobEffectInstance) iterator.next(); -+ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().isBeneficial()) continue; // Purpur ++ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); if (event.isCancelled()) { continue; -@@ -1514,13 +1549,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1533,13 +1565,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; @@ -2969,7 +2737,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 LivingEntity entityliving2 = entitywolf.getOwner(); if (entityliving2 instanceof net.minecraft.world.entity.player.Player) { -@@ -1628,6 +1663,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1654,6 +1686,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -2988,7 +2756,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 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); -@@ -1794,7 +1841,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1820,7 +1864,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = false; if (this.dead && adversary instanceof WitherBoss) { // Paper @@ -2997,7 +2765,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1840,6 +1887,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1866,6 +1910,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropEquipment(); // CraftBukkit - from below if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { @@ -3005,7 +2773,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 this.dropFromLootTable(source, flag); // Paper start final boolean prev = this.clearEquipmentSlots; -@@ -1848,6 +1896,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1874,6 +1919,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper end this.dropCustomDeathLoot(source, i, flag); this.clearEquipmentSlots = prev; // Paper @@ -3013,37 +2781,29 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } // 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, () -> { -@@ -2131,7 +2180,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); - -- return Mth.ceil((fallDistance - 3.0F - f2) * damageMultiplier); -+ return Mth.ceil((fallDistance - this.safeFallDistance - f2) * damageMultiplier); // Purpur - } - } - -@@ -2354,6 +2403,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2407,6 +2453,21 @@ 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; ++ net.minecraft.world.item.component.ItemAttributeModifiers itemattributemodifiers = player.getMainHandItem().getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, net.minecraft.world.item.component.ItemAttributeModifiers.EMPTY); ++ ++ attackDamage = itemattributemodifiers.compute(player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE), EquipmentSlot.MAINHAND); ++ ++ if (attackDamage == 1.0D) { ++ 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. -@@ -2574,7 +2637,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2630,7 +2691,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override protected void onBelowWorld() { @@ -3052,16 +2812,16 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } protected void updateSwingTime() { -@@ -2768,7 +2831,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2825,7 +2886,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected long lastJumpTime = 0L; // Paper - Prevent excessive velocity through repeated crits - protected void jumpFromGround() { + public void jumpFromGround() { // Purpur - protected -> public - Vec3 vec3d = this.getDeltaMovement(); - // Paper start - Prevent excessive velocity through repeated crits - long time = System.nanoTime(); -@@ -2920,6 +2983,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + float f = this.getJumpPower(); + + if (f > 1.0E-5F) { +@@ -2985,6 +3046,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (f3 > 0.0F) { this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F); @@ -3069,7 +2829,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 this.hurt(this.damageSources().flyIntoWall(), f3); } } -@@ -3530,8 +3594,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3522,8 +3584,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); // Paper start - Add EntityMoveEvent @@ -3082,7 +2842,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 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()); -@@ -3541,12 +3607,48 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3533,12 +3597,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()); } } @@ -3123,7 +2883,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 + flag = false; + } + if (flag) { -+ this.setSecondsOnFire(8); ++ this.igniteForSeconds(8); + } + } + } @@ -3131,11 +2891,11 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 } public boolean isSensitiveToWater() { -@@ -3567,7 +3669,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3559,7 +3659,16 @@ public abstract class LivingEntity extends Entity implements Attackable { int j = i / 10; if (j % 2 == 0) { -- itemstack.hurtAndBreak(1, this, (entityliving) -> { +- itemstack.hurtAndBreak(1, this, EquipmentSlot.CHEST); + // Purpur start + int damage = level().purpurConfig.elytraDamagePerSecond; + if (level().purpurConfig.elytraDamageMultiplyBySpeed > 0) { @@ -3144,24 +2904,24 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879 + damage *= (int) speed; + } + } -+ itemstack.hurtAndBreak(damage, this, (entityliving) -> { ++ itemstack.hurtAndBreak(damage, this, EquipmentSlot.CHEST); + // Purpur end - entityliving.broadcastBreakEvent(EquipmentSlot.CHEST); - }); } + + this.gameEvent(GameEvent.ELYTRA_GLIDE); diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424ccb88793d 100644 +index ad08008a9d3f50bab1ae05603aab4cf3be8e2d54..446237ffe4f40cf287c57c28a9866dfea39ed1bb 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -66,6 +66,7 @@ import net.minecraft.world.item.ProjectileWeaponItem; - import net.minecraft.world.item.SpawnEggItem; +@@ -74,6 +74,7 @@ import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.SwordItem; + import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.Level; -@@ -136,6 +137,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -150,6 +151,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti private BlockPos restrictCenter; private float restrictRadius; @@ -3169,7 +2929,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c public boolean aware = true; // CraftBukkit protected Mob(EntityType type, Level world) { -@@ -151,8 +153,8 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -166,8 +168,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti this.goalSelector = new GoalSelector(); this.targetSelector = new GoalSelector(); // Gale end - Purpur - remove vanilla profiler @@ -3180,7 +2940,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c this.jumpControl = new JumpControl(this); this.bodyRotationControl = this.createBodyControl(); this.navigation = this.createNavigation(world); -@@ -327,6 +329,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -341,6 +343,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti entityliving = null; } } @@ -3188,7 +2948,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c this.target = entityliving; return true; // CraftBukkit end -@@ -371,8 +374,28 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -380,8 +383,28 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti this.resetAmbientSoundTime(); this.playAmbientSound(); } @@ -3215,9 +2975,9 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c + // Purpur end + @Override - protected void playHurtSound(DamageSource source) { + protected void playHurtSound(DamageSource damageSource) { this.resetAmbientSoundTime(); -@@ -562,6 +585,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -584,6 +607,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti } nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit @@ -3225,7 +2985,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c } @Override -@@ -632,6 +656,11 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -668,6 +692,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti this.aware = nbt.getBoolean("Bukkit.Aware"); } // CraftBukkit end @@ -3237,7 +2997,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c } @Override -@@ -675,7 +704,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -718,7 +747,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti @Override public void aiStep() { super.aiStep(); @@ -3246,7 +3006,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c 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(); -@@ -1159,6 +1188,12 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1289,6 +1318,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti } @@ -3259,24 +3019,24 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c @Nullable public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) { switch (equipmentSlot) { -@@ -1253,7 +1288,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1383,7 +1418,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti 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)); -- if (randomsource.nextFloat() < 0.05F) { -+ if (randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance) { // Purpur - this.setLeftHanded(true); - } else { - this.setLeftHanded(false); -@@ -1301,6 +1336,7 @@ public abstract class Mob extends LivingEntity implements Targeting { + this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); +- this.setLeftHanded(randomsource.nextFloat() < 0.05F); ++ this.setLeftHanded(randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance); // Purpur + return entityData; + } + +@@ -1430,6 +1465,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti if (!this.isAlive()) { return InteractionResult.PASS; } else if (this.getLeashHolder() == player) { + if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur // CraftBukkit start - fire PlayerUnleashEntityEvent // Paper start - Expand EntityUnleashEvent - org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild); -@@ -1375,7 +1411,7 @@ public abstract class Mob extends LivingEntity implements Targeting { + org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); +@@ -1505,7 +1541,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} protected InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -3285,7 +3045,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c } public boolean isWithinRestriction() { -@@ -1686,6 +1722,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1820,6 +1856,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti this.setLastHurtMob(target); } @@ -3293,7 +3053,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c return flag; } -@@ -1711,28 +1748,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1829,28 +1866,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti // Gale end - JettPack - optimize sun burn tick - cache eye blockpos public boolean isSunBurnTick() { @@ -3323,7 +3083,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c } @Override -@@ -1780,4 +1796,56 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1898,4 +1914,56 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg); } @@ -3394,13 +3154,13 @@ index 2ee48ac3b665db2b02bcb1a30ec972d43a3725b0..59e8f5431ce5026209e1428b5fa5b548 } // 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 12458621cadf5d186307c8b08edcb48f9c70c4f0..94082358b0dd573e09e61b167af2a54f8aa4bb2a 100644 +index 665fbe3362dcd9de4bd290b71a1b1f2fed218eeb..894082d9a8e2aa05f86948bfd335090f37a4ba07 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -@@ -27,14 +27,22 @@ public class AttributeMap { - // Gale end - Lithium - replace AI attributes with optimized collections +@@ -23,14 +23,22 @@ public class AttributeMap { + private final Set dirtyAttributes = new ObjectOpenHashSet<>(); private final AttributeSupplier supplier; - private final java.util.function.Function createInstance; // Gale - Airplane - reduce entity allocations + private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations + private final net.minecraft.world.entity.LivingEntity entity; // Purpur public AttributeMap(AttributeSupplier defaultAttributes) { @@ -3412,29 +3172,29 @@ index 12458621cadf5d186307c8b08edcb48f9c70c4f0..94082358b0dd573e09e61b167af2a54f + this.entity = entity; + // Purpur end this.supplier = defaultAttributes; - this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Gale - Airplane - reduce entity allocations + this.createInstance = attributex -> this.supplier.createInstance(this::onAttributeModified, attributex); // Gale - Airplane - reduce entity allocations } private void onAttributeModified(AttributeInstance instance) { -- if (instance.getAttribute().isClientSyncable()) { -+ if (instance.getAttribute().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute()))) { // Purpur +- if (instance.getAttribute().value().isClientSyncable()) { ++ if (instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))) { // Purpur this.dirtyAttributes.add(instance); } } -@@ -44,7 +52,7 @@ public class AttributeMap { +@@ -40,7 +48,7 @@ public class AttributeMap { } public Collection getSyncableAttributes() { -- return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().isClientSyncable()).collect(Collectors.toList()); -+ return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute()))).collect(Collectors.toList()); // Purpur +- return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable()).collect(Collectors.toList()); ++ return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute().value()))).collect(Collectors.toList()); // Purpur } @Nullable 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 c92583b6d1527db32f4a644f30c8f8468e9e2fc2..b8f65dc8f0db4bbe5f9c223e4ba129738fbfd795 100644 +index 10a1434313b11dae8210484583c6bf3b627416f7..35af18f371b3beaf81fcdca79fefe85e0a862b50 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 -@@ -123,7 +123,7 @@ public class DefaultAttributes { +@@ -129,7 +129,7 @@ public class DefaultAttributes { .put(EntityType.OCELOT, Ocelot.createAttributes().build()) .put(EntityType.PANDA, Panda.createAttributes().build()) .put(EntityType.PARROT, Parrot.createAttributes().build()) @@ -3456,7 +3216,7 @@ index f0703302e7dbbda88de8c648d20d87c55ed9b1e0..a913ebabaa5f443afa987b972355a8f8 } } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index b5242f2d450f863a3eb774d8a14bb00cbe699a16..4d2b6e69ed98aca98ffc50fefc6e535c1afb759d 100644 +index b5242f2d450f863a3eb774d8a14bb00cbe699a16..c72ce539f3e339c6e87138e744f033d2143abc7a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java @@ -82,7 +82,7 @@ public class AcquirePoi { @@ -3464,15 +3224,15 @@ index b5242f2d450f863a3eb774d8a14bb00cbe699a16..4d2b6e69ed98aca98ffc50fefc6e535c // Paper start - optimise POI access java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); - io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); -+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur ++ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur Set, BlockPos>> set = new java.util.HashSet<>(poiposes); // Paper end - optimise POI access Path path = findPathToPois(entity, set); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java -index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02d22db5c1 100644 +index 2ade08d1466660ee1787fa97908002ef56389712..8d4e206aa05b95b7bfec5d23496085cf55a3e1de 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java -@@ -40,17 +40,19 @@ public class HarvestFarmland extends Behavior { +@@ -41,17 +41,19 @@ public class HarvestFarmland extends Behavior { private long nextOkStartTime; private int timeWorkedSoFar; private final List validFarmlandAroundVillager = Lists.newArrayList(); @@ -3494,7 +3254,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02 BlockPos.MutableBlockPos blockposition_mutableblockposition = entity.blockPosition().mutable(); this.validFarmlandAroundVillager.clear(); -@@ -81,6 +83,7 @@ public class HarvestFarmland extends Behavior { +@@ -82,6 +84,7 @@ public class HarvestFarmland extends Behavior { Block block = iblockdata.getBlock(); Block block1 = world.getBlockState(pos.below()).getBlock(); @@ -3502,7 +3262,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02 return block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) || iblockdata.isAir() && block1 instanceof FarmBlock; } -@@ -106,20 +109,20 @@ public class HarvestFarmland extends Behavior { +@@ -107,20 +110,20 @@ public class HarvestFarmland extends Behavior { Block block = iblockdata.getBlock(); Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock(); @@ -3526,7 +3286,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02 Item item = itemstack.getItem(); if (item instanceof BlockItem) { -@@ -135,7 +138,7 @@ public class HarvestFarmland extends Behavior { +@@ -136,7 +139,7 @@ public class HarvestFarmland extends Behavior { } if (flag) { @@ -3536,7 +3296,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02 if (itemstack.isEmpty()) { inventorysubcontainer.setItem(j, ItemStack.EMPTY); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -index 42ae4d293a420f0b8eb476df6389b2e7a693895f..97c20c5b89e6d7e4ed844eff39ee55dfa8988d37 100644 +index 736f46d552d558bf0edd9a86601b5fbb6940815b..cf039181dfe0ddb3ccda44064a5d8a2f6c5c432c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java @@ -57,7 +57,7 @@ public class InteractWithDoor { @@ -3579,15 +3339,15 @@ index 18dad0825616c4167a0a7555689ee64910a87e09..6945992491027d43eca4f1ca697ad45c && this.lookTime > 0 && entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -index a866e254b7faf50e2e64829a7e40db62d4d26424..753587e4d9582605951461f2bea37aff3bf28fcd 100644 +index 3232f40ef11f59091cec469f0dd40c60ee2a16e9..7db823e9edd70808c5629f0a7efd84fe40f42dd9 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -@@ -65,6 +65,12 @@ public class TradeWithVillager extends Behavior { +@@ -63,6 +63,12 @@ public class TradeWithVillager extends Behavior { throwHalfStack(entity, Villager.FOOD_POINTS_KEY_ARRAY, villager); // Gale - optimize villager data storage } + // Purpur start -+ if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getMaxStackSize() / 2) { ++ if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) { + throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager); + } + // Purpur end @@ -3596,10 +3356,10 @@ index a866e254b7faf50e2e64829a7e40db62d4d26424..753587e4d9582605951461f2bea37aff if (this.trades != null && entity.getInventory().hasAnyOf(this.trades)) { throwHalfStack(entity, this.trades, villager); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java -index d2917f9b215919890f28b513601863ccaced17c7..58338e240079f2de1669e8c2ce839451511feafd 100644 +index f000a6c1e61198e6dd06ae5f084d12fdf309f50a..3091d985ba9c55d404332576320718840538722e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java -@@ -49,8 +49,13 @@ public class VillagerGoalPackages { +@@ -52,8 +52,13 @@ public class VillagerGoalPackages { } public static ImmutableList>> getWorkPackage(VillagerProfession profession, float speed) { @@ -3615,10 +3375,10 @@ index d2917f9b215919890f28b513601863ccaced17c7..58338e240079f2de1669e8c2ce839451 } else { workAtPoi = new WorkAtPoi(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java -index 0cc411dd39d981187c9e9a3c5eb8043b19a09b98..f7032f4ea55f5aca293c2640686238b7af0f9c80 100644 +index 0a608418f87b71d5d71706712e1f82da0d7e4d34..03e7ca83e4c28dfaa5b52bcb100bd542db105970 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java -@@ -127,8 +127,10 @@ public class VillagerMakeLove extends Behavior { +@@ -125,8 +125,10 @@ public class VillagerMakeLove extends Behavior { return Optional.empty(); } // Move age setting down @@ -3632,7 +3392,7 @@ index 0cc411dd39d981187c9e9a3c5eb8043b19a09b98..f7032f4ea55f5aca293c2640686238b7 // CraftBukkit end world.broadcastEntityEvent(entityvillager2, (byte) 12); diff --git a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java -index ca02566b20dd52a59bc7b150529a1d68bc560ab0..10265fd19c90cea34372a786bb272dbcdd91b993 100644 +index c8fd5696de7c3623cdb4f498190a5c2708cf843e..e403d9dfeeaa3dcf53be790d761e7e922419efb0 100644 --- a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java +++ b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java @@ -29,6 +29,20 @@ public class MoveControl implements Control { @@ -3734,7 +3494,7 @@ index df695b444fa2a993d381e2f197182c3e91a68502..0f4f546cd0eda4bd82b47446ae23ac32 double d = this.llama.distanceToSqr(this.llama.getCaravanHead()); if (d > 676.0) { 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 5580a396a56c6e0f364a5368985ee99b9e2be0a8..3facfd6eee17cb0b59425494c966e19833660dd2 100644 +index 6634228ef002cbef67980272a26be4a75c954116..a61abba840a55fb4fbc9716a5e05eb2778068785 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 { @@ -3747,7 +3507,7 @@ index 5580a396a56c6e0f364a5368985ee99b9e2be0a8..3facfd6eee17cb0b59425494c966e198 } else if (this.nextStartTick > 0) { --this.nextStartTick; diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java -index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..a3074ec9b430c9d0a0ef33fe353db643849fab7d 100644 +index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..d409ae987088df3d47192128401d7491aaabc87c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java @@ -67,7 +67,7 @@ public class RunAroundLikeCrazyGoal extends Goal { @@ -3755,7 +3515,7 @@ index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..a3074ec9b430c9d0a0ef33fe353db643 int j = this.horse.getMaxTemper(); - if (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent -+ if ((this.horse.level().purpurConfig.alwaysTameInCreative && ((Player) entity).getAbilities().instabuild) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // CraftBukkit - fire EntityTameEvent // Purpur ++ if ((this.horse.level().purpurConfig.alwaysTameInCreative && entityhuman.hasInfiniteMaterials()) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // CraftBukkit - fire EntityTameEvent // Purpur this.horse.tameWithName(entityhuman); return; } @@ -3779,10 +3539,10 @@ index 137ec75ee803789deb7b1ca93dd9369c9af362b9..ca95d25af3e9a0536868b0c7fd8e7d2f } } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java -index 0d9b194781d152e842c9a4b8d6f23d307b2e4452..00cf59524477ec79d4354cc403fc3e75a63b81a0 100644 +index 13f8c2cb42334ba3b573ca44ace1d3df76e41ff7..baca552e52c728867fcb0527b6c3eb394b2b9c7f 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java -@@ -62,7 +62,7 @@ public class TemptGoal extends Goal { +@@ -64,7 +64,7 @@ public class TemptGoal extends Goal { } private boolean shouldFollow(LivingEntity entity) { @@ -3847,18 +3607,10 @@ index 68bc8699a9389d118411ea7134ea0e0588adf8dc..1731147abd53ca2149683ea593e96523 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 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464dad395c6f 100644 +index f223e369dd8d781e32e1f06572b2ae717afd6f32..f1a3e05d993e87cb93e6916d2c5a130d7d852b6a 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -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; -+import net.minecraft.world.entity.MoverType; - import net.minecraft.world.entity.Pose; - import net.minecraft.world.entity.ai.attributes.AttributeSupplier; - import net.minecraft.world.entity.ai.attributes.Attributes; -@@ -46,12 +47,59 @@ public class Bat extends AmbientCreature { +@@ -44,12 +44,59 @@ public class Bat extends AmbientCreature { public Bat(EntityType type, Level world) { super(type, world); @@ -3909,7 +3661,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d + float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2; + setSpeed(speed); + Vec3 mot = getDeltaMovement(); -+ move(MoverType.SELF, mot.multiply(speed, 0.25, speed)); ++ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 0.25, speed)); + setDeltaMovement(mot.scale(0.9D)); + } + } @@ -3918,7 +3670,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d @Override public boolean isFlapping() { return !this.isResting() && (float) this.tickCount % 10.0F == 0.0F; -@@ -101,7 +149,7 @@ public class Bat extends AmbientCreature { +@@ -99,7 +146,7 @@ public class Bat extends AmbientCreature { protected void pushEntities() {} public static AttributeSupplier.Builder createAttributes() { @@ -3927,7 +3679,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d } public boolean isResting() { -@@ -134,6 +182,14 @@ public class Bat extends AmbientCreature { +@@ -132,6 +179,14 @@ public class Bat extends AmbientCreature { @Override protected void customServerAiStep() { @@ -3942,7 +3694,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d super.customServerAiStep(); BlockPos blockposition = this.blockPosition(); BlockPos blockposition1 = blockposition.above(); -@@ -212,6 +268,28 @@ public class Bat extends AmbientCreature { +@@ -210,6 +265,28 @@ public class Bat extends AmbientCreature { } } @@ -3972,10 +3724,10 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); diff --git a/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java b/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java -index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c921c3881a7 100644 +index 3231eaa6af2ddfe4095ff2d650f580ebd4d43aea..e8cb124d232f7316cc8c35dd8bd12f79bbcda7d6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java -@@ -94,6 +94,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { +@@ -87,6 +87,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { @Override protected void registerGoals() { super.registerGoals(); @@ -3983,7 +3735,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92 this.goalSelector.addGoal(0, new PanicGoal(this, 1.25)); this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 1.6, 1.4, EntitySelector.NO_SPECTATORS::test)); this.goalSelector.addGoal(4, new AbstractFish.FishSwimGoal(this)); -@@ -107,7 +108,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { +@@ -100,7 +101,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { @Override public void travel(Vec3 movementInput) { if (this.isEffectiveAi() && this.isInWater()) { @@ -3992,7 +3744,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92 this.move(MoverType.SELF, this.getDeltaMovement()); this.setDeltaMovement(this.getDeltaMovement().scale(0.9)); if (this.getTarget() == null) { -@@ -168,7 +169,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { +@@ -161,7 +162,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { protected void playStepSound(BlockPos pos, BlockState state) { } @@ -4001,7 +3753,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92 private final AbstractFish fish; FishMoveControl(AbstractFish owner) { -@@ -176,14 +177,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { +@@ -169,14 +170,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { this.fish = owner; } @@ -4027,7 +3779,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92 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 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83c346eb85 100644 +index 5193cf1d3c922d750a11e492b7636215e23ad0d6..7f90a0d8f65c96844df06b7c4fa3da28a6f51dd1 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 { @@ -4038,7 +3790,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83 protected Animal(EntityType type, Level world) { super(type, world); -@@ -151,7 +152,7 @@ public abstract class Animal extends AgeableMob { +@@ -146,7 +147,7 @@ public abstract class Animal extends AgeableMob { if (this.isFood(itemstack)) { int i = this.getAge(); @@ -4047,7 +3799,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83 final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying this.usePlayerItem(player, hand, itemstack); this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying -@@ -242,12 +243,20 @@ public abstract class Animal extends AgeableMob { +@@ -234,12 +235,20 @@ public abstract class Animal extends AgeableMob { AgeableMob entityageable = this.getBreedOffspring(world, other); if (entityageable != null) { @@ -4071,7 +3823,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83 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()) { -@@ -275,8 +284,10 @@ public abstract class Animal extends AgeableMob { +@@ -267,8 +276,10 @@ public abstract class Animal extends AgeableMob { entityplayer.awardStat(Stats.ANIMALS_BRED); CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable); } // Paper @@ -4085,18 +3837,10 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83 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 f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd6473ba96 100644 +index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d73cd27e68 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; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.Mob; - import net.minecraft.world.entity.MobType; -+import net.minecraft.world.entity.MoverType; - import net.minecraft.world.entity.NeutralMob; - import net.minecraft.world.entity.PathfinderMob; - import net.minecraft.world.entity.Pose; -@@ -147,6 +148,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -143,6 +143,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { public Bee(EntityType type, Level world) { super(type, world); this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); @@ -4104,7 +3848,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd // Paper start - Fix MC-167279 class BeeFlyingMoveControl extends FlyingMoveControl { public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { -@@ -155,22 +157,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -151,22 +152,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public void tick() { @@ -4130,12 +3874,12 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd this.moveControl = new BeeFlyingMoveControl(this, 20, true); // Paper end - Fix MC-167279 this.lookControl = new Bee.BeeLookControl(this); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); -- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); -+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur - this.setPathfindingMalus(BlockPathTypes.WATER_BORDER, 16.0F); - this.setPathfindingMalus(BlockPathTypes.COCOA, -1.0F); - this.setPathfindingMalus(BlockPathTypes.FENCE, -1.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); +- this.setPathfindingMalus(PathType.WATER, -1.0F); ++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur + this.setPathfindingMalus(PathType.WATER_BORDER, 16.0F); + this.setPathfindingMalus(PathType.COCOA, -1.0F); + this.setPathfindingMalus(PathType.FENCE, -1.0F); } + // Purpur start @@ -4166,16 +3910,16 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd + float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2; + setSpeed(speed); + Vec3 mot = getDeltaMovement(); -+ move(MoverType.SELF, mot.multiply(speed, speed, speed)); ++ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed)); + setDeltaMovement(mot.scale(0.9D)); + } + } + // Purpur end + @Override - protected void defineSynchedData() { - super.defineSynchedData(); -@@ -185,6 +234,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -181,6 +229,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override protected void registerGoals() { @@ -4183,7 +3927,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.399999976158142D, true)); this.goalSelector.addGoal(1, new Bee.BeeEnterHiveGoal()); this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); -@@ -200,6 +250,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -198,6 +247,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.goalSelector.addGoal(7, new Bee.BeeGrowCropGoal()); this.goalSelector.addGoal(8, new Bee.BeeWanderGoal()); this.goalSelector.addGoal(9, new FloatGoal(this)); @@ -4191,7 +3935,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd 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)); -@@ -355,7 +406,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -345,7 +395,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { boolean wantsToEnterHive() { if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { @@ -4200,7 +3944,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd return flag && !this.isHiveNearFire(); } else { -@@ -395,6 +446,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -385,6 +435,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.hurt(this.damageSources().drown(), 1.0F); } @@ -4208,7 +3952,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd if (flag) { ++this.timeSinceSting; if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { -@@ -427,6 +479,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -417,6 +468,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -4235,7 +3979,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd @Override public int getRemainingPersistentAngerTime() { return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME); -@@ -742,6 +814,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -726,6 +797,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); @@ -4243,7 +3987,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd return true; } else { Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); -@@ -798,6 +871,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -782,6 +854,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.pollinating = false; Bee.this.navigation.stop(); Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; @@ -4251,7 +3995,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd } @Override -@@ -844,6 +918,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -828,6 +901,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setWantedPos(); } @@ -4259,14 +4003,14 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd ++this.successfulPollinatingTicks; if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { this.lastSoundPlayedTick = this.successfulPollinatingTicks; -@@ -888,16 +963,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -872,16 +946,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } - private class BeeLookControl extends LookControl { + private class BeeLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - BeeLookControl(Mob entity) { + BeeLookControl(final Mob entity) { super(entity); } @@ -4280,11 +4024,11 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd } diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java -index f760ce7d9df79ef58f8963de3e901cba3e12fcaa..6af5e1dfcfd739e0bc857f648c189151d5a795c8 100644 +index 07559b9629d4ecb40b511256f400a781e39820e0..3e1345f1c534320e07820d573f5c8dba49746425 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java -@@ -98,6 +98,51 @@ public class Cat extends TamableAnimal implements VariantHolder { - super(type, world); +@@ -104,6 +104,53 @@ public class Cat extends TamableAnimal implements VariantHolder { - protected void registerGoals() { - this.temptGoal = new Cat.CatTemptGoal(this, 0.6D, Cat.TEMPT_INGREDIENT, true); +@@ -114,6 +161,7 @@ public class Cat extends TamableAnimal implements VariantHolder { +@@ -126,6 +174,7 @@ public class Cat extends TamableAnimal implements VariantHolder(this, Rabbit.class, false, (Predicate) null)); this.targetSelector.addGoal(1, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -309,6 +356,14 @@ public class Cat extends TamableAnimal implements VariantHolder { +@@ -318,6 +367,14 @@ public class Cat extends TamableAnimal implements VariantHolder { +@@ -377,6 +434,7 @@ public class Cat extends TamableAnimal implements VariantHolder { - } - } else if (this.isFood(itemstack)) { - this.usePlayerItem(player, hand, itemstack); -- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit -+ if ((this.level().purpurConfig.alwaysTameInCreative && player.getAbilities().instabuild) || (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled())) { // CraftBukkit // Purpur - this.tame(player); - this.setOrderedToSit(true); - this.level().broadcastEntityEvent(this, (byte) 7); + private void tryToTame(Player player) { +- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit ++ if ((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit + this.tame(player); + this.setOrderedToSit(true); + this.level().broadcastEntityEvent(this, (byte) 7); diff --git a/src/main/java/net/minecraft/world/entity/animal/Chicken.java b/src/main/java/net/minecraft/world/entity/animal/Chicken.java -index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9f228a3ee 100644 +index 0a4d4cb4ad7cda7c50c46151c03586865d56c797..d8fe8f86ccc9b26b2208b090bb6572b483d14bae 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Chicken.java +++ b/src/main/java/net/minecraft/world/entity/animal/Chicken.java -@@ -55,16 +55,65 @@ public class Chicken extends Animal { - this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F); +@@ -54,10 +54,51 @@ public class Chicken extends Animal { + this.setPathfindingMalus(PathType.WATER, 0.0F); } + // Purpur start @@ -4438,8 +4184,9 @@ index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9 + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + // this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D)); // Purpur - moved down this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, Chicken.FOOD_ITEMS, false)); - this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.1D)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, (itemstack) -> { + return itemstack.is(ItemTags.CHICKEN_FOOD); +@@ -66,6 +107,14 @@ public class Chicken extends Animal { this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); @@ -4454,7 +4201,7 @@ index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9 } @Override -@@ -73,7 +122,7 @@ public class Chicken extends Animal { +@@ -74,7 +123,7 @@ public class Chicken extends Animal { } public static AttributeSupplier.Builder createAttributes() { @@ -4502,7 +4249,7 @@ index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..f0b6118a9995bb41836685bbf94d2e7f public ItemStack getBucketItemStack() { return new ItemStack(Items.COD_BUCKET); diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java -index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594ac7b06fe 100644 +index 5a7b1be351834a6b8889b1380cede1be025cb302..1691a98caabf27ea092a9b422649ac84bc0a7235 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cow.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java @@ -2,6 +2,7 @@ package net.minecraft.world.entity.animal; @@ -4513,21 +4260,23 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; -@@ -30,6 +31,7 @@ import net.minecraft.world.item.ItemUtils; +@@ -29,6 +30,7 @@ import net.minecraft.world.item.ItemStack; + import net.minecraft.world.item.ItemUtils; import net.minecraft.world.item.Items; - import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; - import org.joml.Vector3f; - -@@ -40,25 +42,74 @@ import org.bukkit.event.player.PlayerBucketFillEvent; + // CraftBukkit start + import org.bukkit.craftbukkit.event.CraftEventFactory; +@@ -37,6 +39,7 @@ import org.bukkit.event.player.PlayerBucketFillEvent; // CraftBukkit end public class Cow extends Animal { + private boolean isNaturallyAggressiveToPlayers; // Purpur - public Cow(EntityType type, Level world) { + private static final EntityDimensions BABY_DIMENSIONS = EntityType.COW.getDimensions().scale(0.5F).withEyeHeight(0.665F); + +@@ -44,18 +47,65 @@ public class Cow extends Animal { super(type, world); } @@ -4565,9 +4314,9 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 + } + + @Override -+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, net.minecraft.world.entity.SpawnGroupData entityData, net.minecraft.nbt.CompoundTag entityNbt) { ++ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, net.minecraft.world.entity.SpawnGroupData entityData) { + this.isNaturallyAggressiveToPlayers = world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance; -+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); ++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData); + } + + @Override @@ -4582,8 +4331,10 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 this.goalSelector.addGoal(1, new PanicGoal(this, 2.0D)); + this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); -+ if (level().purpurConfig.cowFeedMushrooms > 0) this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(Items.WHEAT, Blocks.RED_MUSHROOM.asItem(), Blocks.BROWN_MUSHROOM.asItem()), false)); else // Purpur - this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(Items.WHEAT), false)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, (itemstack) -> { +- return itemstack.is(ItemTags.COW_FOOD); ++ return level().purpurConfig.cowFeedMushrooms > 0 && (itemstack.is(Blocks.RED_MUSHROOM.asItem()) || itemstack.is(Blocks.BROWN_MUSHROOM.asItem())) || itemstack.is(ItemTags.COW_FOOD); // Purpur + }, false)); this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25D)); this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); @@ -4591,13 +4342,17 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 + this.targetSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, target -> isNaturallyAggressiveToPlayers)); // Purpur } + @Override +@@ -64,7 +114,7 @@ public class Cow extends Animal { + } + public static AttributeSupplier.Builder createAttributes() { - return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.MOVEMENT_SPEED, 0.20000000298023224D); + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.MOVEMENT_SPEED, 0.20000000298023224D).add(Attributes.ATTACK_DAMAGE, 0.0D); // Purpur } @Override -@@ -88,6 +139,7 @@ public class Cow extends Animal { +@@ -94,6 +144,7 @@ public class Cow extends Animal { @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -4605,7 +4360,7 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.BUCKET) && !this.isBaby()) { -@@ -95,7 +147,7 @@ public class Cow extends Animal { +@@ -101,7 +152,7 @@ public class Cow extends Animal { PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); if (event.isCancelled()) { @@ -4614,7 +4369,7 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 } // CraftBukkit end -@@ -104,6 +156,10 @@ public class Cow extends Animal { +@@ -110,6 +161,10 @@ public class Cow extends Animal { player.setItemInHand(hand, itemstack1); return InteractionResult.sidedSuccess(this.level().isClientSide); @@ -4625,9 +4380,9 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 } else { return super.mobInteract(player, hand); } -@@ -124,4 +180,69 @@ public class Cow extends Animal { - protected Vector3f getPassengerAttachmentPoint(Entity passenger, EntityDimensions dimensions, float scaleFactor) { - return new Vector3f(0.0F, dimensions.height - 0.03125F * scaleFactor, 0.0F); +@@ -125,4 +180,69 @@ public class Cow extends Animal { + public EntityDimensions getDefaultDimensions(Pose pose) { + return this.isBaby() ? Cow.BABY_DIMENSIONS : super.getDefaultDimensions(pose); } + + // Purpur start - feed mushroom to change to mooshroom @@ -4696,10 +4451,10 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594 + // 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 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18c1a2243c 100644 +index 1b1cb0e4d54e52ebe794199e386c54c5d84b3719..c1a9a87ef0fefc499c0e1edbe1031f47cc432b31 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -@@ -83,19 +83,104 @@ public class Dolphin extends WaterAnimal { +@@ -81,19 +81,104 @@ public class Dolphin extends WaterAnimal { public static final Predicate ALLOWED_ITEMS = (entityitem) -> { return !entityitem.hasPickUpDelay() && entityitem.isAlive() && entityitem.isInWater(); }; @@ -4798,14 +4553,14 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18 + @Nullable @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { + public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) { this.setAirSupply(this.getMaxAirSupply()); this.setXRot(0.0F); + this.isNaturallyAggressiveToPlayers = world.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance; // Purpur - return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); + return super.finalizeSpawn(world, difficulty, spawnReason, entityData); } -@@ -160,17 +245,21 @@ public class Dolphin extends WaterAnimal { +@@ -158,17 +243,21 @@ public class Dolphin extends WaterAnimal { protected void registerGoals() { this.goalSelector.addGoal(0, new BreathAirGoal(this)); this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); @@ -4828,7 +4583,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18 } public static AttributeSupplier.Builder createAttributes() { -@@ -221,7 +310,7 @@ public class Dolphin extends WaterAnimal { +@@ -214,7 +303,7 @@ public class Dolphin extends WaterAnimal { @Override protected boolean canRide(Entity entity) { @@ -4837,7 +4592,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18 } @Override -@@ -256,6 +345,11 @@ public class Dolphin extends WaterAnimal { +@@ -249,6 +338,11 @@ public class Dolphin extends WaterAnimal { @Override public void tick() { super.tick(); @@ -4849,7 +4604,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18 if (this.isNoAi()) { this.setAirSupply(this.getMaxAirSupply()); } else { -@@ -401,6 +495,7 @@ public class Dolphin extends WaterAnimal { +@@ -391,6 +485,7 @@ public class Dolphin extends WaterAnimal { @Override public boolean canUse() { @@ -4858,10 +4613,10 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18 } 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 f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71777c7874 100644 +index e705449496b1a06270ecbc13f4dce5357479845b..124839f22ed0499ca395a648e858469d81d31f93 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; +@@ -37,6 +37,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.util.StringRepresentable; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.InteractionHand; @@ -4869,7 +4624,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.AgeableMob; import net.minecraft.world.entity.Entity; -@@ -148,6 +149,64 @@ public class Fox extends Animal implements VariantHolder { +@@ -145,6 +146,64 @@ public class Fox extends Animal implements VariantHolder { this.setCanPickUpLoot(true); } @@ -4932,9 +4687,9 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 + } + @Override - protected void defineSynchedData() { - super.defineSynchedData(); -@@ -167,6 +226,7 @@ public class Fox extends Animal implements VariantHolder { + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -164,6 +223,7 @@ public class Fox extends Animal implements VariantHolder { return entityliving instanceof AbstractSchoolingFish; }); this.goalSelector.addGoal(0, new Fox.FoxFloatGoal()); @@ -4942,7 +4697,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 this.goalSelector.addGoal(0, new ClimbOnTopOfPowderSnowGoal(this, this.level())); this.goalSelector.addGoal(1, new Fox.FaceplantGoal()); this.goalSelector.addGoal(2, new Fox.FoxPanicGoal(2.2D)); -@@ -193,6 +253,7 @@ public class Fox extends Animal implements VariantHolder { +@@ -190,6 +250,7 @@ public class Fox extends Animal implements VariantHolder { this.goalSelector.addGoal(11, new Fox.FoxSearchForItemsGoal()); this.goalSelector.addGoal(12, new Fox.FoxLookAtPlayerGoal(this, Player.class, 24.0F)); this.goalSelector.addGoal(13, new Fox.PerchAndSearchGoal()); @@ -4950,7 +4705,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 this.targetSelector.addGoal(3, new Fox.DefendTrustedTargetGoal(LivingEntity.class, false, false, (entityliving) -> { return Fox.TRUSTED_TARGET_SELECTOR.test(entityliving) && !this.trusts(entityliving.getUUID()); })); -@@ -349,6 +410,11 @@ public class Fox extends Animal implements VariantHolder { +@@ -344,6 +405,11 @@ public class Fox extends Animal implements VariantHolder { } private void setTargetGoals() { @@ -4962,7 +4717,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 if (this.getVariant() == Fox.Type.RED) { this.targetSelector.addGoal(4, this.landTargetGoal); this.targetSelector.addGoal(4, this.turtleEggTargetGoal); -@@ -382,6 +448,7 @@ public class Fox extends Animal implements VariantHolder { +@@ -377,6 +443,7 @@ public class Fox extends Animal implements VariantHolder { public void setVariant(Fox.Type variant) { this.entityData.set(Fox.DATA_TYPE_ID, variant.getId()); @@ -4970,7 +4725,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 } List getTrustedUUIDs() { -@@ -728,6 +795,29 @@ public class Fox extends Animal implements VariantHolder { +@@ -717,6 +784,29 @@ public class Fox extends Animal implements VariantHolder { } // Paper end @@ -5000,7 +4755,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 @Override // Paper start - Cancellable death event protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) { -@@ -785,16 +875,16 @@ public class Fox extends Animal implements VariantHolder { +@@ -769,16 +859,16 @@ public class Fox extends Animal implements VariantHolder { return new Vec3(0.0D, (double) (0.55F * this.getEyeHeight()), (double) (this.getBbWidth() * 0.4F)); } @@ -5020,7 +4775,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 } } -@@ -805,16 +895,16 @@ public class Fox extends Animal implements VariantHolder { +@@ -789,16 +879,16 @@ public class Fox extends Animal implements VariantHolder { } } @@ -5040,7 +4795,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 } } -@@ -932,8 +1022,10 @@ public class Fox extends Animal implements VariantHolder { +@@ -916,8 +1006,10 @@ public class Fox extends Animal implements VariantHolder { CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer2, this.animal, this.partner, entityfox); } @@ -5053,7 +4808,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 this.animal.resetLove(); this.partner.resetLove(); worldserver.addFreshEntityWithPassengers(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason -@@ -1319,7 +1411,7 @@ public class Fox extends Animal implements VariantHolder { +@@ -1303,7 +1395,7 @@ public class Fox extends Animal implements VariantHolder { } protected void onReachedTarget() { @@ -5063,10 +4818,10 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71 if (iblockdata.is(Blocks.SWEET_BERRY_BUSH)) { diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b718abd62 100644 +index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a678be60c 100644 --- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -@@ -60,14 +60,59 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -56,13 +56,58 @@ public class IronGolem extends AbstractGolem implements NeutralMob { private int remainingPersistentAngerTime; @Nullable private UUID persistentAngerTarget; @@ -5074,7 +4829,6 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b public IronGolem(EntityType type, Level world) { super(type, world); - this.setMaxUpStep(1.0F); } + // Purpur start @@ -5126,7 +4880,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0D, true)); this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9D, 32.0F)); this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6D, false)); -@@ -75,6 +120,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -70,6 +115,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { this.goalSelector.addGoal(5, new OfferFlowerGoal(this)); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); @@ -5134,7 +4888,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b this.targetSelector.addGoal(1, new DefendVillageTargetGoal(this)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); -@@ -139,6 +185,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -134,6 +180,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putBoolean("PlayerCreated", this.isPlayerCreated()); @@ -5142,7 +4896,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b this.addPersistentAngerSaveData(nbt); } -@@ -146,6 +193,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -141,6 +188,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); this.setPlayerCreated(nbt.getBoolean("PlayerCreated")); @@ -5150,7 +4904,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b this.readPersistentAngerSaveData(this.level(), nbt); } -@@ -270,13 +318,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -265,18 +313,19 @@ public class IronGolem extends AbstractGolem implements NeutralMob { ItemStack itemstack = player.getItemInHand(hand); if (!itemstack.is(Items.IRON_INGOT)) { @@ -5166,16 +4920,14 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b } else { float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; -@@ -285,6 +333,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - itemstack.shrink(1); - } - + this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f1); + itemstack.consume(1, player); + if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur return InteractionResult.sidedSuccess(this.level().isClientSide); } } 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 6659abb4ab8a13a48c154d2e3f273eb13b202e7f..560981601c6a43fee99372eafd7bd746798845a6 100644 +index 5707c6287a691030841fa973e8f7f34a816103e4..8299ed1f8632f94592f274b543b234c46fd83886 100644 --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java @@ -64,6 +64,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 +- 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()) { @@ -5236,16 +4988,16 @@ index 6659abb4ab8a13a48c154d2e3f273eb13b202e7f..560981601c6a43fee99372eafd7bd746 } drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); } -@@ -152,7 +189,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder> optional = this.getEffectsFromItemStack(itemstack); +@@ -150,7 +187,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder optional = this.getEffectsFromItemStack(itemstack); if (optional.isEmpty()) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur } - if (!player.getAbilities().instabuild) { -@@ -176,13 +213,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder generateDefaultDrops() { -+ public List generateDefaultDrops(int looting) { // Purpur - List dropEntities = new java.util.ArrayList<>(5); +- public java.util.List generateDefaultDrops() { ++ public java.util.List generateDefaultDrops(int looting) { // Purpur + java.util.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; diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java -index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf598352a62a35 100644 +index 2c7491edbb60e7ec6a208ea7292cd28a3f8f9e31..07dc8a43f4e8c54a94696b84896d32f66a207ad3 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java -@@ -70,6 +70,43 @@ public class Ocelot extends Animal { +@@ -66,6 +66,43 @@ public class Ocelot extends Animal { this.reassessTrustingGoals(); } @@ -5310,9 +5062,9 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983 public boolean isTrusting() { return (Boolean) this.entityData.get(Ocelot.DATA_TRUSTING); } -@@ -101,12 +138,14 @@ public class Ocelot extends Animal { - protected void registerGoals() { - this.temptGoal = new Ocelot.OcelotTemptGoal(this, 0.6D, Ocelot.TEMPT_INGREDIENT, true); +@@ -99,12 +136,14 @@ public class Ocelot extends Animal { + return itemstack.is(ItemTags.OCELOT_FOOD); + }, true); this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.goalSelector.addGoal(3, this.temptGoal); @@ -5325,7 +5077,7 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Chicken.class, false)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -256,7 +295,7 @@ public class Ocelot extends Animal { +@@ -254,7 +293,7 @@ public class Ocelot extends Animal { if (world.isUnobstructed(this) && !world.containsAnyLiquid(this.getBoundingBox())) { BlockPos blockposition = this.blockPosition(); @@ -5335,10 +5087,10 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983 } diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java -index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993ca49a01d 100644 +index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e13da79ba 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -115,6 +115,53 @@ public class Panda extends Animal { +@@ -120,6 +120,53 @@ public class Panda extends Animal { } @@ -5392,7 +5144,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 @Override public boolean canTakeItem(ItemStack stack) { EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(stack); -@@ -276,6 +323,7 @@ public class Panda extends Animal { +@@ -281,6 +328,7 @@ public class Panda extends Animal { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -5400,7 +5152,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 this.goalSelector.addGoal(2, new Panda.PandaPanicGoal(this, 2.0D)); this.goalSelector.addGoal(2, new Panda.PandaBreedGoal(this, 1.0D)); this.goalSelector.addGoal(3, new Panda.PandaAttackGoal(this, 1.2000000476837158D, true)); -@@ -291,6 +339,7 @@ public class Panda extends Animal { +@@ -298,6 +346,7 @@ public class Panda extends Animal { this.goalSelector.addGoal(12, new Panda.PandaRollGoal(this)); this.goalSelector.addGoal(13, new FollowParentGoal(this, 1.25D)); this.goalSelector.addGoal(14, new WaterAvoidingRandomStrollGoal(this, 1.0D)); @@ -5408,7 +5160,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); } -@@ -614,7 +663,10 @@ public class Panda extends Animal { +@@ -632,7 +681,10 @@ public class Panda extends Animal { public void setAttributes() { if (this.isWeak()) { @@ -5420,7 +5172,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 } if (this.isLazy()) { -@@ -637,7 +689,7 @@ public class Panda extends Animal { +@@ -655,7 +707,7 @@ public class Panda extends Animal { ItemStack itemstack = player.getItemInHand(hand); if (this.isScared()) { @@ -5429,7 +5181,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 } else if (this.isOnBack()) { this.setOnBack(false); return InteractionResult.sidedSuccess(this.level().isClientSide); -@@ -655,7 +707,7 @@ public class Panda extends Animal { +@@ -673,7 +725,7 @@ public class Panda extends Animal { this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying } else { if (this.level().isClientSide || this.isSitting() || this.isInWater()) { @@ -5438,7 +5190,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 } this.tryToSit(); -@@ -674,7 +726,7 @@ public class Panda extends Animal { +@@ -692,7 +744,7 @@ public class Panda extends Animal { return InteractionResult.SUCCESS; } else { @@ -5447,8 +5199,8 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 } } -@@ -719,7 +771,7 @@ public class Panda extends Animal { - return new Vector3f(0.0F, dimensions.height - (this.isBaby() ? 0.4375F : 0.0F) * scaleFactor, 0.0F); +@@ -737,7 +789,7 @@ public class Panda extends Animal { + return this.isBaby() ? Panda.BABY_DIMENSIONS : super.getDefaultDimensions(pose); } - private static class PandaMoveControl extends MoveControl { @@ -5456,7 +5208,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 private final Panda panda; -@@ -729,9 +781,9 @@ public class Panda extends Animal { +@@ -747,9 +799,9 @@ public class Panda extends Animal { } @Override @@ -5469,10 +5221,10 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993 } } diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java -index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e5dca147b 100644 +index 5ca96541abbb754f4d9fbe01f37ebaf19c532bbb..b8c69414b734eecb7412fab8ae6996712307da70 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java -@@ -131,12 +131,88 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, Level world) { super(type, world); @@ -5500,9 +5252,9 @@ index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e + } + this.moveControl = new ParrotMoveControl(this, 10, false); + // Purpur end - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); - this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F); - this.setPathfindingMalus(BlockPathTypes.COCOA, -1.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); + this.setPathfindingMalus(PathType.DAMAGE_FIRE, -1.0F); + this.setPathfindingMalus(PathType.COCOA, -1.0F); } + // Purpur start @@ -5561,8 +5313,8 @@ index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e + @Nullable @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { -@@ -155,8 +231,11 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { -@@ -308,13 +388,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder { @@ -155,6 +193,17 @@ public class Pig extends Animal implements ItemSteerable, Saddleable { public InteractionResult mobInteract(Player player, InteractionHand hand) { boolean flag = this.isFood(player.getItemInHand(hand)); @@ -5688,7 +5440,7 @@ index 24770540c51fe4831040d6b46b27636d25ebac40..10d6361077a74c5685eca72d12f99e33 if (!this.level().isClientSide) { player.startRiding(this); diff --git a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java -index c9e10d4ce00b711b30de5d346a5ac26e7b441390..2fecdd574b407eeb1d0cd4f1b34ff7931e620540 100644 +index c87a57e8ceac32a6c8a603aa24f8cb053610e47c..9b6e07b0de7328b18c5e526b89cfd48fdbc79753 100644 --- a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java +++ b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java @@ -59,11 +59,81 @@ public class PolarBear extends Animal implements NeutralMob { @@ -5824,10 +5576,10 @@ index c9e10d4ce00b711b30de5d346a5ac26e7b441390..2fecdd574b407eeb1d0cd4f1b34ff793 public float getStandingAnimationScale(float tickDelta) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java -index a197337f2e09f53cf382022569c8836745d78769..54f5206b686c3cf4d2e5b470c07047a518f5dd00 100644 +index 3f0fad476fe573c3ba946a9436d1b3f7c5260ee2..c758f759ccae81b7651bfcba254f54335f2c7cc8 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java +++ b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java -@@ -45,6 +45,33 @@ public class Pufferfish extends AbstractFish { +@@ -51,6 +51,33 @@ public class Pufferfish extends AbstractFish { this.refreshDimensions(); } @@ -5859,13 +5611,13 @@ index a197337f2e09f53cf382022569c8836745d78769..54f5206b686c3cf4d2e5b470c07047a5 + } + @Override - protected void defineSynchedData() { - super.defineSynchedData(); + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb55dcb825 100644 +index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f24ebbfd4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -@@ -87,6 +87,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -86,6 +86,7 @@ public class Rabbit extends Animal implements VariantHolder { private boolean wasOnGround; private int jumpDelayTicks; public int moreCarrotTicks; @@ -5873,7 +5625,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb public Rabbit(EntityType type, Level world) { super(type, world); -@@ -94,9 +95,75 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -93,9 +94,75 @@ public class Rabbit extends Animal implements VariantHolder { this.moveControl = new Rabbit.RabbitMoveControl(this); } @@ -5949,7 +5701,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level())); this.goalSelector.addGoal(1, new Rabbit.RabbitPanicGoal(this, 2.2D)); this.goalSelector.addGoal(2, new BreedGoal(this, 0.8D)); -@@ -111,6 +178,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -112,6 +179,14 @@ public class Rabbit extends Animal implements VariantHolder { @Override protected float getJumpPower() { @@ -5964,7 +5716,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb float f = 0.3F; if (this.horizontalCollision || this.moveControl.hasWanted() && this.moveControl.getWantedY() > this.getY() + 0.5D) { -@@ -135,7 +210,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -136,7 +211,7 @@ public class Rabbit extends Animal implements VariantHolder { } @Override @@ -5973,7 +5725,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb super.jumpFromGround(); double d0 = this.moveControl.getSpeedModifier(); -@@ -185,6 +260,13 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -186,6 +261,13 @@ public class Rabbit extends Animal implements VariantHolder { @Override public void customServerAiStep() { @@ -5987,7 +5739,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb if (this.jumpDelayTicks > 0) { --this.jumpDelayTicks; } -@@ -402,10 +484,23 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -399,10 +481,23 @@ public class Rabbit extends Animal implements VariantHolder { } this.setVariant(entityrabbit_variant); @@ -5998,7 +5750,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb + } + // Purpur end + - return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityNbt); + return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData); } private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor world, BlockPos pos) { @@ -6011,7 +5763,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb Holder holder = world.getBiome(pos); int i = world.getRandom().nextInt(100); -@@ -469,7 +564,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -466,7 +561,7 @@ public class Rabbit extends Animal implements VariantHolder { } } @@ -6020,7 +5772,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb private final Rabbit rabbit; private double nextJumpSpeed; -@@ -480,14 +575,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -477,14 +572,14 @@ public class Rabbit extends Animal implements VariantHolder { } @Override @@ -6037,7 +5789,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb } @Override -@@ -549,7 +644,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -546,7 +641,7 @@ public class Rabbit extends Animal implements VariantHolder { @Override public boolean canUse() { if (this.nextStartTick <= 0) { @@ -6085,10 +5837,10 @@ index 0af79daa357f53a8871e293b57e16c099e5d3f64..382e47f26ee94506cb76463a677351b9 public int getMaxSchoolSize() { return 5; diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java -index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108013b137e 100644 +index 0dfc2ccd8f454d0252542312661f65f41a6209ab..632562e3c27d11b73fdfb6b2f49c31edc761ed8d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java +++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java -@@ -119,10 +119,48 @@ public class Sheep extends Animal implements Shearable { +@@ -117,10 +117,48 @@ public class Sheep extends Animal implements Shearable { super(type, world); } @@ -6136,8 +5888,8 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108 + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.goalSelector.addGoal(1, new PanicGoal(this, 1.25D)); this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new TemptGoal(this, 1.1D, Ingredient.of(Items.WHEAT), false)); -@@ -254,7 +292,7 @@ public class Sheep extends Animal implements Shearable { + this.goalSelector.addGoal(3, new TemptGoal(this, 1.1D, (itemstack) -> { +@@ -259,7 +297,7 @@ public class Sheep extends Animal implements Shearable { if (!this.level().isClientSide && this.readyForShearing()) { // CraftBukkit start // Paper start - custom shear drops @@ -6146,7 +5898,7 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108 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 { +@@ -284,12 +322,13 @@ public class Sheep extends Animal implements Shearable { @Override public void shear(SoundSource shearedSoundCategory) { // Paper start - custom shear drops @@ -6163,13 +5915,13 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108 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 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028bac22031 100644 +index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..3b74931ae4e3a869d8db38c119e57b44af887859 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 +@@ -47,17 +47,56 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + private static final EntityDataAccessor DATA_PUMPKIN_ID = SynchedEntityData.defineId(SnowGolem.class, EntityDataSerializers.BYTE); private static final byte PUMPKIN_FLAG = 16; - private static final float EYE_HEIGHT = 1.7F; + @Nullable private java.util.UUID summoner; // Purpur public SnowGolem(EntityType type, Level world) { @@ -6224,7 +5976,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Mob.class, 10, true, false, (entityliving) -> { return entityliving instanceof Enemy; })); -@@ -79,6 +118,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -77,6 +116,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putBoolean("Pumpkin", this.hasPumpkin()); @@ -6232,7 +5984,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 } @Override -@@ -87,12 +127,13 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -85,12 +125,13 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM if (nbt.contains("Pumpkin")) { this.setPumpkin(nbt.getBoolean("Pumpkin")); } @@ -6247,7 +5999,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 } @Override -@@ -103,10 +144,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -101,10 +142,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM this.hurt(this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING } @@ -6260,7 +6012,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 BlockState iblockdata = Blocks.SNOW.defaultBlockState(); for (int i = 0; i < 4; ++i) { -@@ -154,11 +196,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -147,11 +189,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { // CraftBukkit start // Paper start - custom shear drops @@ -6274,7 +6026,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 } drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); } -@@ -173,19 +215,36 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM +@@ -164,19 +206,36 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM } return InteractionResult.sidedSuccess(this.level().isClientSide); @@ -6310,20 +6062,20 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028 + } + return java.util.Collections.unmodifiableList(list); + } -+ // Purpur end ++ // 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 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24370f750e 100644 +index 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..cb950ba3ee3bdfe0ff7acdb94c7ee233d73ab22e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Squid.java +++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java -@@ -44,13 +44,66 @@ public class Squid extends WaterAnimal { +@@ -42,13 +42,66 @@ public class Squid extends WaterAnimal { public Squid(EntityType type, Level world) { super(type, world); - //this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random -+ if (!world.purpurConfig.entitySharedRandom) this.random.setSeed((long) this.getId()); // Paper - Share random for entities to make them more random // Purpur ++ if (!world.purpurConfig.entitySharedRandom) this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random // Purpur this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } @@ -6386,7 +6138,7 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24 this.goalSelector.addGoal(1, new Squid.SquidFleeGoal()); } -@@ -119,6 +172,7 @@ public class Squid extends WaterAnimal { +@@ -117,6 +170,7 @@ public class Squid extends WaterAnimal { } if (this.isInWaterOrBubble()) { @@ -6394,7 +6146,7 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24 if (this.tentacleMovement < (float) Math.PI) { float f = this.tentacleMovement / (float) Math.PI; this.tentacleAngle = Mth.sin(f * f * (float) Math.PI) * (float) Math.PI * 0.25F; -@@ -292,10 +346,41 @@ public class Squid extends WaterAnimal { +@@ -290,10 +344,41 @@ public class Squid extends WaterAnimal { @Override public void tick() { @@ -6438,10 +6190,10 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24 float g = Mth.cos(f) * 0.2F; float h = -0.1F + this.squid.getRandom().nextFloat() * 0.2F; diff --git a/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java b/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java -index 6e9e86b6d547d7437c990b65718b95ad0d60f020..98205d89aa0cca82863257abfad46ab834385a20 100644 +index 3d03ffe2e12eca82dfa2f414471d12bb362d4552..2d04addd17d2c358fff598012b323cd7d8bf007e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java -@@ -65,6 +65,33 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder +@@ -67,6 +67,33 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder super(type, world); } @@ -6476,11 +6228,11 @@ index 6e9e86b6d547d7437c990b65718b95ad0d60f020..98205d89aa0cca82863257abfad46ab8 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 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924ee67383a8 100644 +index 30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84..01dc59695f295657b1cd7bb015558bfc2ce73b47 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 { - this.setMaxUpStep(1.0F); +@@ -87,6 +87,43 @@ public class Turtle extends Animal { + this.moveControl = new Turtle.TurtleMoveControl(this); } + // Purpur start @@ -6523,7 +6275,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e public void setHomePos(BlockPos pos) { this.entityData.set(Turtle.HOME_POS, pos.immutable()); // Paper - called with mutablepos... } -@@ -188,6 +225,7 @@ public class Turtle extends Animal { +@@ -189,6 +226,7 @@ public class Turtle extends Animal { @Override protected void registerGoals() { @@ -6531,8 +6283,8 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e 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)); -@@ -344,13 +382,15 @@ public class Turtle extends Animal { - return new Vector3f(0.0F, dimensions.height + (this.isBaby() ? 0.0F : 0.15625F) * scaleFactor, -0.25F * scaleFactor); +@@ -342,13 +380,15 @@ public class Turtle extends Animal { + return this.isBaby() ? Turtle.BABY_DIMENSIONS : super.getDefaultDimensions(pose); } - private static class TurtleMoveControl extends MoveControl { @@ -6548,7 +6300,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e } private void updateSpeed() { -@@ -370,7 +410,7 @@ public class Turtle extends Animal { +@@ -368,7 +408,7 @@ public class Turtle extends Animal { } @Override @@ -6557,7 +6309,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e this.updateSpeed(); if (this.operation == MoveControl.Operation.MOVE_TO && !this.turtle.getNavigation().isDone()) { double d0 = this.wantedX - this.turtle.getX(); -@@ -386,7 +426,7 @@ public class Turtle extends Animal { +@@ -384,7 +424,7 @@ public class Turtle extends Animal { this.turtle.setYRot(this.rotlerp(this.turtle.getYRot(), f, 90.0F)); this.turtle.yBodyRot = this.turtle.getYRot(); @@ -6567,63 +6319,27 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e 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/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java -index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e81d1a3b6 100644 +index b5ee82e5abfecc59e2362628f288b76881855f36..b12544d1280f39b6c365317a0f4965c8d65b6497 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java +++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java -@@ -10,6 +10,7 @@ import net.minecraft.network.syncher.EntityDataAccessor; - import net.minecraft.network.syncher.EntityDataSerializers; - import net.minecraft.network.syncher.SynchedEntityData; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvent; - import net.minecraft.sounds.SoundEvents; - import net.minecraft.tags.BlockTags; -@@ -17,9 +18,12 @@ import net.minecraft.util.Mth; - import net.minecraft.util.RandomSource; - import net.minecraft.util.TimeUtil; - import net.minecraft.util.valueproviders.UniformInt; -+import net.minecraft.world.DifficultyInstance; +@@ -30,6 +30,8 @@ import net.minecraft.world.DifficultyInstance; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.AgeableMob; + import net.minecraft.world.entity.Crackiness; import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityDimensions; -@@ -29,6 +33,7 @@ import net.minecraft.world.entity.Mob; - import net.minecraft.world.entity.MobSpawnType; - import net.minecraft.world.entity.NeutralMob; - import net.minecraft.world.entity.Pose; -+import net.minecraft.world.entity.SpawnGroupData; - import net.minecraft.world.entity.TamableAnimal; - import net.minecraft.world.entity.ai.attributes.AttributeSupplier; - import net.minecraft.world.entity.ai.attributes.Attributes; -@@ -37,6 +42,7 @@ import net.minecraft.world.entity.ai.goal.BegGoal; - import net.minecraft.world.entity.ai.goal.BreedGoal; - import net.minecraft.world.entity.ai.goal.FloatGoal; - import net.minecraft.world.entity.ai.goal.FollowOwnerGoal; -+import net.minecraft.world.entity.ai.goal.Goal; - import net.minecraft.world.entity.ai.goal.LeapAtTargetGoal; - import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; - import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; -@@ -64,6 +70,7 @@ import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelAccessor; -+import net.minecraft.world.level.ServerLevelAccessor; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.pathfinder.BlockPathTypes; -@@ -86,6 +93,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -104,6 +106,37 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder RABID_PREDICATE = entity -> entity instanceof ServerPlayer || entity instanceof Mob; -+ private final Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR); -+ private final Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE); ++ private static final Predicate RABID_PREDICATE = entity -> entity instanceof net.minecraft.server.level.ServerPlayer || entity instanceof Mob; ++ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR); ++ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE); + private static final class AvoidRabidWolfGoal extends AvoidEntityGoal { + private final Wolf wolf; + @@ -6651,10 +6367,10 @@ index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e + } + // Purpur end private static final float START_HEALTH = 8.0F; - private static final float TAME_HEALTH = 20.0F; - private float interestedAngle; -@@ -105,12 +143,93 @@ public class Wolf extends TamableAnimal implements NeutralMob { - this.setPathfindingMalus(BlockPathTypes.DANGER_POWDER_SNOW, -1.0F); + private static final float TAME_HEALTH = 40.0F; + private static final float ARMOR_REPAIR_UNIT = 0.125F; +@@ -124,12 +157,86 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.wolfNaturalRabid; -+ this.updatePathfinders(false); -+ return super.finalizeSpawn(world, difficulty, type, data, nbt); -+ } -+ -+ @Override + public void tame(Player player) { + setCollarColor(level().purpurConfig.wolfDefaultCollarColor); + super.tame(player); @@ -6740,14 +6449,14 @@ index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e protected void registerGoals() { this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.goalSelector.addGoal(1, new Wolf.WolfPanicGoal(1.5D)); + this.goalSelector.addGoal(1, new Wolf.WolfPanicGoal(this, 1.5D)); this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this)); this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5D, 1.5D)); + this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F)); this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true)); this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false)); -@@ -119,11 +238,12 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -138,11 +245,12 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false)); this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true)); -@@ -150,6 +270,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -185,6 +293,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.wolfNaturalRabid; ++ this.updatePathfinders(false); ++ // Purpur end ++ + return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData); + } + +@@ -261,6 +380,11 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder brainProvider() { return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); -@@ -224,7 +259,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS +@@ -218,7 +253,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { @@ -6888,47 +6610,28 @@ index c521ff04be40bfa892021f67acc1b324551fcd5e..eb60d2d99155aae4a761051175fbbddf this.getBrain().tick((ServerLevel) this.level(), this); AllayAi.updateActivity(this); super.customServerAiStep(); -@@ -367,9 +402,31 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS - - @Override - public boolean wantsToPickUp(ItemStack stack) { -- ItemStack itemstack1 = this.getItemInHand(InteractionHand.MAIN_HAND); -- -- return !itemstack1.isEmpty() && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.inventory.canAddItem(stack) && this.allayConsidersItemEqual(itemstack1, stack); -+ // Purpur start -+ if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ return false; -+ } -+ ItemStack itemStack = this.getItemInHand(InteractionHand.MAIN_HAND); -+ if (itemStack.isEmpty()) { -+ return false; -+ } -+ if (!allayConsidersItemEqual(itemStack, stack)) { -+ return false; -+ } -+ if (!this.inventory.canAddItem(stack)) { -+ return false; -+ } -+ for (String tag : this.level().purpurConfig.allayRespectNBT) { -+ if (stack.hasTag() && itemStack.hasTag()) { -+ Tag tag1 = stack.getTag().get(tag); -+ Tag tag2 = itemStack.getTag().get(tag); -+ if (!Objects.equals(tag1, tag2)) { -+ return false; -+ } -+ } -+ } -+ return true; -+ // Purpur end +diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +index 6a3b119bdcac4de1b39216b23ba8dceae062d278..063dde771ade593a29481f14b8f44a0f72f15953 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java ++++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +@@ -465,4 +465,11 @@ public class Armadillo extends Animal { + return this.animationDuration; + } } - - private boolean allayConsidersItemEqual(ItemStack stack, ItemStack stack2) { ++ ++ // Purpur start ++ @Override ++ public int getPurpurBreedTime() { ++ return 6000; ++ } ++ // Purpur end + } 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 d0c624a6a000c2a41e41d14dd785a7bf9612afe8..bcc49ca8afa9794952883098a586d0e1b89d04d5 100644 +index d339e9c0b81a50d20048375bd8b4141618fc1d2a..3409b0eaf9f09a92846359ca58ecda7deb17c099 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; -@@ -278,7 +315,7 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { +@@ -103,6 +103,8 @@ public class Frog extends Animal implements VariantHolder> { public final AnimationState croakAnimationState = new AnimationState(); public final AnimationState tongueAnimationState = new AnimationState(); public final AnimationState swimIdleAnimationState = new AnimationState(); @@ -7074,10 +6777,10 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1 public Frog(EntityType type, Level world) { super(type, world); - this.lookControl = new Frog.FrogLookControl(this); - this.setPathfindingMalus(BlockPathTypes.WATER, 4.0F); - this.setPathfindingMalus(BlockPathTypes.TRAPDOOR, -1.0F); -- this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); +@@ -110,6 +112,58 @@ public class Frog extends Animal implements VariantHolder> { + this.setPathfindingMalus(PathType.WATER, 4.0F); + this.setPathfindingMalus(PathType.TRAPDOOR, -1.0F); + this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); + // Purpur start + this.purpurLandController = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.2F); + this.purpurWaterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(this, 0.5F); @@ -7098,9 +6801,8 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1 + } + }; + // Purpur end - this.setMaxUpStep(1.0F); - } - ++ } ++ + // Purpur start + @Override + public boolean isRidable() { @@ -7131,12 +6833,10 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1 + + public int getPurpurBreedTime() { + return this.level().purpurConfig.frogBreedingTicks; -+ } -+ + } + @Override - protected Brain.Provider brainProvider() { - return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -186,7 +239,7 @@ public class Frog extends Animal implements VariantHolder { +@@ -184,7 +238,7 @@ public class Frog extends Animal implements VariantHolder> { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { @@ -7145,20 +6845,20 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1 this.getBrain().tick((ServerLevel)this.level(), this); FrogAi.updateActivity(this); super.customServerAiStep(); -@@ -372,7 +425,7 @@ public class Frog extends Animal implements VariantHolder { +@@ -369,7 +423,7 @@ public class Frog extends Animal implements VariantHolder> { return world.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } - class FrogLookControl extends LookControl { + class FrogLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - FrogLookControl(Mob entity) { + FrogLookControl(final Mob entity) { 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 257687004b03e17cf3f5c0ea4c4cfeb7f34033e4..93e321a0b8fdce12968f03b3cfe6724ae564b823 100644 +index 40dad395aabb04c21ac26fadce823ce8b4f79b3a..e6861fd5f9817ec54294976f0e93952baa387773 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 -@@ -48,13 +48,50 @@ public class Tadpole extends AbstractFish { +@@ -51,13 +51,50 @@ public class Tadpole extends AbstractFish { protected static final ImmutableList>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.FROG_TEMPTATIONS); protected static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.BREED_TARGET, MemoryModuleType.IS_PANICKING); public boolean ageLocked; // Paper @@ -7210,22 +6910,20 @@ index 257687004b03e17cf3f5c0ea4c4cfeb7f34033e4..93e321a0b8fdce12968f03b3cfe6724a @Override protected PathNavigation createNavigation(Level world) { return new WaterBoundPathNavigation(this, world); -@@ -83,8 +120,8 @@ public class Tadpole extends AbstractFish { +@@ -86,7 +123,7 @@ public class Tadpole extends AbstractFish { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -- this.getBrain().tick((ServerLevel) this.level(), this); + 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); // Dreeam TODO - should remove this? + this.getBrain().tick((ServerLevel) this.level(), this); TadpoleAi.updateActivity(this); super.customServerAiStep(); - } diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9e303be4a 100644 +index 1bf1e2714f210188202a97219765428f9cf2c956..65d01a9c1b2d66446eb08a4a2bcdbe8284ce9e43 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -92,6 +92,38 @@ public class Goat extends Animal { +@@ -91,6 +91,38 @@ public class Goat extends Animal { return InstrumentItem.create(Items.GOAT_HORN, (Holder) holderset.getRandomElement(randomsource).get()); } @@ -7264,7 +6962,7 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9 @Override protected Brain.Provider brainProvider() { return Brain.provider(Goat.MEMORY_TYPES, Goat.SENSOR_TYPES); -@@ -194,7 +226,7 @@ public class Goat extends Animal { +@@ -193,7 +225,7 @@ public class Goat extends Animal { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { @@ -7273,7 +6971,7 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9 this.getBrain().tick((ServerLevel) this.level(), this); GoatAi.updateActivity(this); super.customServerAiStep(); -@@ -393,6 +425,7 @@ public class Goat extends Animal { +@@ -392,6 +424,7 @@ public class Goat extends Animal { // Paper start - Goat ram API public void ram(net.minecraft.world.entity.LivingEntity entity) { @@ -7282,16 +6980,15 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9 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 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac330644a0f 100644 +index 9357cf0179d19fbdfe76413e909a99b924c85780..59829fb7342696d29aa709d392f89bf263257fd3 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, +@@ -217,11 +217,59 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, protected AbstractHorse(EntityType type, Level world) { super(type, world); + this.moveControl = new net.minecraft.world.entity.ai.control.MoveControl(this); // Purpur - use vanilla controller + this.lookControl = new net.minecraft.world.entity.ai.control.LookControl(this); // Purpur - use vanilla controller - this.setMaxUpStep(1.0F); this.createInventory(); } @@ -7346,7 +7043,7 @@ index 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac3 this.goalSelector.addGoal(1, new PanicGoal(this, 1.2D)); this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2D)); this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D, AbstractHorse.class)); -@@ -165,6 +213,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -232,6 +280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, if (this.canPerformRearing()) { this.goalSelector.addGoal(9, new RandomStandGoal(this)); } @@ -7354,26 +7051,17 @@ index 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac3 this.addBehaviourGoals(); } -@@ -337,7 +386,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, - - @Override - protected int calculateFallDamage(float fallDistance, float damageMultiplier) { -- return Mth.ceil((fallDistance * 0.5F - 3.0F) * damageMultiplier); -+ return Mth.ceil((fallDistance * 0.5F - this.safeFallDistance) * damageMultiplier); - } - - protected int getInventorySize() { -@@ -1231,7 +1280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -1249,7 +1298,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, entityData = new AgeableMob.AgeableMobGroupData(0.2F); } - this.randomizeAttributes(world.getRandom()); + // this.randomizeAttributes(world.getRandom()); // Purpur - replaced by initAttributes() - return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityNbt); + return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData); } diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java -index 8c14f9f2ad383f87c498126f135b460a241da410..42efd14b59a2b7da3409895bdff49e83b6cb2fa5 100644 +index ff02169ba14f5264cea8beaf1779e2890c5d74b8..94021abe521aea4a70f5eaa78fb05f9f71b7c38c 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java @@ -15,6 +15,43 @@ public class Donkey extends AbstractChestedHorse { @@ -7421,10 +7109,10 @@ index 8c14f9f2ad383f87c498126f135b460a241da410..42efd14b59a2b7da3409895bdff49e83 protected SoundEvent getAmbientSound() { return SoundEvents.DONKEY_AMBIENT; diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java -index 2181d74ad955197eb4f1925a64914a6197fa9023..eab6efcae632a393924d7245a71c40b57c6e316d 100644 +index 6e299770fca78699f7e1988db4cdef37b99d74c1..fdf9ec418b0fc567e286ac79dbdbeddac568ad67 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java -@@ -40,6 +40,43 @@ public class Horse extends AbstractHorse implements VariantHolder { +@@ -44,6 +44,43 @@ public class Horse extends AbstractHorse implements VariantHolder { super(type, world); } @@ -7469,7 +7157,7 @@ index 2181d74ad955197eb4f1925a64914a6197fa9023..eab6efcae632a393924d7245a71c40b5 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 6623674136b0f865d5b3d7a10d3bf05793b82f87..22abcf70f51a6752ab6d3f421366adb196e50dfc 100644 +index 1dd4290287725898ace29e46b439b55df8fdd1af..7d2a5c806fd0f1228c45b8a8b56d7ba13b899a2d 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 0 && this.level().getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level().purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur + } + -+ // Purpur start ++ // Purpur start + if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) { + return; // on cooldown + } @@ -7991,12 +7676,11 @@ index 036640d49a5e891e9a0f767abe33f1f51d6d4cde..fcca438db945c1c7327cf3a979de01f0 + phantomBeamTicks = 0; + phantomDamageCooldown = 0; + idleCooldown = 60; - } + // Purpur end + } @Override - protected void addAdditionalSaveData(CompoundTag nbt) { -@@ -124,16 +190,18 @@ public class EndCrystal extends Entity { +@@ -121,16 +187,18 @@ public class EndCrystal extends Entity { } // CraftBukkit end if (!source.is(DamageTypeTags.IS_EXPLOSION)) { @@ -8018,10 +7702,10 @@ index 036640d49a5e891e9a0f767abe33f1f51d6d4cde..fcca438db945c1c7327cf3a979de01f0 this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a77996018e589807 100644 +index 6f14607a88761171a72e274b3c9b476b20a272f1..3da1f7a6e443954e4976dd59391ea19b9c903cf7 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -108,6 +108,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -106,6 +106,7 @@ public class EnderDragon extends Mob implements Enemy { @Nullable private BlockPos podium; // Paper end - Allow changing the EnderDragon podium @@ -8029,7 +7713,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 public EnderDragon(EntityType entitytypes, Level world) { super(EntityType.ENDER_DRAGON, world); -@@ -130,6 +131,37 @@ public class EnderDragon extends Mob implements Enemy { +@@ -128,6 +129,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, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE); // CraftBukkit @@ -8067,7 +7751,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 } public void setDragonFight(EndDragonFight fight) { -@@ -144,6 +176,27 @@ public class EnderDragon extends Mob implements Enemy { +@@ -142,6 +174,27 @@ public class EnderDragon extends Mob implements Enemy { return this.fightOrigin; } @@ -8095,7 +7779,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D); } -@@ -205,6 +258,37 @@ public class EnderDragon extends Mob implements Enemy { +@@ -203,6 +256,37 @@ public class EnderDragon extends Mob implements Enemy { @Override public void aiStep() { @@ -8133,7 +7817,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 this.processFlappingMovement(); if (this.level().isClientSide) { this.setHealth(this.getHealth()); -@@ -231,6 +315,8 @@ public class EnderDragon extends Mob implements Enemy { +@@ -229,6 +313,8 @@ public class EnderDragon extends Mob implements Enemy { float f; if (this.isDeadOrDying()) { @@ -8142,7 +7826,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 float f1 = (this.random.nextFloat() - 0.5F) * 8.0F; f = (this.random.nextFloat() - 0.5F) * 4.0F; -@@ -243,9 +329,9 @@ public class EnderDragon extends Mob implements Enemy { +@@ -241,9 +327,9 @@ public class EnderDragon extends Mob implements Enemy { f = 0.2F / ((float) vec3d.horizontalDistance() * 10.0F + 1.0F); f *= (float) Math.pow(2.0D, vec3d.y); @@ -8154,7 +7838,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 this.flapTime += f * 0.5F; } else { this.flapTime += f; -@@ -279,7 +365,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -277,7 +363,7 @@ public class EnderDragon extends Mob implements Enemy { } this.phaseManager.getCurrentPhase().doClientTick(); @@ -8163,7 +7847,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 DragonPhaseInstance idragoncontroller = this.phaseManager.getCurrentPhase(); idragoncontroller.doServerTick(); -@@ -348,7 +434,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -346,7 +432,7 @@ public class EnderDragon extends Mob implements Enemy { this.tickPart(this.body, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F)); this.tickPart(this.wing1, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F)); this.tickPart(this.wing2, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F)); @@ -8172,7 +7856,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 this.knockBack(this.level().getEntities((Entity) this, this.wing1.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); this.knockBack(this.level().getEntities((Entity) this, this.wing2.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); this.hurt(this.level().getEntities((Entity) this, this.head.getBoundingBox().inflate(1.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); -@@ -392,7 +478,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -390,7 +476,7 @@ public class EnderDragon extends Mob implements Enemy { } if (!this.level().isClientSide) { @@ -8181,7 +7865,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 if (this.dragonFight != null) { this.dragonFight.updateDragon(this); } -@@ -524,7 +610,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -522,7 +608,7 @@ public class EnderDragon extends Mob implements Enemy { BlockState iblockdata = this.level().getBlockState(blockposition); if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) { @@ -8190,7 +7874,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 // CraftBukkit start - Add blocks to list rather than destroying them // flag1 = this.level().removeBlock(blockposition, false) || flag1; flag1 = true; -@@ -668,7 +754,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -666,7 +752,7 @@ public class EnderDragon extends Mob implements Enemy { boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT); short short0 = 500; @@ -8199,7 +7883,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 short0 = 12000; } -@@ -1104,6 +1190,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -1102,6 +1188,7 @@ public class EnderDragon extends Mob implements Enemy { @Override protected boolean canRide(Entity entity) { @@ -8208,11 +7892,11 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601 } 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 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad22c3447f 100644 +index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb85146398403 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 -@@ -85,20 +85,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob - return entityliving.getMobType() != MobType.UNDEAD && entityliving.attackable(); +@@ -88,20 +88,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob + return !entityliving.getType().is(EntityTypeTags.WITHER_FRIENDS) && entityliving.attackable(); }; private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR); + @Nullable private java.util.UUID summoner; // Purpur @@ -8272,7 +7956,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad @Override protected PathNavigation createNavigation(Level world) { FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, world); -@@ -109,13 +148,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -112,13 +151,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob return navigationflying; } @@ -8386,7 +8070,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, WitherBoss.LIVING_ENTITY_SELECTOR)); } -@@ -133,6 +272,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -136,6 +275,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putInt("Invul", this.getInvulnerableTicks()); @@ -8394,7 +8078,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } @Override -@@ -142,6 +282,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -145,6 +285,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.hasCustomName()) { this.bossEvent.setName(this.getDisplayName()); } @@ -8402,7 +8086,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } -@@ -257,6 +398,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -263,6 +404,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected void customServerAiStep() { @@ -8419,7 +8103,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad int i; if (this.getInvulnerableTicks() > 0) { -@@ -273,7 +424,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -279,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } // CraftBukkit end @@ -8428,7 +8112,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad // 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; -@@ -298,7 +449,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) { @@ -8437,15 +8121,15 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } } else { -@@ -358,7 +509,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; - if (this.destroyBlocksTick == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { + if (this.destroyBlocksTick == 0 && (this.level().purpurConfig.witherBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur - i = Mth.floor(this.getY()); - j = Mth.floor(this.getX()); - int i1 = Mth.floor(this.getZ()); + boolean flag = false; + + j = Mth.floor(this.getBbWidth() / 2.0F + 1.0F); @@ -391,8 +542,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } } @@ -8459,7 +8143,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -578,11 +731,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -580,11 +733,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } public int getAlternativeTarget(int headIndex) { @@ -8473,7 +8157,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } @Override -@@ -597,6 +750,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -594,6 +747,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected boolean canRide(Entity entity) { @@ -8482,10 +8166,10 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad } 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 eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae08143f4d 100644 +index c2bd2e303f956d390319f6bbbe9a6492ebec5154..6697cd8a632becd72ee132007a61d1221e817abf 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -100,10 +100,12 @@ public class ArmorStand extends LivingEntity { +@@ -103,10 +103,12 @@ public class ArmorStand extends LivingEntity { private boolean noTickPoseDirty = false; private boolean noTickEquipmentDirty = false; // Paper end - Allow ArmorStands not to tick @@ -8498,32 +8182,31 @@ index eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY); this.headPose = ArmorStand.DEFAULT_HEAD_POSE; -@@ -113,6 +115,7 @@ public class ArmorStand extends LivingEntity { +@@ -115,6 +117,7 @@ public class ArmorStand extends LivingEntity { + this.rightArmPose = ArmorStand.DEFAULT_RIGHT_ARM_POSE; this.leftLegPose = ArmorStand.DEFAULT_LEFT_LEG_POSE; this.rightLegPose = ArmorStand.DEFAULT_RIGHT_LEG_POSE; - this.setMaxUpStep(0.0F); + this.setShowArms(world != null && world.purpurConfig.armorstandPlaceWithArms); // Purpur } public ArmorStand(Level world, double x, double y, double z) { -@@ -607,7 +610,7 @@ public class ArmorStand extends LivingEntity { +@@ -613,6 +616,7 @@ public class ArmorStand extends LivingEntity { private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper ItemStack itemstack = new ItemStack(Items.ARMOR_STAND); -- if (this.hasCustomName()) { -+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { // Purpur - itemstack.setHoverName(this.getCustomName()); - } - -@@ -678,6 +681,7 @@ public class ArmorStand extends LivingEntity { ++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames) + itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName()); + this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior + return this.brokenByAnything(damageSource); // Paper +@@ -676,6 +680,7 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { -+ maxUpStep = level().purpurConfig.armorstandStepHeight; // Purpur ++ maxUpStep = level().purpurConfig.armorstandStepHeight; // Paper start - Allow ArmorStands not to tick if (!this.canTick) { if (this.noTickPoseDirty) { -@@ -1005,4 +1009,18 @@ public class ArmorStand extends LivingEntity { +@@ -1003,4 +1008,18 @@ public class ArmorStand extends LivingEntity { } } // Paper end @@ -8543,18 +8226,18 @@ index eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae + // 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 c34701f95580e4cf45fe086115563127432a28c5..2363d9eaad655389c7b7d67d545ef8025f550431 100644 +index da0d1c9a1c4ae081bff9ca4230c9a1503885c354..9af8fcf6abb9b768829592bc1b091ebe4599ed2e 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -268,7 +268,13 @@ public class ItemFrame extends HangingEntity { +@@ -262,7 +262,13 @@ public class ItemFrame extends HangingEntity { } if (alwaysDrop) { - this.spawnAtLocation(this.getFrameItemStack()); + // Purpur start + final ItemStack itemFrame = this.getFrameItemStack(); -+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { -+ itemFrame.setHoverName(this.getCustomName()); ++ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) { ++ itemFrame.set(DataComponents.CUSTOM_NAME, null); + } + this.spawnAtLocation(itemFrame); + // Purpur end @@ -8562,27 +8245,18 @@ index c34701f95580e4cf45fe086115563127432a28c5..2363d9eaad655389c7b7d67d545ef802 if (!itemstack.isEmpty()) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/Painting.java b/src/main/java/net/minecraft/world/entity/decoration/Painting.java -index fee2269b241cbfb10bbbb76b404aa5ef3997dfe0..af07901daaf6a0e5cd7e4b1e07fb491566807932 100644 +index 40e7112669abb58a0ab6df1846afec3979e95e55..183464f202d4c2774840edfde1dfcab44d05d0d3 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/Painting.java +++ b/src/main/java/net/minecraft/world/entity/decoration/Painting.java -@@ -120,7 +120,7 @@ public class Painting extends HangingEntity implements VariantHolder holder = loadVariant(nbt).orElseGet(Painting::getDefaultVariant); -+ Holder holder = loadVariant(nbt).orElseGet(() -> (Holder.Reference) getDefaultVariant()); // Purpur - decompile error TODO: still needed? - this.setVariant(holder); - this.direction = Direction.from2DDataValue(nbt.getByte("facing")); - super.readAdditionalSaveData(nbt); -@@ -155,7 +155,13 @@ public class Painting extends HangingEntity implements VariantHolder type, Level world) { super(type, world); -@@ -393,7 +399,16 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -399,7 +405,16 @@ public class ItemEntity extends Entity implements TraceableEntity { @Override public boolean hurt(DamageSource source, float amount) { @@ -8624,7 +8298,7 @@ index 293bc6e40fec09a8ec5cac901d52cc3f7e9b9ea3..6a94e28cda9319b3a965f07d758083b5 return false; } else if (!this.getItem().isEmpty() && this.getItem().is(Items.NETHER_STAR) && source.is(DamageTypeTags.IS_EXPLOSION)) { return false; -@@ -596,6 +611,12 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -607,6 +622,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 - Alternative item-despawn-rate @@ -8638,10 +8312,10 @@ index 293bc6e40fec09a8ec5cac901d52cc3f7e9b9ea3..6a94e28cda9319b3a965f07d758083b5 @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 e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5c52026e2 100644 +index f1f352ec0e51f5db59254841a06c176c5a876fc9..dff0e7b08b973a1b29f916e63d3e4778d6c56cdc 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -200,4 +200,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -193,4 +193,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); } // Paper end - Option to prevent TNT from moving in water @@ -8658,7 +8332,7 @@ index e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5 + new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.TNT)); + tntItem.setPickUpDelay(10); + -+ inHand.hurtAndBreak(1, player, entity -> entity.broadcastBreakEvent(hand)); ++ inHand.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); + level().addFreshEntity(tntItem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CUSTOM); + + this.playSound(net.minecraft.sounds.SoundEvents.SHEEP_SHEAR); @@ -8672,10 +8346,10 @@ index e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5 + // 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 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e564d9e568 100644 +index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf54a8ff96b 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 +@@ -65,16 +65,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo protected AbstractSkeleton(EntityType type, Level world) { super(type, world); this.reassessWeaponGoal(); @@ -8695,8 +8369,8 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5 this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); -@@ -99,35 +102,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - } +@@ -93,35 +96,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + abstract SoundEvent getStepSound(); // Paper start - shouldBurnInDay API - private boolean shouldBurnInDay = true; @@ -8725,7 +8399,7 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5 - } - - if (flag) { -- this.setSecondsOnFire(8); +- this.igniteForSeconds(8); - } - } - @@ -8761,19 +8435,19 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5 // Paper end - shouldBurnInDay API diff --git a/src/main/java/net/minecraft/world/entity/monster/Blaze.java b/src/main/java/net/minecraft/world/entity/monster/Blaze.java -index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed750c3b916 100644 +index aee2fa184bc5723dfd3d54f460a173982d874c8b..27db17e19dd95e99f7bd67747eba3c3072b48ed5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Blaze.java +++ b/src/main/java/net/minecraft/world/entity/monster/Blaze.java @@ -32,26 +32,73 @@ public class Blaze extends Monster { public Blaze(EntityType type, Level world) { super(type, world); -- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); +- this.setPathfindingMalus(PathType.WATER, -1.0F); + this.moveControl = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.3F); // Purpur -+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur - this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F); - this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F); ++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur + this.setPathfindingMalus(PathType.LAVA, 8.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F); + this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); this.xpReward = 10; } @@ -8836,11 +8510,11 @@ index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed7 public static AttributeSupplier.Builder createAttributes() { - return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0); -+ return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0).add(Attributes.FLYING_SPEED, 0.6); // Purpur ++ return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur } @Override -@@ -111,11 +158,19 @@ public class Blaze extends Monster { +@@ -111,11 +158,18 @@ public class Blaze extends Monster { @Override public boolean isSensitiveToWater() { @@ -8857,15 +8531,27 @@ index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed7 + return; + } + // Purpur end -+ this.nextHeightOffsetChangeTick--; if (this.nextHeightOffsetChangeTick <= 0) { this.nextHeightOffsetChangeTick = 100; +diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java +index 754eb747179d9318bc5a3883e5622cc400c4e06c..4e929539cb093d58f3311d5f6a62bd1aeb71cfb0 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java +@@ -155,7 +155,7 @@ public class Bogged extends AbstractSkeleton implements Shearable { + + // Paper start - shear drops API + @Override +- public java.util.List generateDefaultDrops() { ++ public java.util.List generateDefaultDrops(int looting) { // Purpur + final java.util.List drops = new java.util.ArrayList<>(); + this.generateShearedMushrooms(drops::add); + return drops; diff --git a/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java b/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java -index 70d25bb45ad603095a1f5812cc396dfc5f16a1e1..c9bd400473166999479f5eef1edad529d3aafe01 100644 +index 87e4b300ac248f6c13d9b4a8f24fd78b24b565b4..43b5a0e7993ae9daef1c1ea67722347f9851d3a9 100644 --- a/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java +++ b/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java -@@ -29,6 +29,38 @@ public class CaveSpider extends Spider { +@@ -26,6 +26,38 @@ public class CaveSpider extends Spider { return Spider.createAttributes().add(Attributes.MAX_HEALTH, 12.0D); } @@ -8905,13 +8591,13 @@ 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 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980a5b2c627 100644 +index cbcb2bfa8f91099e5c374f590f48885390bdf7a7..1829bedfa8084c4932a0e67c36f48f19993e22b6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -60,21 +60,99 @@ public class Creeper extends Monster implements PowerableMob { - public int maxSwell = 30; +@@ -61,21 +61,99 @@ public class Creeper extends Monster implements PowerableMob { public int explosionRadius = 3; private int droppedSkulls; + private Player entityIgniter; // CraftBukkit + // Purpur start + private int spacebarCharge = 0; + private int prevSpacebarCharge = 0; @@ -9008,7 +8694,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); } -@@ -174,6 +252,37 @@ public class Creeper extends Monster implements PowerableMob { +@@ -175,6 +253,37 @@ public class Creeper extends Monster implements PowerableMob { } } @@ -9017,12 +8703,12 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.creeperMaxHealth); + } + -+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { ++ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData) { + double chance = world.getLevel().purpurConfig.creeperChargedChance; + if (chance > 0D && random.nextDouble() <= chance) { + setPowered(true); + } -+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); ++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData); + } + + @Override @@ -9046,7 +8732,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 @Override protected SoundEvent getHurtSound(DamageSource source) { return SoundEvents.CREEPER_HURT; -@@ -265,15 +374,17 @@ public class Creeper extends Monster implements PowerableMob { +@@ -263,15 +372,17 @@ public class Creeper extends Monster implements PowerableMob { } public void explodeCreeper() { @@ -9061,12 +8747,12 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 if (!event.isCancelled()) { // CraftBukkit end this.dead = true; -- this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit -+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), this.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Purpur +- this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API ++ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), this.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Paper - fix DamageSource API // Purpur this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause this.spawnLingeringCloud(); // CraftBukkit start -@@ -283,7 +394,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -281,7 +392,7 @@ public class Creeper extends Monster implements PowerableMob { } // CraftBukkit end } @@ -9075,7 +8761,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 } private void spawnLingeringCloud() { -@@ -325,6 +436,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -323,6 +434,7 @@ public class Creeper extends Monster implements PowerableMob { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited()); @@ -9084,7 +8770,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980 } // Paper end - CreeperIgniteEvent 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 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bffb76c8e62 100644 +index cff1b5e0e3fd32d82157d5f13d83d4abdfad7378..15afee3c4f6307557321424560d2340e23cd472b 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; @@ -9095,8 +8781,8 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; -@@ -68,6 +69,58 @@ public class Drowned extends Zombie implements RangedAttackMob { - this.groundNavigation = new GroundPathNavigation(this, world); +@@ -71,6 +72,58 @@ public class Drowned extends Zombie implements RangedAttackMob { + return Zombie.createAttributes().add(Attributes.STEP_HEIGHT, 1.0D); } + // Purpur start @@ -9154,7 +8840,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff @Override protected void addBehaviourGoals() { this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0D)); -@@ -75,10 +128,23 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -78,10 +131,23 @@ public class Drowned extends Zombie implements RangedAttackMob { this.goalSelector.addGoal(2, new Drowned.DrownedAttackGoal(this, 1.0D, false)); this.goalSelector.addGoal(5, new Drowned.DrownedGoToBeachGoal(this, 1.0D)); this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0D, this.level().getSeaLevel())); @@ -9179,7 +8865,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false)); this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); -@@ -112,7 +178,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -115,7 +181,7 @@ public class Drowned extends Zombie implements RangedAttackMob { @Override public boolean supportsBreakDoorGoal() { @@ -9188,7 +8874,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff } @Override -@@ -259,8 +325,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -262,8 +328,7 @@ public class Drowned extends Zombie implements RangedAttackMob { this.searchingForLand = targetingUnderwater; } @@ -9198,7 +8884,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff private final Drowned drowned; public DrownedMoveControl(Drowned drowned) { -@@ -269,7 +334,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -272,7 +337,7 @@ public class Drowned extends Zombie implements RangedAttackMob { } @Override @@ -9207,7 +8893,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff LivingEntity entityliving = this.drowned.getTarget(); if (this.drowned.wantsToSwim() && this.drowned.isInWater()) { -@@ -292,7 +357,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -295,7 +360,7 @@ public class Drowned extends Zombie implements RangedAttackMob { this.drowned.setYRot(this.rotlerp(this.drowned.getYRot(), f, 90.0F)); this.drowned.yBodyRot = this.drowned.getYRot(); @@ -9216,7 +8902,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff float f2 = Mth.lerp(0.125F, this.drowned.getSpeed(), f1); this.drowned.setSpeed(f2); -@@ -302,7 +367,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -305,7 +370,7 @@ public class Drowned extends Zombie implements RangedAttackMob { this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add(0.0D, -0.008D, 0.0D)); } @@ -9226,10 +8912,10 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff } diff --git a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java -index 91ff663b2260d1cdd1388c93068e4cd9d0331aea..cb189457305916f509d624beb303feff35d0c358 100644 +index fd995b1f29c47884e9db2cb92f1dd615d62ae032..7e8603ef5df722f19e85b9c5cdd4ebfdd6481e42 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java -@@ -36,6 +36,33 @@ public class ElderGuardian extends Guardian { +@@ -33,6 +33,33 @@ public class ElderGuardian extends Guardian { } @@ -9264,15 +8950,15 @@ index 91ff663b2260d1cdd1388c93068e4cd9d0331aea..cb189457305916f509d624beb303feff 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 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47ac53dfe7 100644 +index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d39d7e9622 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 { +@@ -90,12 +90,40 @@ public class EnderMan extends Monster implements NeutralMob { + public EnderMan(EntityType type, Level world) { super(type, world); - this.setMaxUpStep(1.0F); -- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); -+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur +- this.setPathfindingMalus(PathType.WATER, -1.0F); ++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur + } + + // Purpur start @@ -9309,7 +8995,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 this.goalSelector.addGoal(1, new EnderMan.EndermanFreezeWhenLookedAt(this)); this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D, 0.0F)); -@@ -108,9 +136,10 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -103,9 +131,10 @@ public class EnderMan extends Monster implements NeutralMob { this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); this.goalSelector.addGoal(10, new EnderMan.EndermanLeaveBlockGoal(this)); this.goalSelector.addGoal(11, new EnderMan.EndermanTakeBlockGoal(this)); @@ -9321,7 +9007,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false)); } -@@ -247,7 +276,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -242,7 +271,7 @@ public class EnderMan extends Monster implements NeutralMob { // Paper end - EndermanAttackPlayerEvent ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3); @@ -9330,7 +9016,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 return false; } else { Vec3 vec3d = player.getViewVector(1.0F).normalize(); -@@ -289,12 +318,12 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -274,12 +303,12 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean isSensitiveToWater() { @@ -9345,7 +9031,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 float f = this.getLightLevelDependentMagicValue(); if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent -@@ -415,6 +444,8 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -400,6 +429,8 @@ public class EnderMan extends Monster implements NeutralMob { public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { return false; @@ -9354,7 +9040,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 } else { boolean flag = source.getDirectEntity() instanceof ThrownPotion; boolean flag1; -@@ -429,6 +460,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -414,6 +445,7 @@ public class EnderMan extends Monster implements NeutralMob { } else { flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount); @@ -9362,7 +9048,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent for (int i = 0; i < 64; ++i) { if (this.teleport()) { -@@ -475,7 +507,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -458,7 +490,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { @@ -9371,7 +9057,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 } private static class EndermanFreezeWhenLookedAt extends Goal { -@@ -522,7 +554,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -505,7 +537,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { @@ -9389,7 +9075,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 } @Override -@@ -567,7 +608,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -550,7 +591,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { @@ -9408,10 +9094,10 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47 @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/Endermite.java b/src/main/java/net/minecraft/world/entity/monster/Endermite.java -index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d7825bebf15b 100644 +index 9c78905762d9a484878fa9cf03a2ca3850e7e613..14d6796a124a85b8cbf5f3b719d89d99e0cf8db5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Endermite.java +++ b/src/main/java/net/minecraft/world/entity/monster/Endermite.java -@@ -37,20 +37,63 @@ public class Endermite extends Monster { +@@ -32,20 +32,63 @@ public class Endermite extends Monster { private static final int MAX_LIFE = 2400; public int life; @@ -9475,7 +9161,7 @@ index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d782 this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); } -@@ -93,12 +136,14 @@ public class Endermite extends Monster { +@@ -83,12 +126,14 @@ public class Endermite extends Monster { public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); this.life = nbt.getInt("Lifetime"); @@ -9491,10 +9177,10 @@ index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d782 @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 e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc72465702dfe 100644 +index 38e866571c35ebc4843a8d4fa39691902a5fcc91..f92f93c780f4c176d6c02c4b98ffe3a4ef3993f6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java -@@ -51,10 +51,43 @@ public class Evoker extends SpellcasterIllager { +@@ -52,10 +52,43 @@ public class Evoker extends SpellcasterIllager { this.xpReward = 10; } @@ -9538,7 +9224,7 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724 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()); -@@ -63,6 +96,7 @@ public class Evoker extends SpellcasterIllager { +@@ -64,6 +97,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)); @@ -9546,7 +9232,7 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724 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)); -@@ -327,7 +361,7 @@ public class Evoker extends SpellcasterIllager { +@@ -340,7 +374,7 @@ public class Evoker extends SpellcasterIllager { return false; } else if (Evoker.this.tickCount < this.nextAttackTickCount) { return false; @@ -9556,10 +9242,10 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724 } else { List list = Evoker.this.level().getNearbyEntities(Sheep.class, this.wololoTargeting, Evoker.this, Evoker.this.getBoundingBox().inflate(16.0D, 4.0D, 16.0D)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Ghast.java b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b698c6bfc 100644 +index 373a4f036157017b0d95e8f1849780582235a549..a25c82be45e3db5143f6bf617fedc2fa85bd89ca 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -@@ -45,11 +45,47 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -43,11 +43,47 @@ public class Ghast extends FlyingMob implements Enemy { this.moveControl = new Ghast.GhastMoveControl(this); } @@ -9607,7 +9293,7 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; })); -@@ -97,6 +133,21 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -95,6 +131,21 @@ public class Ghast extends FlyingMob implements Enemy { } } @@ -9627,9 +9313,9 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b + } + @Override - protected void defineSynchedData() { - super.defineSynchedData(); -@@ -104,7 +155,7 @@ public class Ghast extends FlyingMob implements Enemy { + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -102,7 +153,7 @@ public class Ghast extends FlyingMob implements Enemy { } public static AttributeSupplier.Builder createAttributes() { @@ -9638,8 +9324,8 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b } @Override -@@ -171,7 +222,7 @@ public class Ghast extends FlyingMob implements Enemy { - return 2.6F; +@@ -154,7 +205,7 @@ public class Ghast extends FlyingMob implements Enemy { + } - private static class GhastMoveControl extends MoveControl { @@ -9647,7 +9333,7 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b private final Ghast ghast; private int floatDuration; -@@ -182,7 +233,7 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -165,7 +216,7 @@ public class Ghast extends FlyingMob implements Enemy { } @Override @@ -9657,22 +9343,19 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b if (this.floatDuration-- <= 0) { this.floatDuration += this.ghast.getRandom().nextInt(5) + 2; diff --git a/src/main/java/net/minecraft/world/entity/monster/Giant.java b/src/main/java/net/minecraft/world/entity/monster/Giant.java -index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac30273426 100644 +index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..5c2881d0be519c52cbba74d7b7ca3ea9b4536463 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Giant.java +++ b/src/main/java/net/minecraft/world/entity/monster/Giant.java -@@ -1,18 +1,123 @@ +@@ -1,23 +1,128 @@ package net.minecraft.world.entity.monster; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.Difficulty; +import net.minecraft.world.DifficultyInstance; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.MobSpawnType; - import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.SpawnGroupData; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; @@ -9699,9 +9382,8 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac public class Giant extends Monster { public Giant(EntityType type, Level world) { super(type, world); -+ this.safeFallDistance = 10.0F; // Purpur -+ } -+ + } + + // Purpur start + @Override + public boolean isRidable() { @@ -9748,7 +9430,6 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac + protected boolean isAlwaysExperienceDropper() { + return this.level().purpurConfig.giantAlwaysDropExp; + } -+ // Purpur end + + @Override + protected void initAttributes() { @@ -9757,9 +9438,15 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level().purpurConfig.giantAttackDamage); + } + ++ // Purpur end ++ + public static AttributeSupplier.Builder createAttributes() { + return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 100.0).add(Attributes.MOVEMENT_SPEED, 0.5).add(Attributes.ATTACK_DAMAGE, 50.0); + } + + @Override -+ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { -+ SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); ++ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) { ++ SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData); + if (groupData == null) { + populateDefaultEquipmentSlots(this.random, difficulty); + populateDefaultEquipmentEnchantments(this.random, difficulty); @@ -9781,11 +9468,8 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac + // make giants jump as high as everything else relative to their size + // 1.0 makes bottom of feet about as high as their waist when they jump + return level().purpurConfig.giantJumpHeight; - } - - @Override -@@ -31,6 +136,6 @@ public class Giant extends Monster { - ++ } ++ @Override public float getWalkTargetValue(BlockPos pos, LevelReader world) { - return world.getPathfindingCostFromLightLevels(pos); @@ -9793,12 +9477,12 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac } } 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 fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e7b7e724e 100644 +index 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..f9496126f75b4c1b89ec33617e577d83042e0290 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 { +@@ -66,15 +66,51 @@ public class Guardian extends Monster { this.xpReward = 10; - this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F); + this.setPathfindingMalus(PathType.WATER, 0.0F); this.moveControl = new Guardian.GuardianMoveControl(this); + // Purpur start + this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this) { @@ -9848,7 +9532,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e this.goalSelector.addGoal(4, this.guardianAttackGoal = new Guardian.GuardianAttackGoal(this)); // CraftBukkit - assign field this.goalSelector.addGoal(5, pathfindergoalmovetowardsrestriction); this.goalSelector.addGoal(7, this.randomStrollGoal); -@@ -87,6 +123,7 @@ public class Guardian extends Monster { +@@ -83,6 +119,7 @@ public class Guardian extends Monster { this.goalSelector.addGoal(9, new RandomLookAroundGoal(this)); this.randomStrollGoal.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); pathfindergoalmovetowardsrestriction.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); @@ -9856,7 +9540,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 10, true, false, new Guardian.GuardianAttackSelector(this))); } -@@ -347,7 +384,7 @@ public class Guardian extends Monster { +@@ -333,7 +370,7 @@ public class Guardian extends Monster { @Override public void travel(Vec3 movementInput) { if (this.isControlledByLocalInstance() && this.isInWater()) { @@ -9865,8 +9549,8 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e this.move(MoverType.SELF, this.getDeltaMovement()); this.setDeltaMovement(this.getDeltaMovement().scale(0.9D)); if (!this.isMoving() && this.getTarget() == null) { -@@ -364,7 +401,7 @@ public class Guardian extends Monster { - return new Vector3f(0.0F, dimensions.height + 0.125F * scaleFactor, 0.0F); +@@ -345,7 +382,7 @@ public class Guardian extends Monster { + } - private static class GuardianMoveControl extends MoveControl { @@ -9874,7 +9558,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e private final Guardian guardian; -@@ -373,8 +410,17 @@ public class Guardian extends Monster { +@@ -354,8 +391,17 @@ public class Guardian extends Monster { this.guardian = guardian; } @@ -9893,7 +9577,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e 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(); -@@ -385,7 +431,7 @@ public class Guardian extends Monster { +@@ -366,7 +412,7 @@ public class Guardian extends Monster { this.guardian.setYRot(this.rotlerp(this.guardian.getYRot(), f, 90.0F)); this.guardian.yBodyRot = this.guardian.getYRot(); @@ -9903,10 +9587,10 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e 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 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd945503d69 100644 +index c34c8483a026f61fe20935697d321d7ef5d8dfbc..95d3edc6c88d6ed0556c21c2623cdd5cfda35911 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 { +@@ -20,6 +20,59 @@ public class Husk extends Zombie { public Husk(EntityType type, Level world) { super(type, world); @@ -9966,7 +9650,7 @@ index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd9 } public static boolean checkHuskSpawnRules(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { -@@ -30,7 +83,7 @@ public class Husk extends Zombie { +@@ -28,7 +81,7 @@ public class Husk extends Zombie { @Override public boolean isSunSensitive() { @@ -9976,10 +9660,10 @@ index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd9 @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc423f5c0658 100644 +index a7964208c952cb4e34916ae6523850fc3921b07e..ae036a16e3677dfba451f4eb4505036d45e50cf3 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java +++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -@@ -59,10 +59,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { +@@ -56,10 +56,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { } @@ -10025,7 +9709,7 @@ index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc42 this.goalSelector.addGoal(1, new SpellcasterIllager.SpellcasterCastingSpellGoal()); this.goalSelector.addGoal(4, new Illusioner.IllusionerMirrorSpellGoal()); this.goalSelector.addGoal(5, new Illusioner.IllusionerBlindnessSpellGoal()); -@@ -70,6 +105,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { +@@ -67,6 +102,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { 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)); @@ -10034,10 +9718,10 @@ index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc42 this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300)); this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300)); diff --git a/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java b/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java -index c4b4ff79bfdf9e34bf73a7760369e24b28dbbd70..1bfd5ef9ce8a07375ff215d092368c3f5104ab13 100644 +index 7be2393dc3cb79556d9767b09f43be0f81308a12..e7c79e8c72226285eb5a4763dcf8ddd27078539c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java +++ b/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java -@@ -25,6 +25,58 @@ public class MagmaCube extends Slime { +@@ -24,6 +24,58 @@ public class MagmaCube extends Slime { super(type, world); } @@ -10096,7 +9780,7 @@ index c4b4ff79bfdf9e34bf73a7760369e24b28dbbd70..1bfd5ef9ce8a07375ff215d092368c3f public static AttributeSupplier.Builder createAttributes() { return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } -@@ -70,11 +122,12 @@ public class MagmaCube extends Slime { +@@ -64,11 +116,12 @@ public class MagmaCube extends Slime { } @Override @@ -10130,10 +9814,10 @@ index 759839e912c54598b257ad738481364940f88a18..e60e6b3e5ae5a468cfe649ed2222412f return false; } else { diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b2498d2bb998 100644 +index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336abb3563d2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -50,6 +50,8 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -48,6 +48,8 @@ public class Phantom extends FlyingMob implements Enemy { Vec3 moveTargetPoint; public BlockPos anchorPoint; Phantom.AttackPhase attackPhase; @@ -10142,10 +9826,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 public Phantom(EntityType type, Level world) { super(type, world); -@@ -59,6 +61,92 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -57,6 +59,92 @@ public class Phantom extends FlyingMob implements Enemy { this.xpReward = 5; this.moveControl = new Phantom.PhantomMoveControl(this); - this.lookControl = new Phantom.PhantomLookControl(this); + this.lookControl = new Phantom.PhantomLookControl(this, this); + this.setShouldBurnInDay(true); // Purpur + } + @@ -10235,7 +9919,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 } @Override -@@ -73,9 +161,17 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -71,9 +159,17 @@ public class Phantom extends FlyingMob implements Enemy { @Override protected void registerGoals() { @@ -10256,7 +9940,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); } -@@ -91,7 +187,10 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -89,7 +185,10 @@ public class Phantom extends FlyingMob implements Enemy { private void updatePhantomSizeInfo() { this.refreshDimensions(); @@ -10268,7 +9952,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 } public int getPhantomSize() { -@@ -121,6 +220,21 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -114,6 +213,21 @@ public class Phantom extends FlyingMob implements Enemy { return true; } @@ -10290,8 +9974,8 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 @Override public void tick() { super.tick(); -@@ -141,14 +255,12 @@ public class Phantom extends FlyingMob implements Enemy { - this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f2, this.getY() + (double) f4, this.getZ() - (double) f3, 0.0D, 0.0D, 0.0D); +@@ -134,14 +248,12 @@ public class Phantom extends FlyingMob implements Enemy { + this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f3, this.getY() + (double) f5, this.getZ() - (double) f4, 0.0D, 0.0D, 0.0D); } + if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur @@ -10299,17 +9983,17 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 @Override public void aiStep() { -- if (this.isAlive() && shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API -- this.setSecondsOnFire(8); +- if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API +- this.igniteForSeconds(8); - } - + // Purpur - moved down to shouldBurnInDay() super.aiStep(); } -@@ -160,7 +272,11 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -153,7 +265,11 @@ public class Phantom extends FlyingMob implements Enemy { @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { + public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) { this.anchorPoint = this.blockPosition().above(5); - this.setPhantomSize(0); + // Purpur start @@ -10317,10 +10001,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 + int max = world.getLevel().purpurConfig.phantomMaxSize; + this.setPhantomSize(min == max ? min : world.getRandom().nextInt(max + 1 - min) + min); + // Purpur end - return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); + return super.finalizeSpawn(world, difficulty, spawnReason, entityData); } -@@ -176,7 +292,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -169,7 +285,7 @@ public class Phantom extends FlyingMob implements Enemy { if (nbt.hasUUID("Paper.SpawningEntity")) { this.spawningEntity = nbt.getUUID("Paper.SpawningEntity"); } @@ -10329,7 +10013,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); } // Paper end -@@ -193,7 +309,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -186,7 +302,7 @@ public class Phantom extends FlyingMob implements Enemy { if (this.spawningEntity != null) { nbt.putUUID("Paper.SpawningEntity", this.spawningEntity); } @@ -10338,12 +10022,13 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 // Paper end } -@@ -262,8 +378,14 @@ public class Phantom extends FlyingMob implements Enemy { - return spawningEntity; +@@ -242,8 +358,15 @@ public class Phantom extends FlyingMob implements Enemy { + return this.spawningEntity; } public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; } - private boolean shouldBurnInDay = true; - public boolean shouldBurnInDay() { return shouldBurnInDay; } ++ + // private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity - keep methods for ABI compatibility + // Purpur start + public boolean shouldBurnInDay() { @@ -10354,8 +10039,8 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 + // Purpur End public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Paper end - private static enum AttackPhase { -@@ -273,7 +395,125 @@ public class Phantom extends FlyingMob implements Enemy { + +@@ -254,7 +377,125 @@ public class Phantom extends FlyingMob implements Enemy { private AttackPhase() {} } @@ -10482,7 +10167,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 private float speed = 0.1F; -@@ -281,8 +521,19 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -262,8 +503,19 @@ public class Phantom extends FlyingMob implements Enemy { super(entity); } @@ -10503,15 +10188,15 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 if (Phantom.this.horizontalCollision) { Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F); this.speed = 0.1F; -@@ -328,14 +579,20 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -309,14 +561,20 @@ public class Phantom extends FlyingMob implements Enemy { } } - private class PhantomLookControl extends LookControl { + private class PhantomLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - public PhantomLookControl(Mob entity) { - super(entity); + public PhantomLookControl(final Phantom entity, final Mob phantom) { + super(phantom); } + // Purpur start @@ -10526,7 +10211,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 } private class PhantomBodyRotationControl extends BodyRotationControl { -@@ -422,6 +679,12 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -403,6 +661,12 @@ public class Phantom extends FlyingMob implements Enemy { return false; } else if (!entityliving.isAlive()) { return false; @@ -10539,7 +10224,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 } else { if (entityliving instanceof Player) { Player entityhuman = (Player) entityliving; -@@ -567,6 +830,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -548,6 +812,7 @@ public class Phantom extends FlyingMob implements Enemy { this.nextScanTick = reducedTickDelay(60); List list = Phantom.this.level().getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0D, 64.0D, 16.0D)); @@ -10548,10 +10233,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249 list.sort(Comparator.comparing((Entity e) -> { return e.getY(); }).reversed()); // CraftBukkit - decompile error Iterator iterator = list.iterator(); diff --git a/src/main/java/net/minecraft/world/entity/monster/Pillager.java b/src/main/java/net/minecraft/world/entity/monster/Pillager.java -index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9aea10cb60 100644 +index ac411202c0029052a962b51b015da191b124de5f..ae3eb87af8d3853be82c2002507141e43ab644de 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Pillager.java -@@ -66,15 +66,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve +@@ -58,15 +58,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve super(type, world); } @@ -10592,7 +10277,7 @@ index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9a super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F)); + this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F)); // Paper - decomp fix this.goalSelector.addGoal(3, new RangedCrossbowAttackGoal<>(this, 1.0D, 8.0F)); this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 15.0F, 1.0F)); @@ -10602,11 +10287,11 @@ index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9a this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45458c0a75 100644 +index 2d7b7c949faaaaae94c0043132a4a822f55df104..9551bd7c9bed37cf17910e7f71b82ed20fb2d759 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -71,14 +71,54 @@ public class Ravager extends Raider { - this.setPathfindingMalus(BlockPathTypes.LEAVES, 0.0F); +@@ -68,14 +68,54 @@ public class Ravager extends Raider { + this.setPathfindingMalus(PathType.LEAVES, 0.0F); } + // Purpur start @@ -10660,7 +10345,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45 this.targetSelector.addGoal(2, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entityliving) -> { -@@ -136,7 +176,7 @@ public class Ravager extends Raider { +@@ -128,7 +168,7 @@ public class Ravager extends Raider { @Override public void aiStep() { super.aiStep(); @@ -10669,7 +10354,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45 if (this.isImmobile()) { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D); } else { -@@ -146,7 +186,7 @@ public class Ravager extends Raider { +@@ -138,7 +178,7 @@ public class Ravager extends Raider { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0)); } @@ -10678,7 +10363,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45 boolean flag = false; AABB axisalignedbb = this.getBoundingBox().inflate(0.2D); Iterator iterator = BlockPos.betweenClosed(Mth.floor(axisalignedbb.minX), Mth.floor(axisalignedbb.minY), Mth.floor(axisalignedbb.minZ), Mth.floor(axisalignedbb.maxX), Mth.floor(axisalignedbb.maxY), Mth.floor(axisalignedbb.maxZ)).iterator(); -@@ -156,7 +196,7 @@ public class Ravager extends Raider { +@@ -148,7 +188,7 @@ public class Ravager extends Raider { BlockState iblockdata = this.level().getBlockState(blockposition); Block block = iblockdata.getBlock(); @@ -10688,10 +10373,10 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45 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 f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b741da086 100644 +index 5215fa54666979ef4da074ddfdb082e7274f2957..1afa6dc4f2a6437cd4cc3e49694e79641fcc13ad 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; +@@ -23,6 +23,8 @@ import net.minecraft.tags.DamageTypeTags; import net.minecraft.util.Mth; import net.minecraft.world.Difficulty; import net.minecraft.world.DifficultyInstance; @@ -10699,8 +10384,8 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b +import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityDimensions; -@@ -49,6 +51,8 @@ import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.EntitySelector; +@@ -48,6 +50,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.ShulkerBullet; import net.minecraft.world.item.DyeColor; @@ -10769,7 +10454,7 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{this.getClass()})).setAlertOthers()); this.targetSelector.addGoal(2, new Shulker.ShulkerNearestAttackGoal(this)); this.targetSelector.addGoal(3, new Shulker.ShulkerDefenseAttackGoal(this)); -@@ -474,12 +525,21 @@ public class Shulker extends AbstractGolem implements VariantHolder getVariant() { @@ -10805,20 +10490,20 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b } @Nullable -@@ -601,7 +661,7 @@ public class Shulker extends AbstractGolem implements VariantHolder(this, Player.class, true)); } -@@ -187,7 +221,7 @@ public class Silverfish extends Monster { +@@ -167,7 +201,7 @@ public class Silverfish extends Monster { continue; } // CraftBukkit end @@ -10876,7 +10561,7 @@ index fcd5cc3ff8d4b38f4dea08f78723db3dac53ffde..931412a5ab315d4080a9f5209d3e85d7 world.destroyBlock(blockposition1, true, this.silverfish); } else { world.setBlock(blockposition1, ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)), 3); -@@ -225,7 +259,7 @@ public class Silverfish extends Monster { +@@ -205,7 +239,7 @@ public class Silverfish extends Monster { } else { RandomSource randomsource = this.mob.getRandom(); @@ -10886,7 +10571,7 @@ index fcd5cc3ff8d4b38f4dea08f78723db3dac53ffde..931412a5ab315d4080a9f5209d3e85d7 BlockPos blockposition = BlockPos.containing(this.mob.getX(), this.mob.getY() + 0.5D, this.mob.getZ()).relative(this.selectedDirection); BlockState iblockdata = this.mob.level().getBlockState(blockposition); diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c97e8ab13 100644 +index 5642bddc8268d70e5bb5446b65be1d8ce34feb9b..9eb6ed001bfc578311300977dda6f3f156d07190 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java @@ -14,6 +14,16 @@ import net.minecraft.world.item.Items; @@ -10906,7 +10591,7 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c public class Skeleton extends AbstractSkeleton { private static final int TOTAL_CONVERSION_TIME = 300; -@@ -26,6 +36,38 @@ public class Skeleton extends AbstractSkeleton { +@@ -26,6 +36,40 @@ public class Skeleton extends AbstractSkeleton { super(type, world); } @@ -10932,10 +10617,12 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c + this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.skeletonMaxHealth); + } + ++ // Purpur start + @Override + public boolean isSensitiveToWater() { + return this.level().purpurConfig.skeletonTakeDamageFromWater; + } ++ // Purpur end + + @Override + protected boolean isAlwaysExperienceDropper() { @@ -10943,9 +10630,9 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c + } + @Override - protected void defineSynchedData() { - super.defineSynchedData(); -@@ -142,4 +184,67 @@ public class Skeleton extends AbstractSkeleton { + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -140,4 +184,67 @@ public class Skeleton extends AbstractSkeleton { } } @@ -11014,10 +10701,10 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e7291b70a2a4 100644 +index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fec00147ca 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -62,6 +62,7 @@ public class Slime extends Mob implements Enemy { +@@ -61,6 +61,7 @@ public class Slime extends Mob implements Enemy { public float squish; public float oSquish; private boolean wasOnGround; @@ -11025,7 +10712,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 public Slime(EntityType type, Level world) { super(type, world); -@@ -69,12 +70,89 @@ public class Slime extends Mob implements Enemy { +@@ -68,12 +69,89 @@ public class Slime extends Mob implements Enemy { this.moveControl = new Slime.SlimeMoveControl(this); } @@ -11115,7 +10802,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; })); -@@ -99,9 +177,9 @@ public class Slime extends Mob implements Enemy { +@@ -98,9 +176,9 @@ public class Slime extends Mob implements Enemy { this.entityData.set(Slime.ID_SIZE, j); this.reapplyPosition(); this.refreshDimensions(); @@ -11127,7 +10814,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 if (heal) { this.setHealth(this.getMaxHealth()); } -@@ -386,11 +464,12 @@ public class Slime extends Mob implements Enemy { +@@ -382,11 +460,12 @@ public class Slime extends Mob implements Enemy { } @Override @@ -11141,8 +10828,8 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 } @Nullable -@@ -424,7 +503,7 @@ public class Slime extends Mob implements Enemy { - return super.getDimensions(pose).scale(0.255F * (float) this.getSize()); +@@ -420,7 +499,7 @@ public class Slime extends Mob implements Enemy { + return super.getDefaultDimensions(pose).scale((float) this.getSize()); } - private static class SlimeMoveControl extends MoveControl { @@ -11150,7 +10837,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 private float yRot; private int jumpDelay; -@@ -443,21 +522,33 @@ public class Slime extends Mob implements Enemy { +@@ -439,21 +518,33 @@ public class Slime extends Mob implements Enemy { } public void setWantedMovement(double speed) { @@ -11187,7 +10874,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 if (this.jumpDelay-- <= 0) { this.jumpDelay = this.slime.getJumpDelay(); if (this.isAggressive) { -@@ -474,7 +565,7 @@ public class Slime extends Mob implements Enemy { +@@ -470,7 +561,7 @@ public class Slime extends Mob implements Enemy { this.mob.setSpeed(0.0F); } } else { @@ -11197,10 +10884,10 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729 } diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index 7618364e5373fe17cfe45a5a4ee9ab25e591581c..b44ffeb4cc0ef63fdd25683f60c5a20fcdeb9135 100644 +index fa0316e9d2a4cf213982994dc8bf310299cca984..159740069aba59bffff444d933af32aaf752ba48 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java -@@ -53,14 +53,48 @@ public class Spider extends Monster { +@@ -51,9 +51,42 @@ public class Spider extends Monster { super(type, world); } @@ -11240,8 +10927,10 @@ index 7618364e5373fe17cfe45a5a4ee9ab25e591581c..b44ffeb4cc0ef63fdd25683f60c5a20f protected void registerGoals() { this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.goalSelector.addGoal(3, new LeapAtTargetGoal(this, 0.4F)); - this.goalSelector.addGoal(4, new Spider.SpiderAttackGoal(this)); + this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Armadillo.class, 6.0F, 1.0D, 1.2D, (entityliving) -> { + return !((Armadillo) entityliving).isScared(); + })); +@@ -62,6 +95,7 @@ public class Spider extends Monster { this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8D)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); @@ -11293,18 +10982,18 @@ index 207a649d737adff440bd3f7cba15b0dbca338a35..18c0cf991c2e8418d7fdd4c8dbd7487a BlockPos blockPos = pos; diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java -index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce828c2d78fc 100644 +index fe85900a610afd0b237d8b5a164181c03afbdfc7..5ea5bf9c0e11b0e1f9fe50093899c6e35ee6cf4f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Strider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java -@@ -94,12 +94,44 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { +@@ -91,12 +91,44 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { super(type, world); this.steering = new ItemBasedSteering(this.entityData, Strider.DATA_BOOST_TIME, Strider.DATA_SADDLE_ID); this.blocksBuilding = true; -- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); -+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur - this.setPathfindingMalus(BlockPathTypes.LAVA, 0.0F); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F); - this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F); +- this.setPathfindingMalus(PathType.WATER, -1.0F); ++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur + this.setPathfindingMalus(PathType.LAVA, 0.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F); + this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); } + // Purpur start @@ -11342,14 +11031,14 @@ index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce82 public static boolean checkStriderSpawnRules(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable(); -@@ -161,6 +193,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { +@@ -158,6 +190,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { @Override protected void registerGoals() { this.goalSelector.addGoal(1, new PanicGoal(this, 1.65D)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.temptGoal = new TemptGoal(this, 1.4D, Strider.TEMPT_ITEMS, false); - this.goalSelector.addGoal(3, this.temptGoal); + this.temptGoal = new TemptGoal(this, 1.4D, (itemstack) -> { + return itemstack.is(ItemTags.STRIDER_TEMPT_ITEMS); @@ -414,7 +447,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { @Override @@ -11389,10 +11078,10 @@ 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 f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb55ffc5dc1 100644 +index fd3b37dde54623ba38186efb2a64d364c86b81d2..691f319719280f873140df7d93c821417e32e8f7 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 { +@@ -60,6 +60,65 @@ public class Vex extends Monster implements TraceableEntity { this.xpReward = 3; } @@ -11438,7 +11127,6 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { + return false; // no fall damage please + } -+ // Purpur end + + @Override + public void initAttributes() { @@ -11454,11 +11142,12 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 + protected boolean isAlwaysExperienceDropper() { + return this.level().purpurConfig.vexAlwaysDropExp; + } ++ // Purpur end + @Override - protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { - return dimensions.height - 0.28125F; -@@ -81,7 +140,7 @@ public class Vex extends Monster implements TraceableEntity { + public boolean isFlapping() { + return this.tickCount % Vex.TICKS_PER_FLAP == 0; +@@ -73,7 +132,7 @@ public class Vex extends Monster implements TraceableEntity { @Override public void tick() { @@ -11467,7 +11156,7 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 super.tick(); this.noPhysics = false; this.setNoGravity(true); -@@ -96,17 +155,19 @@ public class Vex extends Monster implements TraceableEntity { +@@ -88,17 +147,19 @@ public class Vex extends Monster implements TraceableEntity { protected void registerGoals() { super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -11488,14 +11177,14 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 } @Override -@@ -251,14 +312,14 @@ public class Vex extends Monster implements TraceableEntity { - return new Vector3f(0.0F, dimensions.height - 0.0625F * scaleFactor, 0.0F); +@@ -230,14 +291,14 @@ public class Vex extends Monster implements TraceableEntity { + this.setDropChance(EquipmentSlot.MAINHAND, 0.0F); } - private class VexMoveControl extends MoveControl { + private class VexMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - public VexMoveControl(Vex entityvex) { + public VexMoveControl(final Vex entityvex) { super(entityvex); } @@ -11505,7 +11194,7 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 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(); -@@ -267,7 +328,7 @@ public class Vex extends Monster implements TraceableEntity { +@@ -246,7 +307,7 @@ public class Vex extends Monster implements TraceableEntity { this.operation = MoveControl.Operation.WAIT; Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5D)); } else { @@ -11515,10 +11204,10 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5 Vec3 vec3d1 = Vex.this.getDeltaMovement(); diff --git a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java -index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47bedf926fb 100644 +index b3da310d6fd1d533da805c38c2f449cf06d01492..e7703aa5467e7551bff06fab4c11d76237bda2e0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java -@@ -56,14 +56,48 @@ public class Vindicator extends AbstractIllager { +@@ -50,14 +50,48 @@ public class Vindicator extends AbstractIllager { super(type, world); } @@ -11567,7 +11256,7 @@ index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47b this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true)); -@@ -136,6 +170,12 @@ public class Vindicator extends AbstractIllager { +@@ -124,6 +158,12 @@ public class Vindicator extends AbstractIllager { RandomSource randomSource = world.getRandom(); this.populateDefaultEquipmentSlots(randomSource, difficulty); this.populateDefaultEquipmentEnchantments(randomSource, difficulty); @@ -11581,10 +11270,10 @@ index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47b } diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java -index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d747115e1cc70 100644 +index 5803c1d36b769f0186baa0665976749765b4cb61..b4aab57b9aaab2ed1322ca41d4bf3c60f155902c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -59,6 +59,38 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -55,6 +55,38 @@ public class Witch extends Raider implements RangedAttackMob { super(type, world); } @@ -11623,7 +11312,7 @@ index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d7471 @Override protected void registerGoals() { super.registerGoals(); -@@ -67,10 +99,12 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -63,10 +95,12 @@ public class Witch extends Raider implements RangedAttackMob { }); this.attackPlayersGoal = new NearestAttackableWitchTargetGoal<>(this, Player.class, 10, true, false, (Predicate) null); this.goalSelector.addGoal(1, new FloatGoal(this)); @@ -11637,11 +11326,11 @@ index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d7471 this.targetSelector.addGoal(2, this.healRaidersGoal); this.targetSelector.addGoal(3, this.attackPlayersGoal); diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java -index 20a65c11ededcd7170704b70118da6200151fbab..e97cb4e166c2e9ac6d93ed5b15350758326e7e74 100644 +index 3f1191795e58f31b7e2fe34ef2774df13b9a789f..8c62d39c54acf274200667ae30c517cd4416b22f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java -@@ -35,6 +35,38 @@ public class WitherSkeleton extends AbstractSkeleton { - this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F); +@@ -32,6 +32,38 @@ public class WitherSkeleton extends AbstractSkeleton { + this.setPathfindingMalus(PathType.LAVA, 8.0F); } + // Purpur start @@ -11680,10 +11369,10 @@ index 20a65c11ededcd7170704b70118da6200151fbab..e97cb4e166c2e9ac6d93ed5b15350758 protected void registerGoals() { this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractPiglin.class, true)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java -index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432f7decfb6 100644 +index e650d78e21944579f556f9c9efb38d150cd3a64e..f5feb8b048df713808cda9aff37086a531cfa481 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java -@@ -82,6 +82,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { +@@ -80,6 +80,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { this.xpReward = 5; } @@ -11722,7 +11411,7 @@ index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432 @Override protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -241,6 +273,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { +@@ -234,6 +266,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { @Override protected void customServerAiStep() { @@ -11731,10 +11420,10 @@ index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432 this.updateActivity(); } 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 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d51040121213b6ff 100644 +index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d2c1a78cb 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 { +@@ -93,22 +93,69 @@ public class Zombie extends Monster { private int inWaterTime; public int conversionTime; private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field @@ -11805,7 +11494,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 this.addBehaviourGoals(); } -@@ -121,7 +168,19 @@ public class Zombie extends Monster { +@@ -118,7 +165,19 @@ public class Zombie extends Monster { this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers(ZombifiedPiglin.class)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); @@ -11826,7 +11515,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -243,30 +302,7 @@ public class Zombie extends Monster { +@@ -240,30 +299,7 @@ public class Zombie extends Monster { @Override public void aiStep() { @@ -11849,7 +11538,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 - } - - if (flag) { -- this.setSecondsOnFire(8); +- this.igniteForSeconds(8); - } - } - } @@ -11858,7 +11547,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 super.aiStep(); } -@@ -304,6 +340,7 @@ public class Zombie extends Monster { +@@ -301,6 +337,7 @@ public class Zombie extends Monster { } @@ -11866,16 +11555,16 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 public boolean isSunSensitive() { return this.shouldBurnInDay; // Paper - Add more Zombie API } -@@ -433,7 +470,7 @@ public class Zombie extends Monster { +@@ -424,7 +461,7 @@ public class Zombie extends Monster { nbt.putBoolean("CanBreakDoors", this.canBreakDoors()); nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); - nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API -+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity ++ // nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity } @Override -@@ -447,7 +484,7 @@ public class Zombie extends Monster { +@@ -438,7 +475,7 @@ public class Zombie extends Monster { } // Paper start - Add more Zombie API if (nbt.contains("Paper.ShouldBurnInDay")) { @@ -11884,10 +11573,10 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 } // Paper end - Add more Zombie API -@@ -520,19 +557,20 @@ public class Zombie extends Monster { - if (object instanceof Zombie.ZombieGroupData) { - Zombie.ZombieGroupData entityzombie_groupdatazombie = (Zombie.ZombieGroupData) object; +@@ -509,19 +546,20 @@ public class Zombie extends Monster { + } + if (object instanceof Zombie.ZombieGroupData entityzombie_groupdatazombie) { - if (entityzombie_groupdatazombie.isBaby) { - this.setBaby(true); + // Purpur start @@ -11911,7 +11600,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level()); if (entitychicken1 != null) { -@@ -542,6 +580,7 @@ public class Zombie extends Monster { +@@ -531,6 +569,7 @@ public class Zombie extends Monster { this.startRiding(entitychicken1); world.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit } @@ -11919,7 +11608,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 } } } -@@ -588,7 +627,7 @@ public class Zombie extends Monster { +@@ -577,7 +616,7 @@ public class Zombie extends Monster { } protected void randomizeReinforcementsChance() { @@ -11929,10 +11618,10 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012 @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 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7ccb501c6 100644 +index 22ec9c1e74450f56cd1e390d59ca28f1577e6139..8ea44416ea728e740af82912017e888a10d78983 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 { +@@ -80,6 +80,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { }); } @@ -11989,18 +11678,15 @@ index 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7 + } + @Override - protected void defineSynchedData() { - super.defineSynchedData(); -@@ -168,13 +220,13 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -172,10 +224,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.GOLDEN_APPLE)) { - if (this.hasEffect(MobEffects.WEAKNESS)) { + if (this.hasEffect(MobEffects.WEAKNESS) && level().purpurConfig.zombieVillagerCureEnabled) { // Purpur - if (!player.getAbilities().instabuild) { - itemstack.shrink(1); - } - + itemstack.consume(1, player); if (!this.level().isClientSide) { - this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600); + this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // Purpur @@ -12008,11 +11694,11 @@ index 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7 return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a8046297f73 100644 +index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01ac6c9c41 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -@@ -64,6 +64,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { - this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F); +@@ -62,6 +62,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { + this.setPathfindingMalus(PathType.LAVA, 8.0F); } + // Purpur start @@ -12065,7 +11751,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80 @Override public void setPersistentAngerTarget(@Nullable UUID angryAt) { this.persistentAngerTarget = angryAt; -@@ -111,7 +158,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -109,7 +156,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.maybeAlertOthers(); } @@ -12074,7 +11760,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80 this.lastHurtByPlayerTime = this.tickCount; } -@@ -166,7 +213,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -164,7 +211,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.ticksUntilNextAlert = ZombifiedPiglin.ALERT_INTERVAL.sample(this.random); } @@ -12083,7 +11769,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80 this.setLastHurtByPlayer((Player) entityliving); } -@@ -246,7 +293,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -244,7 +291,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @Override protected void randomizeReinforcementsChance() { @@ -12093,10 +11779,10 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80 @Nullable 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 fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f7f8db803 100644 +index 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0b56c3b50 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -92,6 +92,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { +@@ -90,6 +90,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { this.xpReward = 5; } @@ -12140,7 +11826,7 @@ index fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f @Override public boolean canBeLeashed(Player player) { return !this.isLeashed(); -@@ -158,7 +195,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { +@@ -156,7 +193,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { @@ -12150,10 +11836,10 @@ index fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f HoglinAi.updateActivity(this); if (this.isConverting()) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa72566442 100644 +index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184ada3c57b5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -96,6 +96,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -94,6 +94,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento this.xpReward = 5; } @@ -12192,7 +11878,7 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); -@@ -303,7 +335,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -297,7 +329,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { @@ -12201,7 +11887,7 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa this.getBrain().tick((ServerLevel) this.level(), this); PiglinAi.updateActivity(this); super.customServerAiStep(); -@@ -400,7 +432,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -389,7 +421,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @Override public boolean wantsToPickUp(ItemStack stack) { @@ -12211,39 +11897,23 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa protected boolean canReplaceCurrentItem(ItemStack stack) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index 4f4f557b7f4232ec3b90dda43c6bed30521318ba..dd4313e0507d3adda0ec84c79f1af13ecc2d7ef3 100644 +index e25af9af8f87e6762716749c367658bf6bda9e34..b7d5c0b0e3741fcf04c4bac21a82fc41e2eeed5d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -599,20 +599,33 @@ public class PiglinAi { - Iterator iterator = iterable.iterator(); - - Item item; -+ ItemStack itemstack; // Purpur - - do { - if (!iterator.hasNext()) { - return false; - } - -- ItemStack itemstack = (ItemStack) iterator.next(); -+ itemstack = (ItemStack) iterator.next(); // Purpur +@@ -606,11 +606,18 @@ public class PiglinAi { + ItemStack itemstack = (ItemStack) iterator.next(); item = itemstack.getItem(); -- } while (!(item instanceof ArmorItem) || ((ArmorItem) item).getMaterial() != ArmorMaterials.GOLD); -+ } while (!(item instanceof ArmorItem) || ((ArmorItem) item).getMaterial() != ArmorMaterials.GOLD && (!entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim || !isWearingGoldTrim(entity, itemstack))); // Purpur +- } while (!(item instanceof ArmorItem) || !((ArmorItem) item).getMaterial().is(ArmorMaterials.GOLD)); ++ } while (!(item instanceof ArmorItem) || !((ArmorItem) item).getMaterial().is(ArmorMaterials.GOLD) && (!entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim || !isWearingGoldTrim(item))); // Purpur return true; } + // Purpur start -+ private static boolean isWearingGoldTrim(LivingEntity entity, ItemStack itemstack) { -+ Optional optionalArmorTrim = net.minecraft.world.item.armortrim.ArmorTrim.getTrim(entity.level().registryAccess(), itemstack, true); -+ -+ if (optionalArmorTrim.isEmpty()) return false; -+ -+ net.minecraft.world.item.armortrim.ArmorTrim armorTrim = optionalArmorTrim.get(); -+ -+ return armorTrim.material().is(net.minecraft.world.item.armortrim.TrimMaterials.GOLD); ++ private static boolean isWearingGoldTrim(Item itemstack) { ++ net.minecraft.world.item.armortrim.ArmorTrim armorTrim = itemstack.components().get(net.minecraft.core.component.DataComponents.TRIM); ++ return armorTrim != null && armorTrim.material().is(net.minecraft.world.item.armortrim.TrimMaterials.GOLD); + } + // Purpur end + @@ -12251,10 +11921,10 @@ index 4f4f557b7f4232ec3b90dda43c6bed30521318ba..dd4313e0507d3adda0ec84c79f1af13e piglin.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); piglin.getNavigation().stop(); diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java -index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2bf8ae9bb 100644 +index 072c28e309d1d18cb3e3e719aec23d77dd966b47..723e4467e202669faeffd4d92a376ca85c199496 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java -@@ -63,6 +63,38 @@ public class PiglinBrute extends AbstractPiglin { +@@ -62,6 +62,38 @@ public class PiglinBrute extends AbstractPiglin { this.xpReward = 20; } @@ -12293,7 +11963,7 @@ index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2 public static AttributeSupplier.Builder createAttributes() { return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 50.0).add(Attributes.MOVEMENT_SPEED, 0.35F).add(Attributes.ATTACK_DAMAGE, 7.0); } -@@ -113,6 +145,7 @@ public class PiglinBrute extends AbstractPiglin { +@@ -106,6 +138,7 @@ public class PiglinBrute extends AbstractPiglin { @Override protected void customServerAiStep() { @@ -12302,13 +11972,13 @@ index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2 PiglinBruteAi.updateActivity(this); PiglinBruteAi.maybePlayActivitySound(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 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068057e3ed2 100644 +index 7350e339c673c3c59bc36843f03f86ab1ef5e925..664774be9fa4422cc76b0f7e362737426e8e1105 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 @@ -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); + this.setPathfindingMalus(PathType.LAVA, 8.0F); + this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F); + this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.5F); // Purpur } @@ -12338,16 +12008,14 @@ index 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068 @Override public Packet getAddEntityPacket() { return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); -@@ -396,19 +420,16 @@ public class Warden extends Monster implements VibrationSystem { +@@ -392,17 +416,14 @@ public class Warden extends Monster implements VibrationSystem { @Contract("null->false") public boolean canTargetEntity(@Nullable Entity entity) { - boolean flag; - + if (getRider() != null && isControllable()) return false; // Purpur - if (entity instanceof LivingEntity) { - LivingEntity entityliving = (LivingEntity) entity; - + if (entity instanceof LivingEntity entityliving) { if (this.level() == entity.level() && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && entityliving.getType() != EntityType.ARMOR_STAND && entityliving.getType() != EntityType.WARDEN && !entityliving.isInvulnerable() && !entityliving.isDeadOrDying() && this.level().getWorldBorder().isWithinBounds(entityliving.getBoundingBox())) { - flag = true; - return flag; @@ -12362,10 +12030,10 @@ index 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068 public static void applyDarknessAround(ServerLevel world, Vec3 pos, @Nullable Entity entity, int range) { diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..69553b5b3c56998e4ae40876b1458929b335ad5d 100644 +index d323cf157f2a910916baa9ce3f7e5bc81648c47d..6cbbca1db5362fa2dd5c5704c7fbaa612d3cbab1 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -@@ -42,6 +42,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; +@@ -48,6 +48,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; // CraftBukkit end public abstract class AbstractVillager extends AgeableMob implements InventoryCarrier, Npc, Merchant { @@ -12374,10 +12042,10 @@ index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..69553b5b3c56998e4ae40876b1458929 // CraftBukkit start private CraftMerchant craftMerchant; diff --git a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java -index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b66497eff9db 100644 +index e0e5046c84941a8d17e18c177f3daea9cb631940..d503d7a5837dbeb98e58dbe8f7e5de45f6d88990 100644 --- a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java -@@ -28,7 +28,7 @@ public class CatSpawner implements CustomSpawner { +@@ -27,7 +27,7 @@ public class CatSpawner implements CustomSpawner { if (this.nextTick > 0) { return 0; } else { @@ -12386,7 +12054,7 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664 Player player = world.getRandomPlayer(); if (player == null) { return 0; -@@ -62,8 +62,12 @@ public class CatSpawner implements CustomSpawner { +@@ -61,8 +61,12 @@ public class CatSpawner implements CustomSpawner { private int spawnInVillage(ServerLevel world, BlockPos pos) { int i = 48; @@ -12397,11 +12065,11 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664 + if (range <= 0) return 0; + if (world.getPoiManager().getCountInRange(entry -> entry.is(PoiTypes.HOME), pos, range, PoiManager.Occupancy.IS_OCCUPIED) > 4L) { + List list = world.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(range, 8.0, range)); -+ // Purpur end ++ // Purpur end if (list.size() < 5) { return this.spawnCat(pos, world); } -@@ -74,7 +78,11 @@ public class CatSpawner implements CustomSpawner { +@@ -73,7 +77,11 @@ public class CatSpawner implements CustomSpawner { private int spawnInHut(ServerLevel world, BlockPos pos) { int i = 16; @@ -12415,19 +12083,20 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664 } 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 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788bf9db6f7 100644 +index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c5485bbdfdc 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -146,6 +146,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - }); +@@ -147,6 +147,9 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public long nextGolemPanic = -1; // Pufferfish + + private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur + private int notLobotomizedCount = 0; // Purpur - ++ public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); -@@ -158,6 +160,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + } +@@ -158,6 +161,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.getNavigation().setCanFloat(true); this.setCanPickUpLoot(true); this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); @@ -12519,7 +12188,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 } @Override -@@ -194,7 +281,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -194,7 +282,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F)); } else { brain.setSchedule(Schedule.VILLAGER_DEFAULT); @@ -12528,7 +12197,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 } brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); -@@ -257,13 +344,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -257,13 +345,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler // Paper start this.customServerAiStep(false); } @@ -12542,18 +12211,18 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 + } else { + this.isLobotomized = false; + } ++ // Purpur end // Pufferfish start - if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { -+ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Purpur - only use brain if no rider ++ 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 -- } + } // Pufferfish end -+ else if (this.isLobotomized && shouldRestock()) restock(); -+ // Purpur end ++ else if (this.isLobotomized && shouldRestock()) restock(); // Purpur if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } -@@ -319,7 +414,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -319,7 +416,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(); @@ -12562,7 +12231,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 } else { boolean flag = this.getOffers().isEmpty(); -@@ -332,9 +427,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -332,9 +429,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (flag) { @@ -12575,7 +12244,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 this.startTrading(player); } -@@ -503,7 +599,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -503,7 +601,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); @@ -12584,7 +12253,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 } } -@@ -753,7 +849,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -745,7 +843,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public boolean canBreed() { @@ -12593,7 +12262,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 } private boolean hungry() { -@@ -967,6 +1063,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -959,6 +1057,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public boolean hasFarmSeeds() { return this.getInventory().hasAnyMatching((itemstack) -> { @@ -12605,7 +12274,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS); }); } -@@ -1024,6 +1125,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1016,6 +1119,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) { @@ -12613,7 +12282,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788 if (this.wantsToSpawnGolem(time)) { AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D); List list = world.getEntitiesOfClass(Villager.class, axisalignedbb); -@@ -1088,6 +1190,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1080,6 +1184,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void startSleeping(BlockPos pos) { @@ -12640,7 +12309,7 @@ index 3821c02187ad04b20cdf1e719a0deeabbf91007d..8f36f113e8eb3236ce53ad9cce320c3d "farmer", PoiTypes.FARMER, diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 8d1cc1a644415be251f469ab1cb2ebc09fe5c3eb..b133c186d2d1412aa623ba3db68091bc69c282a5 100644 +index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8b39c7d38 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java @@ -71,6 +71,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill @@ -12718,10 +12387,10 @@ index 8d1cc1a644415be251f469ab1cb2ebc09fe5c3eb..b133c186d2d1412aa623ba3db68091bc this.openTradingScreen(player, this.getDisplayName(), 1); } diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index d7bddedb19c10f62fd1f7d3128453ad706ed16be..752b38d45d59d8b3cd492246e5aa4f378a78734d 100644 +index c72b6ea5530e54fc373c701028e1c147cea34b59..96e9fce5f9084737d2fcf4deb83305733b480179 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -@@ -159,7 +159,17 @@ public class WanderingTraderSpawner implements CustomSpawner { +@@ -160,7 +160,17 @@ public class WanderingTraderSpawner implements CustomSpawner { int k = pos.getX() + this.random.nextInt(range * 2) - range; int l = pos.getZ() + this.random.nextInt(range * 2) - range; int i1 = world.getHeight(Heightmap.Types.WORLD_SURFACE, k, l); @@ -12738,14 +12407,14 @@ index d7bddedb19c10f62fd1f7d3128453ad706ed16be..752b38d45d59d8b3cd492246e5aa4f37 + } + // Purpur end - if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, world, blockposition2, EntityType.WANDERING_TRADER)) { + if (spawnplacementtype.isSpawnPositionOk(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 c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c853fe6151 100644 +index 70b9d7c9f938009274143ea2fb728492f394531e..852acdd290f2c8d7c3de470140e54a150da4dbb6 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -186,11 +186,21 @@ public abstract class Player extends LivingEntity { - public float hurtDir; // Paper - protected -> public +@@ -198,11 +198,20 @@ public abstract class Player extends LivingEntity { + public boolean ignoreFallDamageFromCurrentImpulse; public boolean affectsSpawning = true; // Paper - Affects Spawning API public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage + public int sixRowEnderchestSlotCount = -1; // Purpur @@ -12756,8 +12425,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 public boolean fauxSleeping; public int oldLevel = -1; -+ public void setAfk(boolean afk) { -+ } ++ public void setAfk(boolean afk) {} + + public boolean isAfk() { + return false; @@ -12766,7 +12434,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 @Override public CraftHumanEntity getBukkitEntity() { return (CraftHumanEntity) super.getBukkitEntity(); -@@ -199,6 +209,19 @@ public abstract class Player extends LivingEntity { +@@ -211,6 +220,19 @@ public abstract class Player extends LivingEntity { public final int sendAllPlayerInfoBucketIndex; // Gale - Purpur - spread out sending all player info @@ -12786,7 +12454,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) { super(EntityType.PLAYER, world); this.lastItemInMainHand = ItemStack.EMPTY; -@@ -244,6 +267,12 @@ public abstract class Player extends LivingEntity { +@@ -256,6 +278,12 @@ public abstract class Player extends LivingEntity { @Override public void tick() { @@ -12799,7 +12467,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 this.noPhysics = this.isSpectator(); if (this.isSpectator()) { this.setOnGround(false); -@@ -358,6 +387,16 @@ public abstract class Player extends LivingEntity { +@@ -370,6 +398,16 @@ public abstract class Player extends LivingEntity { this.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, 200, 0, false, false, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.TURTLE_HELMET); // CraftBukkit } @@ -12816,7 +12484,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 } protected ItemCooldowns createItemCooldowns() { -@@ -448,7 +487,7 @@ public abstract class Player extends LivingEntity { +@@ -460,7 +498,7 @@ public abstract class Player extends LivingEntity { @Override public int getPortalWaitTime() { @@ -12825,7 +12493,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 } @Override -@@ -604,7 +643,7 @@ public abstract class Player extends LivingEntity { +@@ -603,7 +641,7 @@ public abstract class Player extends LivingEntity { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -12834,16 +12502,16 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 list1.add(entity); } else if (!entity.isRemoved()) { this.touch(entity); -@@ -1295,7 +1334,7 @@ public abstract class Player extends LivingEntity { - flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits - flag2 = flag2 && !this.isSprinting(); - if (flag2) { -- f *= 1.5F; -+ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur - } +@@ -1311,7 +1349,7 @@ public abstract class Player extends LivingEntity { - f += f1; -@@ -1938,9 +1977,19 @@ public abstract class Player extends LivingEntity { + flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits + if (flag2) { +- f *= 1.5F; ++ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur + } + + f += f1; +@@ -1956,9 +1994,19 @@ public abstract class Player extends LivingEntity { @Override public int getExperienceReward() { if (!this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) { @@ -12866,40 +12534,34 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8 } else { return 0; } -@@ -2016,6 +2065,11 @@ public abstract class Player extends LivingEntity { - return this.inventory.armor; +@@ -2039,6 +2087,13 @@ public abstract class Player extends LivingEntity { + return slot != EquipmentSlot.BODY; } ++ // Purpur start + @Override + public boolean dismountsUnderwater() { + return !level().purpurConfig.playerRidableInWater; + } ++ // Purpur end + public boolean setEntityOnShoulder(CompoundTag entityNbt) { if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) { if (this.getShoulderEntityLeft().isEmpty()) { -@@ -2296,7 +2350,7 @@ public abstract class Player extends LivingEntity { +@@ -2336,7 +2391,7 @@ public abstract class Player extends LivingEntity { public ItemStack eat(Level world, ItemStack stack) { - this.getFoodData().eat(stack.getItem(), stack); + this.getFoodData().eat(stack); this.awardStat(Stats.ITEM_USED.get(stack.getItem())); - world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); + // world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); // Purpur - moved to tick() if (this instanceof ServerPlayer) { CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack); } -@@ -2390,6 +2444,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 - username validation overriding - 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 488a98e20b4f405d1ce4a224d2d2b5151dec369b..609695ef44fa46bd9a0418e9ac5fe3d105daa505 100644 +index 7f99fe3ea54c6b39584a73d1931100193ac09cbd..54483331ce0906c93d109421007ca38833d02e27 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -75,6 +75,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -77,6 +77,7 @@ public abstract class AbstractArrow extends Projectile { @Nullable private List piercedAndKilledEntities; public ItemStack pickupItemStack; @@ -12907,7 +12569,7 @@ index 488a98e20b4f405d1ce4a224d2d2b5151dec369b..609695ef44fa46bd9a0418e9ac5fe3d1 // Spigot Start @Override -@@ -642,6 +643,12 @@ public abstract class AbstractArrow extends Projectile { +@@ -655,6 +656,12 @@ public abstract class AbstractArrow extends Projectile { this.knockback = punch; } @@ -12949,10 +12611,10 @@ index 9d89872c5958f3e8d6c1ef4fd93f9b8b85296851..6a94c86acce5afbf1e9c8e7d664b3eb2 // CraftBukkit start - fire ExplosionPrimeEvent ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); diff --git a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java -index 8f5376543cca9cbfb2a014f67ec373d984b0df64..3673d1442778331ece25f8faca95b3499cafe46e 100644 +index ffd01d24cbfc90e2a8807757e61b2cf20a944354..a419820d5001079ed839e67c757bc8fa591a20b3 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java -@@ -29,6 +29,12 @@ public class LlamaSpit extends Projectile { +@@ -30,6 +30,12 @@ public class LlamaSpit extends Projectile { this.setPos(owner.getX() - (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(owner.yBodyRot * 0.017453292F), owner.getEyeY() - 0.10000000149011612D, owner.getZ() + (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(owner.yBodyRot * 0.017453292F)); } @@ -12963,22 +12625,13 @@ index 8f5376543cca9cbfb2a014f67ec373d984b0df64..3673d1442778331ece25f8faca95b349 + // Purpur end + @Override - public void tick() { - super.tick(); + protected double getDefaultGravity() { + return 0.06D; 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 d3a055e221ec62070f6557d1686febadf1249402..4a3fe54e9b3af58cba9b09478f75ea788f4880f2 100644 +index adb4cd2a926744182952d0702284f7c7b9e5d42c..330d6badfbd096e4aec873dcb419df7975cb60a3 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -70,7 +70,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { - int maxChunkLoadsPerProjectile = maxProjectileChunkLoadsConfig.perProjectile.max; - if (maxChunkLoadsPerProjectile >= 0 && this.chunksLoadedByProjectile >= maxChunkLoadsPerProjectile) { - if (maxProjectileChunkLoadsConfig.perProjectile.removeFromWorldAfterReachLimit) { -- this.discard(); -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur - } else if (maxProjectileChunkLoadsConfig.perProjectile.resetMovementAfterReachLimit) { - this.setDeltaMovement(0, this.getDeltaMovement().y, 0); - } -@@ -343,7 +343,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -382,7 +382,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean mayInteract(Level world, BlockPos pos) { Entity entity = this.getOwner(); @@ -12988,7 +12641,7 @@ index d3a055e221ec62070f6557d1686febadf1249402..4a3fe54e9b3af58cba9b09478f75ea78 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 6724fe4470aeea338eb4cfd10a7e61fbcac1e5b7..dd38f32ac6a62905c9a79dacf85cf073fa6941b3 100644 +index 3a11ad32d95088a5aca713a1a6a984cc22d4fa9a..c078ccad4aabe469a9611331b415a4cef241973e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -27,7 +27,7 @@ public class SmallFireball extends Fireball { @@ -13001,7 +12654,7 @@ index 6724fe4470aeea338eb4cfd10a7e61fbcac1e5b7..dd38f32ac6a62905c9a79dacf85cf073 // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -index 5e82549ea2e80b3968b793b7b4b685c4891e9a91..bb61e1132c28274175215a679befdcfa2496b099 100644 +index 2b4d206c0d31ba38d7b2af654bd420e85145d441..1b9d0e28e518c501b4b93ae385ddd64aeade97d5 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java @@ -58,11 +58,41 @@ public class Snowball extends ThrowableItemProjectile { @@ -13074,10 +12727,10 @@ index 1fb1e729d6879568d8b4943071fa940325b2e5b0..d9761d8fe746e925a7a32dfc15eb8045 // CraftBukkit end this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS); 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 8ae7d62b72fb72d893e68b02b645d48374595ae6..2bd77524313ae7b32f710e7d197e81a2ddd12965 100644 +index 3ff06cc6ad35567bcb1f29115db63c11a8e79dbb..f7dd785bdb0dbd0706b367b48235215ff1a0e08f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -63,7 +63,7 @@ public class ThrownTrident extends AbstractArrow { +@@ -67,7 +67,7 @@ public class ThrownTrident extends AbstractArrow { Entity entity = this.getOwner(); byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY); @@ -13087,7 +12740,7 @@ index 8ae7d62b72fb72d893e68b02b645d48374595ae6..2bd77524313ae7b32f710e7d197e81a2 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 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e8883b477 100644 +index 55b4b5ad5f084c9a271a716d076672478d6486ba..a60d7f7baab005afc532ecec7aa22c53db4f51e0 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java @@ -99,7 +99,7 @@ public class WitherSkull extends AbstractHurtingProjectile { @@ -13099,10 +12752,11 @@ index 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { -@@ -111,6 +111,17 @@ public class WitherSkull extends AbstractHurtingProjectile { +@@ -111,6 +111,19 @@ public class WitherSkull extends AbstractHurtingProjectile { } ++ // Purpur start + @Override + public boolean canHitEntity(Entity target) { + // do not hit rider @@ -13113,15 +12767,16 @@ index 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e + public boolean canSaveToDisk() { + return false; + } ++ // Purpur end + @Override - public boolean isPickable() { + public boolean hurt(DamageSource source, float amount) { return false; diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 031355802d86f51489a58561b8806d7d672e4a3b..fb61df507e844a2eed27cbe295ab9378b5f780f5 100644 +index 98e558338b5d9fb03869d2cc21b3e90eb45b95f6..4a8fa7e5844b5cd12ef6b113f988b715c7a3ef64 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -322,7 +322,7 @@ public abstract class Raider extends PatrollingMonster { +@@ -341,7 +341,7 @@ public abstract class Raider extends PatrollingMonster { @Override public boolean canUse() { @@ -13129,12 +12784,12 @@ index 031355802d86f51489a58561b8806d7d672e4a3b..fb61df507e844a2eed27cbe295ab9378 + if ((!this.mob.level().purpurConfig.pillagerBypassMobGriefing && !this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items // Purpur Raid raid = this.mob.getCurrentRaid(); - if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.LEADER_BANNER)) { // Gale - Lithium - cache ominous banner item + if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance(this.mob.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { diff --git a/src/main/java/net/minecraft/world/entity/raid/Raids.java b/src/main/java/net/minecraft/world/entity/raid/Raids.java -index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1636def75 100644 +index 8c60f71270d909c10e6617eb64b8fdb42deb73e9..eedce2a3d67d875d5174ee125e2679480d4d412c 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raids.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raids.java -@@ -29,6 +29,7 @@ import net.minecraft.world.phys.Vec3; +@@ -26,6 +26,7 @@ import net.minecraft.world.phys.Vec3; public class Raids extends SavedData { private static final String RAID_FILE_ID = "raids"; @@ -13142,7 +12797,7 @@ index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1 public final Map raidMap = Maps.newHashMap(); private final ServerLevel level; private int nextAvailableID; -@@ -54,6 +55,17 @@ public class Raids extends SavedData { +@@ -51,6 +52,17 @@ public class Raids extends SavedData { public void tick() { ++this.tick; @@ -13157,28 +12812,28 @@ index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1 + }); + } + // Purpur end - Iterator iterator = this.raidMap.values().iterator(); + Iterator iterator = this.raidMap.values().iterator(); while (iterator.hasNext()) { -@@ -138,11 +150,13 @@ public class Raids extends SavedData { - } +@@ -122,11 +134,13 @@ public class Raids extends SavedData { + */ - if (flag) { + if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished + if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur // CraftBukkit start if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(raid, player)) { - player.removeEffect(MobEffects.BAD_OMEN); + player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN); return null; } + if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur - if (!this.raidMap.containsKey(raid.getId())) { + if (!raid.isStarted() && !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 d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d83dc732b 100644 +index 4d7454e5a64fc18e63793a221daa94617f17c666..e7a1ce585c9e552e6f9ce9acd26fdfe5c43e0b5d 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -105,12 +105,14 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -102,12 +102,14 @@ public abstract class AbstractMinecart extends VehicleEntity { private double flyingY = 0.95; private double flyingZ = 0.95; public double maxSpeed = 0.4D; @@ -13193,7 +12848,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d } protected AbstractMinecart(EntityType type, Level world, double x, double y, double z) { -@@ -294,6 +296,12 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -296,6 +298,12 @@ public abstract class AbstractMinecart extends VehicleEntity { @Override public void tick() { @@ -13206,7 +12861,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d // CraftBukkit start double prevX = this.getX(); double prevY = this.getY(); -@@ -451,16 +459,62 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -448,16 +456,62 @@ public abstract class AbstractMinecart extends VehicleEntity { public void activateMinecart(int x, int y, int z, boolean powered) {} @@ -13269,7 +12924,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d this.move(MoverType.SELF, this.getDeltaMovement()); if (!this.onGround()) { -@@ -622,7 +676,7 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -619,7 +673,7 @@ public abstract class AbstractMinecart extends VehicleEntity { if (d18 > 0.01D) { double d20 = 0.06D; @@ -13279,10 +12934,10 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d 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 db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e10346627f0edb0 100644 +index b068cff9b5aa457d65b679529956e8210296d799..105e2b7d7cd7c64a9164e4114476e44f29433f49 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -@@ -521,6 +521,7 @@ public class Boat extends VehicleEntity implements VariantHolder { +@@ -514,6 +514,7 @@ public class Boat extends VehicleEntity implements VariantHolder { if (f > 0.0F) { this.landFriction = f; @@ -13290,15 +12945,15 @@ index db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e103466 return Boat.Status.ON_LAND; } else { return Boat.Status.IN_AIR; -@@ -967,7 +968,13 @@ public class Boat extends VehicleEntity implements VariantHolder { +@@ -962,7 +963,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()); ++ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) { ++ boat.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null); + } + return boat; + // Purpur end @@ -13306,21 +12961,20 @@ index db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e103466 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 +index b89860d451d92ddda64b7e4144542b7fc5fd86f0..dd72d6a79139ff33f26a32b71283ce0b8d084ecc 100644 --- a/src/main/java/net/minecraft/world/food/FoodData.java +++ b/src/main/java/net/minecraft/world/food/FoodData.java -@@ -33,8 +33,10 @@ public class FoodData { - // CraftBukkit end +@@ -38,7 +38,9 @@ public class FoodData { + } public void eat(int food, float saturationModifier) { + int oldValue = this.foodLevel; // Purpur - this.foodLevel = Math.min(food + this.foodLevel, 20); - this.saturationLevel = Math.min(this.saturationLevel + (float) food * saturationModifier * 2.0F, (float) this.foodLevel); + this.add(food, FoodConstants.saturationByModifier(food, saturationModifier)); + if (this.entityhuman.level().purpurConfig.playerBurpWhenFull && this.foodLevel == 20 && oldValue < 20) this.entityhuman.burpDelay = this.entityhuman.level().purpurConfig.playerBurpDelay; // Purpur } - public void eat(Item item, ItemStack stack) { -@@ -100,7 +102,7 @@ public class FoodData { + public void eat(ItemStack stack) { +@@ -105,7 +107,7 @@ public class FoodData { ++this.tickTimer; if (this.tickTimer >= this.starvationRate) { // CraftBukkit - add regen rate manipulation if (player.getHealth() > 10.0F || enumdifficulty == Difficulty.HARD || player.getHealth() > 1.0F && enumdifficulty == Difficulty.NORMAL) { @@ -13329,54 +12983,8 @@ index c3448707fd8a632b457cc97b35d08a9c6933d5ee..e8079d126e6c0cf0b15c01afb6498922 } this.tickTimer = 0; -diff --git a/src/main/java/net/minecraft/world/food/FoodProperties.java b/src/main/java/net/minecraft/world/food/FoodProperties.java -index 9967ba762567631f2bdb1e4f8fe16a13ea927b46..6c945ae8fe8b1517e312c688f829fab41f12d9f4 100644 ---- a/src/main/java/net/minecraft/world/food/FoodProperties.java -+++ b/src/main/java/net/minecraft/world/food/FoodProperties.java -@@ -2,15 +2,22 @@ package net.minecraft.world.food; - - import com.google.common.collect.Lists; - import com.mojang.datafixers.util.Pair; -+ -+import java.util.ArrayList; - import java.util.List; - import net.minecraft.world.effect.MobEffectInstance; - - public class FoodProperties { -- private final int nutrition; -- private final float saturationModifier; -- private final boolean isMeat; -- private final boolean canAlwaysEat; -- private final boolean fastFood; -+ // Purpur start -+ private int nutrition; public void setNutrition(int nutrition) { this.nutrition = nutrition; } -+ private float saturationModifier; public void setSaturationModifier(float saturation) { this.saturationModifier = saturation; } -+ private boolean isMeat; public void setIsMeat(boolean isMeat) { this.isMeat = isMeat; } -+ private boolean canAlwaysEat; public void setCanAlwaysEat(boolean canAlwaysEat) { this.canAlwaysEat = canAlwaysEat; } -+ private boolean fastFood; public void setFastFood(boolean isFastFood) { this.fastFood = isFastFood; } -+ public FoodProperties copy() { -+ return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, new ArrayList<>(this.effects)); -+ } -+ // Purpur end - private final List> effects; - - FoodProperties(int hunger, float saturationModifier, boolean meat, boolean alwaysEdible, boolean snack, List> statusEffects) { -diff --git a/src/main/java/net/minecraft/world/food/Foods.java b/src/main/java/net/minecraft/world/food/Foods.java -index 4569cf30b33167a415256a8542820557ad38f89e..e21efb231ddbd9438139084d5ec5e53ae584e5c8 100644 ---- a/src/main/java/net/minecraft/world/food/Foods.java -+++ b/src/main/java/net/minecraft/world/food/Foods.java -@@ -4,6 +4,9 @@ import net.minecraft.world.effect.MobEffectInstance; - import net.minecraft.world.effect.MobEffects; - - public class Foods { -+ public static final java.util.Map ALL_PROPERTIES = new java.util.HashMap<>(); // Purpur -+ public static final java.util.Map DEFAULT_PROPERTIES = new java.util.HashMap<>(); // Purpur -+ - public static final FoodProperties APPLE = new FoodProperties.Builder().nutrition(4).saturationMod(0.3F).build(); - 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 48f634a7521d31c1e9dfd3cfc83139d428dbd37a..fa185a8145843edf44fc0aeedb6c36b2b13263ae 100644 +index 32910f677b0522ac8ec513fa0d00b714b52cfae4..f85eef14b91a0ada1f6f4b13ab3966f051ff92d3 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 { @@ -13407,10 +13015,10 @@ index 1af7e1548f0648890a1ef2fc0ff4e4c3a56c947c..decea1697c075e7549ccc7501c8e5935 } else if (this.isFuel(itemstack1)) { if (!this.moveItemStackTo(itemstack1, 1, 2, false)) { diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea33eba74b 100644 +index 2bd91b48eaa06f85a5b9b1ae052c70e966ae8e4c..2747f04e657154362af55eef1dd50455e02af371 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -23,6 +23,13 @@ import org.slf4j.Logger; +@@ -25,6 +25,13 @@ import org.slf4j.Logger; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end @@ -13424,7 +13032,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea public class AnvilMenu extends ItemCombinerMenu { public static final int INPUT_SLOT = 0; -@@ -51,6 +58,8 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -53,6 +60,8 @@ public class AnvilMenu extends ItemCombinerMenu { public int maximumRepairCost = 40; private CraftInventoryView bukkitEntity; // CraftBukkit end @@ -13433,12 +13041,12 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea public AnvilMenu(int syncId, Inventory inventory) { this(syncId, inventory, ContainerLevelAccess.NULL); -@@ -78,12 +87,15 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -80,12 +89,15 @@ public class AnvilMenu extends ItemCombinerMenu { @Override protected boolean mayPickup(Player player, boolean present) { -- return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item -+ return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur +- return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item ++ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur } @Override @@ -13450,7 +13058,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea player.giveExperienceLevels(-this.cost.get()); } -@@ -134,6 +146,12 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -136,6 +148,12 @@ public class AnvilMenu extends ItemCombinerMenu { @Override public void createResult() { @@ -13463,44 +13071,53 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea ItemStack itemstack = this.inputSlots.getItem(0); this.cost.set(1); +@@ -143,7 +161,7 @@ public class AnvilMenu extends ItemCombinerMenu { + long j = 0L; + byte b0 = 0; + +- if (!itemstack.isEmpty() && EnchantmentHelper.canStoreEnchantments(itemstack)) { ++ if (!itemstack.isEmpty() && canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(itemstack)) { // Purpur + ItemStack itemstack1 = itemstack.copy(); + ItemStack itemstack2 = this.inputSlots.getItem(1); + ItemEnchantments.Mutable itemenchantments_a = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemstack1)); @@ -210,7 +228,8 @@ public class AnvilMenu extends ItemCombinerMenu { - int i2 = (Integer) map1.get(enchantment); + int i2 = entry.getIntValue(); - i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); -- boolean flag3 = enchantment.canEnchant(itemstack); -+ boolean flag3 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // Purpur -+ boolean flag4 = true; // Purpur + i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); +- boolean flag3 = enchantment.canEnchant(itemstack); ++ boolean flag3 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // Purpur ++ boolean flag4 = true; // Purpur - if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { - flag3 = true; + if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { + flag3 = true; @@ -222,16 +241,20 @@ public class AnvilMenu extends ItemCombinerMenu { - Enchantment enchantment1 = (Enchantment) iterator1.next(); + Holder holder1 = (Holder) iterator1.next(); - if (enchantment1 != enchantment && !enchantment.isCompatibleWith(enchantment1)) { -- flag3 = false; -+ flag4 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants); // Purpur flag3 -> flag4 + if (!holder1.equals(holder) && !enchantment.isCompatibleWith((Enchantment) holder1.value())) { +- flag3 = false; ++ flag4 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants); // Purpur flag3 -> flag4 + if (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { + iterator1.remove(); + flag4 = true; + } - ++i; - } + ++i; + } + } + +- if (!flag3) { ++ if (!flag3 || !flag4) { // Purpur + flag2 = true; + } else { + flag1 = true; +- if (i2 > enchantment.getMaxLevel()) { ++ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur + i2 = enchantment.getMaxLevel(); } -- if (!flag3) { -+ if (!flag3 || !flag4) { // Purpur - flag2 = true; - } else { - flag1 = true; -- if (i2 > enchantment.getMaxLevel()) { -+ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur - i2 = enchantment.getMaxLevel(); - } - -@@ -276,6 +299,54 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -261,6 +284,54 @@ public class AnvilMenu extends ItemCombinerMenu { if (!this.itemName.equals(itemstack.getHoverName().getString())) { - b1 = 1; - i += b1; + b0 = 1; + i += b0; + // Purpur start + if (this.player != null) { + org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity(); @@ -13545,20 +13162,19 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea + if (removeItalics) { + component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); + } -+ itemstack1.setHoverName(io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); ++ itemstack1.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); + } + else + // Purpur end - itemstack1.setHoverName(Component.literal(this.itemName)); + itemstack1.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName)); } - } else if (itemstack.hasCustomHoverName()) { -@@ -293,6 +364,13 @@ public class AnvilMenu extends ItemCombinerMenu { + } else if (itemstack.has(DataComponents.CUSTOM_NAME)) { +@@ -280,6 +351,12 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } + // Purpur start + if (bypassCost && cost.get() >= maximumRepairCost) { -+ itemstack.addTagElement("Purpur.realCost", IntTag.valueOf(cost.get())); + cost.set(maximumRepairCost - 1); + } + // Purpur end @@ -13566,7 +13182,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } -@@ -315,11 +393,17 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -301,6 +378,12 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); @@ -13576,12 +13192,15 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea + ((ServerPlayer) player).connection.send(new ClientboundContainerSetDataPacket(containerId, 0, cost.get())); + } + // Purpur end - } + } else { + org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), ItemStack.EMPTY); // CraftBukkit + this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item +@@ -308,7 +391,7 @@ public class AnvilMenu extends ItemCombinerMenu { } public static int calculateIncreasedRepairCost(int cost) { -- return cost * 2 + 1; -+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? cost * 2 + 1 : 0; +- return (int) Math.min((long) cost * 2L + 1L, 2147483647L); ++ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int) Math.min((long) cost * 2L + 1L, 2147483647L) : 0; } public boolean setItemName(String newItemName) { @@ -13621,23 +13240,23 @@ 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 e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b38115209 100644 +index 5b3e33807e0e13480e3359c0cf067719e5749237..c3a644b0f8c7c5622acc9e1a496f95d432718806 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; +@@ -38,6 +38,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent; import org.bukkit.entity.Player; // CraftBukkit end +// Purpur start +import net.minecraft.world.level.block.entity.BlockEntity; -+import net.minecraft.world.level.block.entity.EnchantmentTableBlockEntity; ++import net.minecraft.world.level.block.entity.EnchantingTableBlockEntity; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +// Purpur end + public class EnchantmentMenu extends AbstractContainerMenu { static final ResourceLocation EMPTY_SLOT_LAPIS_LAZULI = new ResourceLocation("item/empty_slot_lapis_lazuli"); -@@ -74,6 +80,22 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -72,6 +78,22 @@ public class EnchantmentMenu extends AbstractContainerMenu { return context.getLocation(); } // CraftBukkit end @@ -13650,7 +13269,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b + if (who.getHandle().level().purpurConfig.enchantmentTableLapisPersists) { + access.execute((level, pos) -> { + BlockEntity blockEntity = level.getBlockEntity(pos); -+ if (blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) { ++ if (blockEntity instanceof EnchantingTableBlockEntity enchantmentTable) { + enchantmentTable.setLapis(this.getItem(1).getCount()); + } + }); @@ -13660,7 +13279,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b }; this.random = RandomSource.create(); this.enchantmentSeed = DataSlot.standalone(); -@@ -99,6 +121,17 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -97,6 +119,17 @@ public class EnchantmentMenu extends AbstractContainerMenu { } }); @@ -13668,7 +13287,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b + access.execute((level, pos) -> { + if (level.purpurConfig.enchantmentTableLapisPersists) { + BlockEntity blockEntity = level.getBlockEntity(pos); -+ if (blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) { ++ if (blockEntity instanceof EnchantingTableBlockEntity enchantmentTable) { + this.getSlot(1).set(new ItemStack(Items.LAPIS_LAZULI, enchantmentTable.getLapis())); + } + } @@ -13678,7 +13297,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b int j; for (j = 0; j < 3; ++j) { -@@ -351,6 +384,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -332,6 +365,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { public void removed(net.minecraft.world.entity.player.Player player) { super.removed(player); this.access.execute((world, blockposition) -> { @@ -13687,7 +13306,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b }); } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c3cae4648 100644 +index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b544e4cb4f 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 { @@ -13704,54 +13323,121 @@ index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c world.levelEvent(1042, blockposition, 0); @@ -130,7 +132,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { - Enchantment enchantment = (Enchantment) entry.getKey(); - Integer integer = (Integer) entry.getValue(); + Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value(); + int k = entry.getIntValue(); - if (!enchantment.isCurse()) { + if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment)) { // Purpur - j += enchantment.getMinCost(integer); + j += enchantment.getMinCost(k); } } -@@ -230,7 +232,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { - Entry entry = (Entry) iterator.next(); - Enchantment enchantment = (Enchantment) entry.getKey(); +@@ -229,7 +231,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { + Entry> entry = (Entry) iterator.next(); + Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value(); -- if (!enchantment.isCurse() || EnchantmentHelper.getItemEnchantmentLevel(enchantment, itemstack2) == 0) { -+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment) || EnchantmentHelper.getItemEnchantmentLevel(enchantment, itemstack2) == 0) { // Purpur - itemstack2.enchant(enchantment, (Integer) entry.getValue()); +- if (!enchantment.isCurse() || itemenchantments_a.getLevel(enchantment) == 0) { ++ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment) || itemenchantments_a.getLevel(enchantment) == 0) { // Purpur + itemenchantments_a.upgrade(enchantment, entry.getIntValue()); + } } - } -@@ -250,7 +252,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { - } - - Map map = (Map) EnchantmentHelper.getEnchantments(item).entrySet().stream().filter((entry) -> { -- return ((Enchantment) entry.getKey()).isCurse(); -+ return org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains((Enchantment) entry.getKey()); // Purpur - }).collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - - EnchantmentHelper.setEnchantments(map, itemstack1); -@@ -266,6 +268,20 @@ public class GrindstoneMenu extends AbstractContainerMenu { - itemstack1.setRepairCost(AnvilMenu.calculateIncreasedRepairCost(itemstack1.getBaseRepairCost())); - } - -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveAttributes && itemstack1.getTag() != null) { -+ for (String key : itemstack1.getTag().getAllKeys()) { -+ if (!key.equals("display")) { -+ itemstack1.getTag().remove(key); -+ } -+ } -+ } -+ -+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveDisplay && itemstack1.getTag() != null) { -+ itemstack1.getTag().remove("display"); -+ } -+ // Purpur end -+ - return itemstack1; +@@ -237,10 +239,71 @@ public class GrindstoneMenu extends AbstractContainerMenu { + }); } -@@ -327,7 +343,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { ++ // Purpur start ++ private java.util.List> GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST = java.util.List.of( ++ // DataComponents.MAX_STACK_SIZE, ++ // DataComponents.DAMAGE, ++ // DataComponents.BLOCK_STATE, ++ DataComponents.CUSTOM_DATA, ++ // DataComponents.MAX_DAMAGE, ++ // DataComponents.UNBREAKABLE, ++ // DataComponents.CUSTOM_NAME, ++ // DataComponents.ITEM_NAME, ++ // DataComponents.LORE, ++ // DataComponents.RARITY, ++ // DataComponents.ENCHANTMENTS, ++ // DataComponents.CAN_PLACE_ON, ++ // DataComponents.CAN_BREAK, ++ DataComponents.ATTRIBUTE_MODIFIERS, ++ DataComponents.CUSTOM_MODEL_DATA, ++ // DataComponents.HIDE_ADDITIONAL_TOOLTIP, ++ // DataComponents.HIDE_TOOLTIP, ++ // DataComponents.REPAIR_COST, ++ // DataComponents.CREATIVE_SLOT_LOCK, ++ // DataComponents.ENCHANTMENT_GLINT_OVERRIDE, ++ // DataComponents.INTANGIBLE_PROJECTILE, ++ // DataComponents.FOOD, ++ // DataComponents.FIRE_RESISTANT, ++ // DataComponents.TOOL, ++ // DataComponents.STORED_ENCHANTMENTS, ++ DataComponents.DYED_COLOR, ++ // DataComponents.MAP_COLOR, ++ // DataComponents.MAP_ID, ++ // DataComponents.MAP_DECORATIONS, ++ // DataComponents.MAP_POST_PROCESSING, ++ // DataComponents.CHARGED_PROJECTILES, ++ // DataComponents.BUNDLE_CONTENTS, ++ // DataComponents.POTION_CONTENTS, ++ DataComponents.SUSPICIOUS_STEW_EFFECTS ++ // DataComponents.WRITABLE_BOOK_CONTENT, ++ // DataComponents.WRITTEN_BOOK_CONTENT, ++ // DataComponents.TRIM, ++ // DataComponents.DEBUG_STICK_STATE, ++ // DataComponents.ENTITY_DATA, ++ // DataComponents.BUCKET_ENTITY_DATA, ++ // DataComponents.BLOCK_ENTITY_DATA, ++ // DataComponents.INSTRUMENT, ++ // DataComponents.OMINOUS_BOTTLE_AMPLIFIER, ++ // DataComponents.RECIPES, ++ // DataComponents.LODESTONE_TRACKER, ++ // DataComponents.FIREWORK_EXPLOSION, ++ // DataComponents.FIREWORKS, ++ // DataComponents.PROFILE, ++ // DataComponents.NOTE_BLOCK_SOUND, ++ // DataComponents.BANNER_PATTERNS, ++ // DataComponents.BASE_COLOR, ++ // DataComponents.POT_DECORATIONS, ++ // DataComponents.CONTAINER, ++ // DataComponents.BEES, ++ // DataComponents.LOCK, ++ // DataComponents.CONTAINER_LOOT, ++ ); ++ // Purpur end ++ + private ItemStack removeNonCursesFrom(ItemStack item) { + ItemEnchantments itemenchantments = EnchantmentHelper.updateEnchantments(item, (itemenchantments_a) -> { + itemenchantments_a.removeIf((holder) -> { +- return !((Enchantment) holder.value()).isCurse(); ++ return !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()); + }); + }); + +@@ -255,6 +318,23 @@ public class GrindstoneMenu extends AbstractContainerMenu { + } + + item.set(DataComponents.REPAIR_COST, i); ++ ++ // Purpur start ++ net.minecraft.core.component.DataComponentPatch.Builder builder = net.minecraft.core.component.DataComponentPatch.builder(); ++ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveAttributes) { ++ item.getComponents().forEach(typedDataComponent -> { ++ if (GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST.contains(typedDataComponent.type())) { ++ builder.remove(typedDataComponent.type()); ++ } ++ }); ++ } ++ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveDisplay) { ++ builder.remove(DataComponents.CUSTOM_NAME); ++ builder.remove(DataComponents.LORE); ++ } ++ item.applyComponents(builder.build()); ++ // Purpur end ++ + return item; + } + +@@ -316,7 +396,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } @@ -13762,10 +13448,10 @@ index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c 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..1acb41fab25bdbc4109913b111dbe3b0e106af3f 100644 +index 9992599dbe4f4a430e822a44b03c00505abfbfaf..3fea9339420aa38b303ccf6c154aec246e617b5b 100644 --- a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java +++ b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java -@@ -95,7 +95,7 @@ public class InventoryMenu extends RecipeBookMenu { +@@ -97,7 +97,7 @@ public class InventoryMenu extends RecipeBookMenu { public boolean mayPickup(Player playerEntity) { ItemStack itemstack = this.getItem(); @@ -13775,7 +13461,7 @@ index 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..1acb41fab25bdbc4109913b111dbe3b0 @Override diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index 62e1b7096fa659778b737b3d520389e73138dc5d..3756de835ea87e3a4fb87cbf77365ffd87957ea9 100644 +index 7de5e47f9a54263734eeef855a2dc07ef64d30ea..7215af6cc91f48b040c23c54536d4aac8d293497 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 { @@ -13789,10 +13475,10 @@ index 62e1b7096fa659778b737b3d520389e73138dc5d..3756de835ea87e3a4fb87cbf77365ffd return itemstack; diff --git a/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java -index 4703f23316f82a1a942907b46d2d6dcb7d70ec37..162798f57a05b78121fa6c4fadf5adee80fbe221 100644 +index a15d5ff872dbd77f3c3145e0328f3d02e431ff8c..1dcf36d502990d32fc4cd3ea69c3ea334baed69a 100644 --- a/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java +++ b/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java -@@ -30,11 +30,18 @@ public class PlayerEnderChestContainer extends SimpleContainer { +@@ -31,11 +31,18 @@ public class PlayerEnderChestContainer extends SimpleContainer { } public PlayerEnderChestContainer(Player owner) { @@ -13813,10 +13499,10 @@ index 4703f23316f82a1a942907b46d2d6dcb7d70ec37..162798f57a05b78121fa6c4fadf5adee this.activeChest = blockEntity; } diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java -index 6b81be03f87967124b046708557e05d519aa79e4..b47cc957f9e4936b15b80a6f685ddddb5b289298 100644 +index 786e4a8700cb84b16dd9b8892a0d1d5803924d81..b108ca4c7900ccf6a14ebea01c21c103459054f8 100644 --- a/src/main/java/net/minecraft/world/item/ArmorItem.java +++ b/src/main/java/net/minecraft/world/item/ArmorItem.java -@@ -67,7 +67,7 @@ public class ArmorItem extends Item implements Equipable { +@@ -69,7 +69,7 @@ public class ArmorItem extends Item implements Equipable { return false; } else { LivingEntity entityliving = (LivingEntity) list.get(0); @@ -13826,7 +13512,7 @@ index 6b81be03f87967124b046708557e05d519aa79e4..b47cc957f9e4936b15b80a6f685ddddb // CraftBukkit start Level world = pointer.level(); diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java -index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32bdb1ad44f 100644 +index 1634a7d5ff06583408cf2f02f2b5f90931b1e02a..dfe8473a880cbddfc3ac6a9c97f1a500624eeb38 100644 --- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java +++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java @@ -58,6 +58,14 @@ public class ArmorStandItem extends Item { @@ -13834,21 +13520,21 @@ index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32b } // CraftBukkit end + // Purpur start -+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) { -+ entityarmorstand.setCustomName(itemstack.getHoverName()); -+ if (world.purpurConfig.armorstandSetNameVisible) { -+ entityarmorstand.setCustomNameVisible(true); -+ } ++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) { ++ entityarmorstand.setCustomName(null); ++ } ++ if (world.purpurConfig.armorstandSetNameVisible) { ++ entityarmorstand.setCustomNameVisible(true); + } + // Purpur end worldserver.addFreshEntityWithPassengers(entityarmorstand); 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 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea27985a5efc84 100644 +index 9fd2d97ff0e05578a3e6a0b86dc1974691845c5d..58343722399404530d497648155dbc254d6a865a 100644 --- a/src/main/java/net/minecraft/world/item/AxeItem.java +++ b/src/main/java/net/minecraft/world/item/AxeItem.java -@@ -55,13 +55,15 @@ public class AxeItem extends DiggerItem { +@@ -56,13 +56,15 @@ public class AxeItem extends DiggerItem { Level level = context.getLevel(); BlockPos blockPos = context.getClickedPos(); Player player = context.getPlayer(); @@ -13866,7 +13552,7 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798 return InteractionResult.PASS; } // Paper end -@@ -69,32 +71,41 @@ public class AxeItem extends DiggerItem { +@@ -70,32 +72,41 @@ public class AxeItem extends DiggerItem { CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); } @@ -13882,7 +13568,7 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798 + level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, state)); + // Purpur end if (player != null) { - itemStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(context.getHand())); + itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); } - return InteractionResult.sidedSuccess(level.isClientSide); @@ -13920,28 +13606,20 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798 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 8d2c0accadaf0c5d28e7db6e62a05f6c619cf02f..f33fcd7bca6f315c4b4cf1f5063f4772790ad20d 100644 +index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..7572c289758001c7417a192f0e6e994ffa8408b3 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 { +@@ -157,7 +157,16 @@ public class BlockItem extends Item { } protected boolean updateCustomBlockEntityTag(BlockPos pos, Level world, @Nullable Player player, ItemStack stack, BlockState state) { - return BlockItem.updateCustomBlockEntityTag(world, player, pos, stack); + // Purpur start + boolean handled = updateCustomBlockEntityTag(world, player, pos, stack); -+ if (world.purpurConfig.persistentTileEntityDisplayNames && stack.hasTag()) { -+ CompoundTag display = stack.getTagElement("display"); -+ if (display != null) { -+ BlockEntity blockEntity = world.getBlockEntity(pos); -+ if (blockEntity != null) { -+ if (display.contains("Name", 8)) { -+ blockEntity.setPersistentDisplayName(display.getString("Name")); -+ } -+ if (display.contains("Lore", 9)) { -+ blockEntity.setPersistentLore(display.getList("Lore", 8)); -+ } -+ } ++ if (world.purpurConfig.persistentTileEntityLore) { ++ BlockEntity blockEntity1 = world.getBlockEntity(pos); ++ if (blockEntity1 != null) { ++ blockEntity1.setPersistentLore(stack.getOrDefault(DataComponents.LORE, net.minecraft.world.item.component.ItemLore.EMPTY)); + } + } + return handled; @@ -13949,79 +13627,68 @@ index 8d2c0accadaf0c5d28e7db6e62a05f6c619cf02f..f33fcd7bca6f315c4b4cf1f5063f4772 } @Nullable -@@ -287,7 +304,7 @@ public class BlockItem extends Item { +@@ -219,6 +228,7 @@ public class BlockItem extends Item { - @Override - public void onDestroyed(ItemEntity entity) { -- if (this.block instanceof ShulkerBoxBlock) { -+ if (this.block instanceof ShulkerBoxBlock && entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed) { - ItemStack itemstack = entity.getItem(); - CompoundTag nbttagcompound = BlockItem.getBlockEntityData(itemstack); + if (tileentity != null) { + if (!world.isClientSide && tileentity.onlyOpCanSetNbt() && (player == null || !(player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place"))))) { // Spigot - add permission ++ if (!(!world.isClientSide && world.purpurConfig.silkTouchEnabled && tileentity instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity && player.getBukkitEntity().hasPermission("purpur.drop.spawners"))) + return false; + } + +@@ -259,6 +269,7 @@ public class BlockItem extends Item { + ItemContainerContents itemcontainercontents = (ItemContainerContents) entity.getItem().set(DataComponents.CONTAINER, ItemContainerContents.EMPTY); + + if (itemcontainercontents != null) { ++ if (entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed && entity.getItem().is(Items.SHULKER_BOX)) // Purpur + ItemUtils.onContainerDestroyed(entity, itemcontainercontents.nonEmptyItemsCopy()); + } diff --git a/src/main/java/net/minecraft/world/item/BoatItem.java b/src/main/java/net/minecraft/world/item/BoatItem.java -index 67a5a201d0b26ca7b27e6d0c3ffb9f8b6e16bce0..ec3d60b561de45349b705b7f14592be930af4b91 100644 +index eb74d45ad458b80cf8455297c3bc550186adaea3..ef01856c487e4ab982996e01537618233592ac32 100644 --- a/src/main/java/net/minecraft/world/item/BoatItem.java +++ b/src/main/java/net/minecraft/world/item/BoatItem.java -@@ -71,6 +71,11 @@ public class BoatItem extends Item { +@@ -72,6 +72,11 @@ public class BoatItem extends Item { entityboat.setVariant(this.type); entityboat.setYRot(user.getYRot()); + // Purpur start -+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) { -+ entityboat.setCustomName(itemstack.getHoverName()); ++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) { ++ entityboat.setCustomName(null); + } + // Purpur end if (!world.noCollision(entityboat, entityboat.getBoundingBox())) { return InteractionResultHolder.fail(itemstack); } else { diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java -index 08d597db1a5345a343777a01427655e6bf2c926b..d45a2f49c82d00801578c34e5f5277fc5e82be87 100644 +index 5ca843df5b4caa668953e5e36a9b20fabeb35046..ff39d3614f360918d74b54b817bc227f89d34c9c 100644 --- a/src/main/java/net/minecraft/world/item/BowItem.java +++ b/src/main/java/net/minecraft/world/item/BowItem.java -@@ -38,13 +38,13 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable { - float f = BowItem.getPowerForTime(j); +@@ -29,9 +29,9 @@ public class BowItem extends ProjectileWeaponItem { + int i = this.getUseDuration(stack) - remainingUseTicks; + float f = getPowerForTime(i); + if (!((double)f < 0.1)) { +- List list = draw(stack, itemStack, player); ++ List list = draw(stack, itemStack, player, !((itemStack.is(Items.ARROW) && world.purpurConfig.infinityWorksWithNormalArrows) || (itemStack.is(Items.TIPPED_ARROW) && world.purpurConfig.infinityWorksWithTippedArrows) || (itemStack.is(Items.SPECTRAL_ARROW) && world.purpurConfig.infinityWorksWithSpectralArrows))); + if (!world.isClientSide() && !list.isEmpty()) { +- this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null); ++ this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset, f == 1.0F, null); // Purpur + } - if ((double) f >= 0.1D) { -- boolean flag1 = flag && itemstack1.is(Items.ARROW); -+ boolean flag1 = flag && ((itemstack1.is(Items.ARROW) && world.purpurConfig.infinityWorksWithNormalArrows) || (itemstack1.is(Items.TIPPED_ARROW) && world.purpurConfig.infinityWorksWithTippedArrows) || (itemstack1.is(Items.SPECTRAL_ARROW) && world.purpurConfig.infinityWorksWithSpectralArrows)); // Purpur if (!world.isClientSide) { - - if (!world.isClientSide) { - ArrowItem itemarrow = (ArrowItem) (itemstack1.getItem() instanceof ArrowItem ? itemstack1.getItem() : Items.ARROW); - AbstractArrow entityarrow = itemarrow.createArrow(world, itemstack1, entityhuman); - -- entityarrow.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, f * 3.0F, 1.0F); -+ entityarrow.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset); // Purpur - if (f == 1.0F) { - entityarrow.setCritArrow(true); - } -@@ -64,6 +64,13 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable { - if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) { - entityarrow.setSecondsOnFire(100); - } -+ // Purpur start -+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MOB_LOOTING, stack); -+ -+ if (lootingLevel > 0) { -+ entityarrow.setLootingLevel(lootingLevel); -+ } -+ // Purpur end - // CraftBukkit start - org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityhuman, stack, itemstack1, entityarrow, entityhuman.getUsedItemHand(), f, !flag1); - if (event.isCancelled()) { -@@ -132,7 +139,7 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable { - ItemStack itemstack = user.getItemInHand(hand); - boolean flag = !user.getProjectile(itemstack).isEmpty(); - -- if (!user.getAbilities().instabuild && !flag) { -+ if (!(world.purpurConfig.infinityWorksWithoutArrows && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, itemstack) > 0) && !user.getAbilities().instabuild && !flag) { // Purpur - return InteractionResultHolder.fail(itemstack); + world.playSound( +@@ -81,7 +81,7 @@ public class BowItem extends ProjectileWeaponItem { + public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { + ItemStack itemStack = user.getItemInHand(hand); + boolean bl = !user.getProjectile(itemStack).isEmpty(); +- if (!user.hasInfiniteMaterials() && !bl) { ++ if (!(world.purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemStack) > 0) && !user.hasInfiniteMaterials() && !bl) { + return InteractionResultHolder.fail(itemStack); } else { user.startUsingItem(hand); diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java -index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe1964bf4038 100644 +index 49557d6f22c5725c663a231deab019d4f6fe95fa..046652e8f9c5dcdf7c90acb9391214cac46bd7d8 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java -@@ -195,7 +195,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -194,7 +194,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { // CraftBukkit end if (!flag2) { return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit @@ -14030,7 +13697,7 @@ index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe19 int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); -@@ -203,7 +203,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -202,7 +202,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { world.playSound(entityhuman, blockposition, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); for (int l = 0; l < 8; ++l) { @@ -14040,56 +13707,32 @@ index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe19 return true; diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java -index f3a428f80c265639250114498b10067b4bf1ada1..211d8e59a9b3460b346e5f8cf581df70b05d1b8f 100644 +index 0f6504a7160bc304b3af554f8740c65e2987cd37..9a8092602c96ddd77c8e6fcfe7a6f5ed733023a2 100644 --- a/src/main/java/net/minecraft/world/item/CrossbowItem.java +++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java -@@ -64,7 +64,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { - ItemStack itemstack = user.getItemInHand(hand); - - if (CrossbowItem.isCharged(itemstack)) { -- CrossbowItem.performShooting(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), 1.0F); -+ CrossbowItem.performShooting(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), (float) world.purpurConfig.crossbowProjectileOffset); // Purpur - CrossbowItem.setCharged(itemstack, false); - return InteractionResultHolder.consume(itemstack); - } else if (!user.getProjectile(itemstack).isEmpty()) { -@@ -114,7 +114,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { - // Paper end - Add EntityLoadCrossbowEvent - int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, crossbow); - int j = i == 0 ? 1 : 3; -- boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild; // Paper - Add EntityLoadCrossbowEvent -+ boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, crossbow) > 0); // Paper - Add EntityLoadCrossbowEvent // Purpur - ItemStack itemstack1 = shooter.getProjectile(crossbow); - ItemStack itemstack2 = itemstack1.copy(); - -@@ -291,6 +291,14 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { - entityarrow.setPierceLevel((byte) i); - } - -+ // Purpur start -+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MOB_LOOTING, crossbow); -+ -+ if (lootingLevel > 0) { -+ entityarrow.setLootingLevel(lootingLevel); -+ } -+ // Purpur end -+ - return entityarrow; +@@ -60,7 +60,7 @@ public class CrossbowItem extends ProjectileWeaponItem { + ItemStack itemStack = user.getItemInHand(hand); + ChargedProjectiles chargedProjectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES); + if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { +- this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), 1.0F, null); ++ this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), (float) world.purpurConfig.crossbowProjectileOffset, null); // Purpur + return InteractionResultHolder.consume(itemStack); + } else if (!user.getProjectile(itemStack).isEmpty()) { + this.startSoundPlayed = false; +@@ -107,7 +107,7 @@ public class CrossbowItem extends ProjectileWeaponItem { + return CrossbowItem.tryLoadProjectiles(shooter, crossbow, true); } - -@@ -300,7 +308,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { - - for (int i = 0; i < list.size(); ++i) { - ItemStack itemstack1 = (ItemStack) list.get(i); -- boolean flag = entity instanceof Player && ((Player) entity).getAbilities().instabuild; -+ boolean flag = entity instanceof Player && ((Player) entity).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0); // Purpur - - if (!itemstack1.isEmpty()) { - if (i == 0) { + private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow, boolean consume) { +- List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, consume); ++ List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY, crossbow) > 0) || consume); + // Paper end - Add EntityLoadCrossbowEvent + if (!list.isEmpty()) { + crossbow.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java -index 52ff8331f2859ee4bf39bf2fa6631bed7eed2f18..848a36a740576a0dd9e4ad50d1dd3ff07bd1d537 100644 +index 2202798612cad53aff28c499b8909a7292a37ad5..5ed2b7d15686fc9aa6dc7c03c337433cb3ee2cbd 100644 --- a/src/main/java/net/minecraft/world/item/DyeColor.java +++ b/src/main/java/net/minecraft/world/item/DyeColor.java -@@ -101,4 +101,10 @@ public enum DyeColor implements StringRepresentable { +@@ -105,4 +105,10 @@ public enum DyeColor implements StringRepresentable { public String getSerializedName() { return this.name; } @@ -14101,10 +13744,10 @@ index 52ff8331f2859ee4bf39bf2fa6631bed7eed2f18..848a36a740576a0dd9e4ad50d1dd3ff0 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java -index a3bd507793994e9cc87a956871a8afbb8ca9460d..ef2197a23aef0a4215fae09bd4618e449e14c64e 100644 +index 4ebd634cff286b10868e26eeb3ecf34abdcab22e..7dc811335caa46870d1d895899a1e6c21980382d 100644 --- a/src/main/java/net/minecraft/world/item/EggItem.java +++ b/src/main/java/net/minecraft/world/item/EggItem.java -@@ -24,7 +24,7 @@ public class EggItem extends Item { +@@ -27,7 +27,7 @@ public class EggItem extends Item implements ProjectileItem { ThrownEgg entityegg = new ThrownEgg(world, user); entityegg.setItem(itemstack); @@ -14114,10 +13757,10 @@ index a3bd507793994e9cc87a956871a8afbb8ca9460d..ef2197a23aef0a4215fae09bd4618e44 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 a0bc8bb8d88e96457a2be0befe1fd69ef4973e11..26b0084f0b8c707f6d2b90e4cf6de7e92b4617c0 100644 +index ded33fd166cbb95917f7e321875acc4222caff46..da43fd53a5c44cc0ed7d1fa5297b77c43a894fc5 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 { +@@ -27,7 +27,7 @@ public class EndCrystalItem extends Item { BlockPos blockposition = context.getClickedPos(); BlockState iblockdata = world.getBlockState(blockposition); @@ -14127,7 +13770,7 @@ index a0bc8bb8d88e96457a2be0befe1fd69ef4973e11..26b0084f0b8c707f6d2b90e4cf6de7e9 } else { BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java -index 8c8cf8705107c95d9a4eab28b5845ae13c4ffb3c..8031e38c66468676b3b4a7443d6678eec6b1e8a4 100644 +index 20a91d798d31a71b3c05efa2cc5bda55494e26cc..11b04455f09d8bfdf44499bb8359dc715c2daffd 100644 --- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java +++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java @@ -24,7 +24,7 @@ public class EnderpearlItem extends Item { @@ -14149,62 +13792,45 @@ index 8c8cf8705107c95d9a4eab28b5845ae13c4ffb3c..8031e38c66468676b3b4a7443d6678ee // Paper end - PlayerLaunchProjectileEvent if (user instanceof net.minecraft.server.level.ServerPlayer) { diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -index e1c8b24a92ea63a645406522a3c2fb5efd87f01a..0f6c1716103514dedf46e7068fd79e8b9b94e15d 100644 +index 218f2f085309f04438f8b07bc41cf242583db2dc..ea8e49b42b9dde74784189430be66ed6978015dd 100644 --- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -@@ -15,6 +15,7 @@ import net.minecraft.util.ByIdMap; - import net.minecraft.world.InteractionHand; - import net.minecraft.world.InteractionResult; - import net.minecraft.world.InteractionResultHolder; -+import net.minecraft.world.entity.EquipmentSlot; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.entity.projectile.FireworkRocketEntity; - import net.minecraft.world.item.context.UseOnContext; -@@ -76,6 +77,14 @@ public class FireworkRocketItem extends Item { +@@ -65,6 +65,14 @@ public class FireworkRocketItem extends Item implements ProjectileItem { com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) { user.awardStat(Stats.ITEM_USED.get(this)); + // Purpur start + if (world.purpurConfig.elytraDamagePerFireworkBoost > 0) { -+ ItemStack chestItem = user.getItemBySlot(EquipmentSlot.CHEST); ++ ItemStack chestItem = user.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.CHEST); + if (chestItem.getItem() == Items.ELYTRA) { -+ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerFireworkBoost, user, (entityliving) -> entityliving.broadcastBreakEvent(EquipmentSlot.CHEST)); ++ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerFireworkBoost, user, net.minecraft.world.entity.EquipmentSlot.CHEST); + } + } + // Purpur end - if (event.shouldConsume() && !user.getAbilities().instabuild) { - itemStack.shrink(1); + if (event.shouldConsume() && !user.hasInfiniteMaterials()) { + itemStack.shrink(1); } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/world/item/HangingEntityItem.java b/src/main/java/net/minecraft/world/item/HangingEntityItem.java -index b2ad6d230de2c29f371178bccde1111c7532ee70..6667926519a0f1c151e53f59cce36e7417dfc1cd 100644 +index 530167ce8e5bb72a418f8ec61411e38a5892fd72..35dc7546793dba34bf6debad3f214f61a8fb4f4e 100644 --- a/src/main/java/net/minecraft/world/item/HangingEntityItem.java +++ b/src/main/java/net/minecraft/world/item/HangingEntityItem.java -@@ -48,7 +48,7 @@ public class HangingEntityItem extends Item { - return InteractionResult.FAIL; - } else { - Level world = context.getLevel(); -- Object object; -+ Entity object; // Purpur +@@ -73,6 +73,11 @@ public class HangingEntityItem extends Item { - if (this.type == EntityType.PAINTING) { - Optional optional = Painting.create(world, blockposition1, enumdirection); -@@ -72,6 +72,11 @@ public class HangingEntityItem extends Item { - - if (nbttagcompound != null) { - EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, nbttagcompound); + if (!customdata.isEmpty()) { + EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, customdata); + // Purpur start -+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) { -+ object.setCustomName(itemstack.getHoverName()); ++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) { ++ ((Entity) object).setCustomName(null); + } + // Purpur end } if (((HangingEntity) object).survives()) { diff --git a/src/main/java/net/minecraft/world/item/HoeItem.java b/src/main/java/net/minecraft/world/item/HoeItem.java -index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b9984857028 100644 +index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..28df1b3230762e52b5458ac93a85c9a5d41eb6a6 100644 --- a/src/main/java/net/minecraft/world/item/HoeItem.java +++ b/src/main/java/net/minecraft/world/item/HoeItem.java -@@ -45,15 +45,23 @@ public class HoeItem extends DiggerItem { +@@ -46,15 +46,23 @@ public class HoeItem extends DiggerItem { public InteractionResult useOn(UseOnContext context) { Level level = context.getLevel(); BlockPos blockPos = context.getClickedPos(); @@ -14235,7 +13861,7 @@ index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b99 if (!level.isClientSide) { consumer.accept(context); if (player != null) { -@@ -61,7 +69,7 @@ public class HoeItem extends DiggerItem { +@@ -62,7 +70,7 @@ public class HoeItem extends DiggerItem { } } @@ -14245,10 +13871,10 @@ index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b99 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 a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c76e15d363 100644 +index 028d86b7c26724b955e88373c80af5fea7869d67..1545ec1759526ab88838309133e2a16c634ce074 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -454,6 +454,7 @@ public final class ItemStack { +@@ -475,6 +475,7 @@ public final class ItemStack implements DataComponentHolder { world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 for (BlockState blockstate : blocks) { blockstate.update(true, false); @@ -14256,22 +13882,22 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7 } world.preventPoiUpdated = false; -@@ -485,6 +486,7 @@ public final class ItemStack { +@@ -506,6 +507,7 @@ public final class ItemStack implements DataComponentHolder { if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically - block.getBlock().onPlace(block, world, newblockposition, oldBlock, true, context); // Paper - pass context + block.onPlace(world, newblockposition, oldBlock, true, context); // Paper - pass context } + block.getBlock().forgetPlacer(); // Purpur world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point } -@@ -613,6 +615,16 @@ public final class ItemStack { +@@ -636,6 +638,16 @@ public final class ItemStack implements DataComponentHolder { return this.isDamageableItem() && this.getDamageValue() > 0; } + // Purpur start + public float getDamagePercent() { + if (isDamaged()) { -+ return (float) getDamageValue() / (float) getItem().getMaxDamage(); ++ return (float) getDamageValue() / (float) getMaxDamage(); + } else { + return 0F; + } @@ -14279,9 +13905,9 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7 + // Purpur end + public int getDamageValue() { - return this.tag == null ? 0 : this.tag.getInt("Damage"); + return Mth.clamp((Integer) this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage()); } -@@ -632,7 +644,7 @@ public final class ItemStack { +@@ -653,7 +665,7 @@ public final class ItemStack implements DataComponentHolder { int j; if (amount > 0) { @@ -14290,117 +13916,89 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7 int k = 0; for (int l = 0; j > 0 && l < amount; ++l) { -@@ -687,6 +699,12 @@ public final class ItemStack { - if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - Add EntityDamageItemEvent - breakCallback.accept(entity); - Item item = this.getItem(); -+ // Purpur start -+ if (item == Items.ELYTRA) { -+ setDamageValue(item.getMaxDamage() - 1); -+ return; -+ } -+ // Purpur end - // 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); -@@ -1217,7 +1235,7 @@ public final class ItemStack { - - ListTag nbttaglist = this.tag.getList("Enchantments", 10); - -- nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte) level)); -+ nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels) ? (byte) level : (short) level)); // Purpur - processEnchantOrder(this.tag); // Paper - } - -@@ -1225,6 +1243,12 @@ public final class ItemStack { - return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; +@@ -729,6 +741,12 @@ public final class ItemStack implements DataComponentHolder { + this.hurtAndBreak(amount, randomsource, entity, () -> { // Paper - Add EntityDamageItemEvent + entity.broadcastBreakEvent(slot); + Item item = this.getItem(); ++ // Purpur start ++ if (item == Items.ELYTRA) { ++ setDamageValue(getMaxDamage() - 1); ++ return; ++ } ++ // Purpur end + // 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); +@@ -1210,6 +1228,16 @@ public final class ItemStack implements DataComponentHolder { + return !((ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).isEmpty(); } + // Purpur start + public boolean hasEnchantment(Enchantment enchantment) { -+ return isEnchanted() && EnchantmentHelper.deserializeEnchantments(getEnchantmentTags()).containsKey(enchantment); ++ if (isEnchanted()) { ++ ItemEnchantments enchantments = this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); ++ return new net.minecraft.advancements.critereon.EnchantmentPredicate(enchantment, net.minecraft.advancements.critereon.MinMaxBounds.Ints.atLeast(1)).containedIn(enchantments); ++ } ++ return false; + } + // Purpur end + - public void addTagElement(String key, Tag element) { - this.getOrCreateTag().put(key, element); + public ItemEnchantments getEnchantments() { + return (ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); } diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java -index b43598ee4035d9c53a40629dd4021b58c04132c8..c2c58a0788bfda5c1775194cbb9ddb406b882292 100644 +index d00b59efb754594cf532f8598f4b6d3b29693232..42b322879629afb2d2fc64a215f010f5d5ce9e02 100644 --- a/src/main/java/net/minecraft/world/item/Items.java +++ b/src/main/java/net/minecraft/world/item/Items.java -@@ -316,7 +316,7 @@ public class Items { +@@ -338,7 +338,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); - public static final Item SPAWNER = registerBlock(Blocks.SPAWNER); + public static final Item SPAWNER = registerBlock(new org.purpurmc.purpur.item.SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur - public static final Item CHEST = registerBlock(Blocks.CHEST); + public static final Item CHEST = registerBlock(Blocks.CHEST, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)); public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE); public static final Item FARMLAND = registerBlock(Blocks.FARMLAND); -@@ -1535,7 +1535,7 @@ public class Items { +@@ -1909,7 +1909,7 @@ public class Items { "sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, new Item.Properties().food(Foods.SWEET_BERRIES)) ); public static final Item GLOW_BERRIES = registerItem( - "glow_berries", new ItemNameBlockItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) -+ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur ++ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur ); - public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE); - public static final Item SOUL_CAMPFIRE = registerBlock(Blocks.SOUL_CAMPFIRE); -@@ -1715,6 +1715,13 @@ public class Items { - ((BlockItem)item).registerBlocks(Item.BY_BLOCK, item); - } - -+ // Purpur start -+ if (item.getFoodProperties() != null) { -+ Foods.ALL_PROPERTIES.put(key.location().getPath(), item.getFoodProperties()); -+ Foods.DEFAULT_PROPERTIES.put(key.location().getPath(), item.getFoodProperties().copy()); -+ } -+ // Purpur end -+ - return Registry.register(BuiltInRegistries.ITEM, key, item); - } - } + public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)); + public static final Item SOUL_CAMPFIRE = registerBlock( diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index d8dd99ec8bf7444c5a3c426db3a9c13e334dc0ff..8d3c1897044f9a2bbe1911e1a72dc9a00fb246df 100644 +index ce461b1a8d7fab87ae28e30205f6fab67f1808b6..608390ed36710a419de1542b80340dd3fcc7299c 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -235,6 +235,7 @@ public class MapItem extends ComplexItem { - MapItemSavedData worldmap = MapItem.getSavedData(map, world); - - if (worldmap != null) { -+ worldmap.isExplorerMap = true; // Purpur - if (world.dimension() == worldmap.dimension) { - int i = 1 << worldmap.scale; - int j = worldmap.centerX; +@@ -195,6 +195,7 @@ public class MapItem extends ComplexItem { + public static void renderBiomePreviewMap(ServerLevel world, ItemStack map) { + MapItemSavedData mapItemSavedData = getSavedData(map, world); + if (mapItemSavedData != null) { ++ mapItemSavedData.isExplorerMap = true; // Purpur + if (world.dimension() == mapItemSavedData.dimension) { + int i = 1 << mapItemSavedData.scale; + int j = mapItemSavedData.centerX; diff --git a/src/main/java/net/minecraft/world/item/MilkBucketItem.java b/src/main/java/net/minecraft/world/item/MilkBucketItem.java -index f33977d95b6db473be4f95075ba99caf90ad0220..56dc04d8875971ee9a5d077a695509af74fe2473 100644 +index 0f83ae4b0d5f52ff9ccfff6bbcc31153d45bd619..d0751274e89042715cab8e9e72387042356e3244 100644 --- a/src/main/java/net/minecraft/world/item/MilkBucketItem.java +++ b/src/main/java/net/minecraft/world/item/MilkBucketItem.java -@@ -5,6 +5,8 @@ import net.minecraft.server.level.ServerPlayer; - import net.minecraft.stats.Stats; - import net.minecraft.world.InteractionHand; - import net.minecraft.world.InteractionResultHolder; -+import net.minecraft.world.effect.MobEffectInstance; -+import net.minecraft.world.effect.MobEffects; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.level.Level; -@@ -31,7 +33,9 @@ public class MilkBucketItem extends Item { - } +@@ -26,7 +26,9 @@ public class MilkBucketItem extends Item { + stack.consume(1, user); if (!world.isClientSide) { -+ MobEffectInstance badOmen = user.getEffect(MobEffects.BAD_OMEN); ++ net.minecraft.world.effect.MobEffectInstance badOmen = user.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN); // Purpur user.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.MILK); // CraftBukkit + if (!world.purpurConfig.milkCuresBadOmen && badOmen != null) user.addEffect(badOmen); // Purpur } 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 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976d533d54e 100644 +index 66074445d3908b9bb1c8d70e1e27d057720ec8e5..0fd4f2ab929df479360755a3f1e58a933ae59520 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -119,8 +119,9 @@ public class MinecartItem extends Item { +@@ -120,8 +120,9 @@ public class MinecartItem extends Item { BlockState iblockdata = world.getBlockState(blockposition); if (!iblockdata.is(BlockTags.RAILS)) { @@ -14412,7 +14010,7 @@ index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976 ItemStack itemstack = context.getItemInHand(); if (world instanceof ServerLevel) { -@@ -145,6 +146,6 @@ public class MinecartItem extends Item { +@@ -146,6 +147,6 @@ public class MinecartItem extends Item { itemstack.shrink(1); return InteractionResult.sidedSuccess(world.isClientSide); @@ -14421,22 +14019,41 @@ index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976 } } diff --git a/src/main/java/net/minecraft/world/item/NameTagItem.java b/src/main/java/net/minecraft/world/item/NameTagItem.java -index a0b3c2d3b3f86ecd6cb80ff767839d29ca4f4f68..61b4430d6dd73b5406c4879e41ff80a1b6f67f84 100644 +index 774c982f28b4f127fc3f036c19dfb47fb9ae3264..d49b60e7e643498b49c03593dc0da2f8e4459902 100644 --- a/src/main/java/net/minecraft/world/item/NameTagItem.java +++ b/src/main/java/net/minecraft/world/item/NameTagItem.java -@@ -20,6 +20,7 @@ public class NameTagItem extends Item { +@@ -23,6 +23,7 @@ public class NameTagItem extends Item { if (!event.callEvent()) return InteractionResult.PASS; LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle(); newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null); + if (user.level().purpurConfig.armorstandFixNametags && entity instanceof net.minecraft.world.entity.decoration.ArmorStand) entity.setCustomNameVisible(true); // Purpur - if (event.isPersistent() && newEntity instanceof Mob) { - ((Mob) newEntity).setPersistenceRequired(); - // Paper end - Add PlayerNameEntityEvent + if (event.isPersistent() && newEntity instanceof Mob mob) { + // Paper end - Add PlayerNameEntityEvent + mob.setPersistenceRequired(); +diff --git a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java +index f91ce87491b18f4f4ae6458192d1f320b308102a..aec96d297401b705ca2af97904739afdf1134574 100644 +--- a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java ++++ b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java +@@ -131,6 +131,14 @@ public abstract class ProjectileWeaponItem extends Item { + entityarrow.setPierceLevel((byte) k); + } + ++ // Purpur start ++ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.LOOTING, weaponStack); ++ ++ if (lootingLevel > 0) { ++ entityarrow.setLootingLevel(lootingLevel); ++ } ++ // Purpur end ++ + return entityarrow; + } + diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f28f3cd72 100644 +index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..6b7dbb570f8a698c87c6bce992d84d87b55176e6 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java -@@ -46,9 +46,12 @@ public class ShovelItem extends DiggerItem { +@@ -47,9 +47,12 @@ public class ShovelItem extends DiggerItem { BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); BlockState blockState3 = null; Runnable afterAction = null; // Paper @@ -14452,7 +14069,7 @@ index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { afterAction = () -> { // Paper if (!level.isClientSide()) { -@@ -75,7 +78,7 @@ public class ShovelItem extends DiggerItem { +@@ -76,7 +79,7 @@ public class ShovelItem extends DiggerItem { } } @@ -14462,10 +14079,10 @@ index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f return InteractionResult.PASS; } diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java -index bc8186a5bc3a98b35fad570729dd4ba52efab238..caab0c1e2bc5696080750797cbf1c93f57799f7d 100644 +index 32b170551a2f5bdc88d29f4d03750bfe3974e71b..a41fb0dd26af367fc2470a7913a84d864bc505f7 100644 --- a/src/main/java/net/minecraft/world/item/SnowballItem.java +++ b/src/main/java/net/minecraft/world/item/SnowballItem.java -@@ -25,7 +25,7 @@ public class SnowballItem extends Item { +@@ -28,7 +28,7 @@ public class SnowballItem extends Item implements ProjectileItem { Snowball entitysnowball = new Snowball(world, user); entitysnowball.setItem(itemstack); @@ -14475,31 +14092,30 @@ index bc8186a5bc3a98b35fad570729dd4ba52efab238..caab0c1e2bc5696080750797cbf1c93f 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 3bfbf7daa190b03f978b9fc72233c18c383b6659..afed52ed201193867f19054c5b379270a6fbe480 100644 +index 9cea8da84f39bb3f687139ef213ccea358724dee..076e6858222b92f8409f1f5cad398582c1fd6bcb 100644 --- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java +++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java -@@ -68,6 +68,16 @@ public class SpawnEggItem extends Item { +@@ -74,6 +74,15 @@ public class SpawnEggItem extends Item { Spawner spawner = (Spawner) tileentity; - entitytypes = this.getType(itemstack.getTag()); + entitytypes = this.getType(itemstack); + + // 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())); ++ 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); + world.gameEvent((Entity) context.getPlayer(), (Holder) 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 f47f793c62a919fb65c081ddb82d597a978d3b20..3bbb44ae3da68afbd6012df68dee277a7dbf98c0 100644 +index 369955746f4b51f69fa01103e3771dd74fc6c8f0..e6edd3a0fa2578900cdbe8bd588219dc3fd3af5f 100644 --- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java +++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java -@@ -18,7 +18,7 @@ public class ThrowablePotionItem extends PotionItem { +@@ -21,7 +21,7 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem { if (!world.isClientSide) { ThrownPotion thrownPotion = new ThrownPotion(world, user); thrownPotion.setItem(itemStack); @@ -14509,21 +14125,21 @@ index f47f793c62a919fb65c081ddb82d597a978d3b20..3bbb44ae3da68afbd6012df68dee277a 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 a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd6898335454951868c867a06 100644 +index 47de500fddb0716d142f8f5876a82a95afaa06fa..905a020dd7b365d51d5addadbbeb9555d03c5238 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 { +@@ -76,11 +76,19 @@ public class TridentItem extends Item implements ProjectileItem { if (k == 0) { ThrownTrident entitythrowntrident = new ThrownTrident(world, entityhuman, stack); - entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, 1.0F); + entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, (float) world.purpurConfig.tridentProjectileOffset); // Purpur - if (entityhuman.getAbilities().instabuild) { + if (entityhuman.hasInfiniteMaterials()) { entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; } + // Purpur start -+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, stack); ++ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, stack); + + if (lootingLevel > 0) { + entitythrowntrident.setLootingLevel(lootingLevel); @@ -14533,7 +14149,7 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186 // CraftBukkit start // Paper start - PlayerLaunchProjectileEvent 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()); -@@ -128,6 +136,14 @@ public class TridentItem extends Item implements Vanishable { +@@ -123,6 +131,14 @@ public class TridentItem extends Item implements ProjectileItem { f3 *= f6 / f5; f4 *= f6 / f5; org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f2, f3, f4); // CraftBukkit @@ -14541,7 +14157,7 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186 + // Purpur start + ItemStack chestItem = entityhuman.getItemBySlot(EquipmentSlot.CHEST); + if (chestItem.getItem() == Items.ELYTRA && world.purpurConfig.elytraDamagePerTridentBoost > 0) { -+ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, (entity) -> entity.broadcastBreakEvent(EquipmentSlot.CHEST)); ++ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, EquipmentSlot.CHEST); + } + // Purpur end + @@ -14549,10 +14165,10 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186 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 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a449f2268f 100644 +index e314f36951e9ac15c57137e24fce8c410373130a..21dfb8e91c5427ac12133de2c05d923d87adf5ba 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -@@ -36,6 +36,7 @@ public final class Ingredient implements Predicate { +@@ -41,6 +41,7 @@ public final class Ingredient implements Predicate { @Nullable private IntList stackingIds; public boolean exact; // CraftBukkit @@ -14560,7 +14176,7 @@ index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a4 public static final Codec CODEC = Ingredient.codec(true); public static final Codec CODEC_NONEMPTY = Ingredient.codec(false); -@@ -67,6 +68,12 @@ public final class Ingredient implements Predicate { +@@ -72,6 +73,12 @@ public final class Ingredient implements Predicate { } else if (this.isEmpty()) { return itemstack.isEmpty(); } else { @@ -14574,25 +14190,10 @@ index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a4 int i = aitemstack.length; diff --git a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -index 04c39359585d909dedbdfd78f6cbdc06b926607a..127950c54ae057b3d0eb62e8f81d5eef6f11a36c 100644 +index 81cc05c929d612898609965d82454b89cd18f9f5..fa73c3d4b58ad8379963a9866d8f09e1d6abd663 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java +++ b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -@@ -7,6 +7,14 @@ public class ArrowInfiniteEnchantment extends Enchantment { - super(weight, EnchantmentCategory.BOW, slotTypes); - } - -+ // Purpur start -+ @Override -+ public boolean canEnchant(net.minecraft.world.item.ItemStack stack) { -+ // we have to cheat the system because this class is loaded before purpur's config is loaded -+ return (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity ? EnchantmentCategory.BOW_AND_CROSSBOW : EnchantmentCategory.BOW).canEnchant(stack.getItem()); -+ } -+ // Purpur end -+ - @Override - public int getMinCost(int level) { - return 20; -@@ -19,6 +27,6 @@ public class ArrowInfiniteEnchantment extends Enchantment { +@@ -7,6 +7,6 @@ public class ArrowInfiniteEnchantment extends Enchantment { @Override public boolean checkCompatibility(Enchantment other) { @@ -14600,45 +14201,11 @@ index 04c39359585d909dedbdfd78f6cbdc06b926607a..127950c54ae057b3d0eb62e8f81d5eef + return !(other instanceof MendingEnchantment) && super.checkCompatibility(other) || other instanceof MendingEnchantment && org.purpurmc.purpur.PurpurConfig.allowInfinityMending; // Purpur } } -diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java -index afd74b274aa46b1e2187935ebeb2a8824a133867..4f8d8665cb90b746dc59913ec270839c4e5dba91 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java -@@ -113,6 +113,20 @@ public enum EnchantmentCategory { - public boolean canEnchant(Item item) { - return item instanceof Vanishable || Block.byItem(item) instanceof Vanishable || BREAKABLE.canEnchant(item); - } -+ // Purpur start -+ }, -+ BOW_AND_CROSSBOW { -+ @Override -+ public boolean canEnchant(Item item) { -+ return item instanceof BowItem || item instanceof CrossbowItem; -+ } -+ }, -+ WEAPON_AND_SHEARS { -+ @Override -+ public boolean canEnchant(Item item) { -+ return WEAPON.canEnchant(item) || item instanceof net.minecraft.world.item.ShearsItem; -+ } -+ // Purpur end - }; - - public abstract boolean canEnchant(Item item); diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java -index 496a9b9b095bd322fba8229a5d47e2a0107aeb96..8ffa04b583da86a9aa6cabe7d978373825b82b32 100644 +index d2f0463b0e74983eb2e3dfca9a268e9502b86257..6d0363cec691996be416ab22ef9d825196399158 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java +++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java -@@ -47,7 +47,7 @@ public class EnchantmentHelper { - } - - public static int getEnchantmentLevel(CompoundTag nbt) { -- return Mth.clamp(nbt.getInt("lvl"), 0, 255); -+ return Mth.clamp(nbt.getInt("lvl"), 0, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels) ? 255 : 32767); // Purpur - } - - @Nullable -@@ -266,6 +266,29 @@ public class EnchantmentHelper { +@@ -237,6 +237,29 @@ public class EnchantmentHelper { return getItemEnchantmentLevel(Enchantments.CHANNELING, stack) > 0; } @@ -14666,32 +14233,51 @@ index 496a9b9b095bd322fba8229a5d47e2a0107aeb96..8ffa04b583da86a9aa6cabe7d9783738 + // Purpur end + @Nullable - public static Entry getRandomItemWith(Enchantment enchantment, LivingEntity entity) { + public static java.util.Map.Entry getRandomItemWith(Enchantment enchantment, LivingEntity entity) { return getRandomItemWith(enchantment, entity, stack -> true); -diff --git a/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java -index 7f1ffc0ac402fcf0ec086986e959ecc9f78dde03..1351d52374d1c2367932e5ecd5f4637955fb14c9 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java -@@ -7,6 +7,14 @@ public class LootBonusEnchantment extends Enchantment { - super(rarity, target, slotTypes); - } +diff --git a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java +index af18de11dd55938b6091f5ab183bd3fe4e8df152..2c741860afa1fa4d5798c68b84ec3fe13157ff09 100644 +--- a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java ++++ b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java +@@ -37,7 +37,7 @@ public class ItemEnchantments implements TooltipProvider { + public static final ItemEnchantments EMPTY = new ItemEnchantments(new Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), true); + // Paper end + public static final int MAX_LEVEL = 255; +- private static final Codec LEVEL_CODEC = Codec.intRange(0, 255); ++ private static final Codec LEVEL_CODEC = Codec.intRange(0, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)); // Purpur + private static final Codec>> LEVELS_CODEC = Codec.unboundedMap( // Paper + BuiltInRegistries.ENCHANTMENT.holderByNameCodec(), LEVEL_CODEC + ) +@@ -72,7 +72,7 @@ public class ItemEnchantments implements TooltipProvider { + + for (Entry> entry : enchantments.object2IntEntrySet()) { + int i = entry.getIntValue(); +- if (i < 0 || i > 255) { ++ if (i < 0 || i > (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)) { // Purpur + throw new IllegalArgumentException("Enchantment " + entry.getKey() + " has invalid level " + i); + } + } +@@ -169,13 +169,13 @@ public class ItemEnchantments implements TooltipProvider { + if (level <= 0) { + this.enchantments.removeInt(enchantment.builtInRegistryHolder()); + } else { +- this.enchantments.put(enchantment.builtInRegistryHolder(), Math.min(level, 255)); ++ this.enchantments.put(enchantment.builtInRegistryHolder(), Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767))); + } + } + + public void upgrade(Enchantment enchantment, int level) { + if (level > 0) { +- this.enchantments.merge(enchantment.builtInRegistryHolder(), Math.min(level, 255), Integer::max); ++ this.enchantments.merge(enchantment.builtInRegistryHolder(), Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)), Integer::max); + } + } -+ // Purpur start -+ @Override -+ public boolean canEnchant(net.minecraft.world.item.ItemStack stack) { -+ // we have to cheat the system because this class is loaded before purpur's config is loaded -+ return (org.purpurmc.purpur.PurpurConfig.allowShearsLooting && this.category == EnchantmentCategory.WEAPON ? EnchantmentCategory.WEAPON_AND_SHEARS : this.category).canEnchant(stack.getItem()); -+ } -+ // Purpur end -+ - @Override - public int getMinCost(int level) { - return 15 + (level - 1) * 9; diff --git a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java -index 02feea12c998f37098b72becf6bfaf6b27d155de..9c89a85d934955c9388cfe1361f13e70e699d279 100644 +index 0efc8d997b34302c3e0a5d7ec73a11a940dbeefe..af157881d440b34cfe79fbc9b03cc9ef28515eb8 100644 --- a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java +++ b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java -@@ -149,7 +149,12 @@ public class MerchantOffer { +@@ -131,7 +131,12 @@ public class MerchantOffer { } public void updateDemand() { @@ -14706,10 +14292,10 @@ index 02feea12c998f37098b72becf6bfaf6b27d155de..9c89a85d934955c9388cfe1361f13e70 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 65c3e91ac4541c0150057dc9f012eb1ee566516e..40c199812ecf7b16fe5a17c18cb0d6d3ce258910 100644 +index f57e1b78204dff661ad5d3ee93a88a00330af2dc..967af8771ff8564c715d89f4b4b69b16c25add59 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java -@@ -57,6 +57,7 @@ public abstract class BaseSpawner { +@@ -59,6 +59,7 @@ public abstract class BaseSpawner { } public boolean isNearPlayer(Level world, BlockPos pos) { @@ -14731,10 +14317,10 @@ index ea0aee88c7d901034427db201c1b2430f8a1d522..1f28bfb435c1e4d97da713f96c452aba if (range < 0.0 || 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 e2cb206841b346ace1f392d63790fcec03d57076..392b48f4cb7645282bd5eb1fceb947179325289b 100644 +index b9eea5996b7190b656a9c37bf96706a6b41a19f1..1dbb4a5ca3e9b9197ccc040d1d660e4c3bd58227 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -97,7 +97,7 @@ public class Explosion { +@@ -98,7 +98,7 @@ public class Explosion { this.hitPlayers = Maps.newHashMap(); this.level = world; this.source = entity; @@ -14743,7 +14329,7 @@ index e2cb206841b346ace1f392d63790fcec03d57076..392b48f4cb7645282bd5eb1fceb94717 this.x = x; this.y = y; this.z = z; -@@ -425,10 +425,27 @@ public class Explosion { +@@ -426,10 +426,29 @@ public class Explosion { public void explode() { // CraftBukkit start @@ -14762,18 +14348,20 @@ index e2cb206841b346ace1f392d63790fcec03d57076..392b48f4cb7645282bd5eb1fceb94717 + } + }else { + Location location = new Location(this.level.getWorld(), this.x, this.y, this.z); -+ if(!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, this.damageSource.explodedBlockState).callEvent()) { ++ org.bukkit.block.Block block = location.getBlock(); ++ org.bukkit.block.BlockState blockState = (this.damageSource.blockState != null) ? this.damageSource.blockState : block.getState(); ++ if (!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, blockState).callEvent()) { + this.wasCanceled = true; + return; + } + } + //Purpur end + - this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); + this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); Set set = Sets.newHashSet(); boolean flag = true; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index f239b14fd9c884dc7905a9e0456c2198bf1205e6..52fcce3b1c01c221becadc39334dc3b1de12e688 100644 +index 5854c76fadd8fe08d0d0ca5d01ce218b86a508c1..1397f54cef6cc23ba99a4faa36bf862318da9270 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -175,6 +175,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -14843,11 +14431,10 @@ index f239b14fd9c884dc7905a9e0456c2198bf1205e6..52fcce3b1c01c221becadc39334dc3b1 this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); -@@ -1920,4 +1966,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1917,4 +1963,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return null; } // Paper end - optimize redstone (Alternate Current) -+ + // Purpur start + public boolean isNether() { + return getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER; @@ -14859,10 +14446,10 @@ index f239b14fd9c884dc7905a9e0456c2198bf1205e6..52fcce3b1c01c221becadc39334dc3b1 + // 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 ffa5f8be4aefb451352e1c6db84f36adca3a044d..88b13e6eeec956c10b486e4811b1e0dae0fd990e 100644 +index d0383cef6e204cc806903666d296287e1c530ed3..27fccd091535f7587aaaa1621361dc1835381b89 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -256,7 +256,7 @@ public final class NaturalSpawner { +@@ -251,7 +251,7 @@ public final class NaturalSpawner { blockposition_mutableblockposition.set(l, i, i1); double d0 = (double) l + 0.5D; double d1 = (double) i1 + 0.5D; @@ -14872,66 +14459,65 @@ index ffa5f8be4aefb451352e1c6db84f36adca3a044d..88b13e6eeec956c10b486e4811b1e0da 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 18d2ff1baa2db0b97f2565eac006fbc4e81022fa..58d29c89e8e54fac143982c40c9aecc855b6cfd5 100644 +index 923357251ad950ec4f893e8771fcfa99de8a60c5..78a341ac80806f86f2ca0bd895fb091a9257519e 100644 --- a/src/main/java/net/minecraft/world/level/block/AnvilBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AnvilBlock.java -@@ -62,6 +62,54 @@ public class AnvilBlock extends FallingBlock { +@@ -59,6 +59,53 @@ public class AnvilBlock extends FallingBlock { + return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getClockWise()); + } ++ // Purpur start - repairable/damageable anvils ++ @Override ++ protected net.minecraft.world.ItemInteractionResult useItemOn(final net.minecraft.world.item.ItemStack stack, final BlockState state, final Level world, final BlockPos pos, final Player player, final net.minecraft.world.InteractionHand hand, final BlockHitResult hit) { ++ if (world.purpurConfig.anvilRepairIngotsAmount > 0 && stack.is(net.minecraft.world.item.Items.IRON_INGOT)) { ++ if (stack.getCount() < world.purpurConfig.anvilRepairIngotsAmount) { ++ // not enough iron ingots, play "error" sound and consume ++ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); ++ return net.minecraft.world.ItemInteractionResult.CONSUME; ++ } ++ if (state.is(Blocks.DAMAGED_ANVIL)) { ++ world.setBlock(pos, Blocks.CHIPPED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); ++ } else if (state.is(Blocks.CHIPPED_ANVIL)) { ++ world.setBlock(pos, Blocks.ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); ++ } else if (state.is(Blocks.ANVIL)) { ++ // anvil is already fully repaired, play "error" sound and consume ++ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); ++ return net.minecraft.world.ItemInteractionResult.CONSUME; ++ } ++ if (!player.getAbilities().instabuild) { ++ stack.shrink(world.purpurConfig.anvilRepairIngotsAmount); ++ } ++ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_PLACE, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); ++ return net.minecraft.world.ItemInteractionResult.CONSUME; ++ } ++ if (world.purpurConfig.anvilDamageObsidianAmount > 0 && stack.is(net.minecraft.world.item.Items.OBSIDIAN)) { ++ if (stack.getCount() < world.purpurConfig.anvilDamageObsidianAmount) { ++ // not enough obsidian, play "error" sound and consume ++ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); ++ return net.minecraft.world.ItemInteractionResult.CONSUME; ++ } ++ if (state.is(Blocks.DAMAGED_ANVIL)) { ++ world.destroyBlock(pos, false); ++ } else if (state.is(Blocks.CHIPPED_ANVIL)) { ++ world.setBlock(pos, Blocks.DAMAGED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); ++ } else if (state.is(Blocks.ANVIL)) { ++ world.setBlock(pos, Blocks.CHIPPED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); ++ } ++ if (!player.getAbilities().instabuild) { ++ stack.shrink(world.purpurConfig.anvilDamageObsidianAmount); ++ } ++ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_LAND, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); ++ return net.minecraft.world.ItemInteractionResult.CONSUME; ++ } ++ return net.minecraft.world.ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ } ++ // Purpur end ++ @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { -+ // Purpur start - repairable/damageable anvils -+ if (world.purpurConfig.anvilRepairIngotsAmount > 0) { -+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand); -+ if (itemstack.is(net.minecraft.world.item.Items.IRON_INGOT)) { -+ if (itemstack.getCount() < world.purpurConfig.anvilRepairIngotsAmount) { -+ // not enough iron ingots, play "error" sound and consume -+ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); -+ return InteractionResult.CONSUME; -+ } -+ if (state.is(Blocks.DAMAGED_ANVIL)) { -+ world.setBlock(pos, Blocks.CHIPPED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); -+ } else if (state.is(Blocks.CHIPPED_ANVIL)) { -+ world.setBlock(pos, Blocks.ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); -+ } else if (state.is(Blocks.ANVIL)) { -+ // anvil is already fully repaired, play "error" sound and consume -+ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); -+ return InteractionResult.CONSUME; -+ } -+ if (!player.getAbilities().instabuild) { -+ itemstack.shrink(world.purpurConfig.anvilRepairIngotsAmount); -+ } -+ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_PLACE, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); -+ return InteractionResult.CONSUME; -+ } -+ } -+ if (world.purpurConfig.anvilDamageObsidianAmount > 0) { -+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand); -+ if (itemstack.is(net.minecraft.world.item.Items.OBSIDIAN)) { -+ if (itemstack.getCount() < world.purpurConfig.anvilDamageObsidianAmount) { -+ // not enough obsidian, play "error" sound and consume -+ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_HIT, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); -+ return InteractionResult.CONSUME; -+ } -+ if (state.is(Blocks.DAMAGED_ANVIL)) { -+ world.destroyBlock(pos, false); -+ } else if (state.is(Blocks.CHIPPED_ANVIL)) { -+ world.setBlock(pos, Blocks.DAMAGED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); -+ } else if (state.is(Blocks.ANVIL)) { -+ world.setBlock(pos, Blocks.CHIPPED_ANVIL.defaultBlockState().setValue(FACING, state.getValue(FACING)), 3); -+ } -+ if (!player.getAbilities().instabuild) { -+ itemstack.shrink(world.purpurConfig.anvilDamageObsidianAmount); -+ } -+ world.playSound(null, pos, net.minecraft.sounds.SoundEvents.ANVIL_LAND, net.minecraft.sounds.SoundSource.BLOCKS, 1.0F, 1.0F); -+ return InteractionResult.CONSUME; -+ } -+ } -+ // Purpur end + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { if (world.isClientSide) { - 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 85484d061090d989de8246df81f8e9e5f8906072..472e5d52e948d172b678b0f8e60b442b4d65bb5b 100644 +index fad69dfc20574ab23634b14252b50929cca75b21..7082486f6b760bed2a61938f493d5124722b58e2 100644 --- a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java @@ -49,6 +49,20 @@ public class AzaleaBlock extends BushBlock implements BonemealableBlock { @@ -14956,7 +14542,7 @@ index 85484d061090d989de8246df81f8e9e5f8906072..472e5d52e948d172b678b0f8e60b442b } 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 ffcb4849d83e0f02adbb106f4543bb4898678267..700108e84cf3836a0542c5e04856a9fe254794e9 100644 +index ce9f189bdafec26360bfadd0f36a8bc2726e132b..d5465b48531fd4b4094874c135274abf985ee71a 100644 --- a/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BaseCoralPlantTypeBlock.java @@ -38,6 +38,7 @@ public abstract class BaseCoralPlantTypeBlock extends Block implements SimpleWat @@ -14968,28 +14554,28 @@ index ffcb4849d83e0f02adbb106f4543bb4898678267..700108e84cf3836a0542c5e04856a9fe 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 38fcde81d797dc46409f5a9ed426fe296d79bdfa..83fa72b5a8fde431e7035fe5cacc50e33ae506bf 100644 +index 4459685d1fb655f93a523ae50b62d6b97785ed90..a4a988ab1399702b943019e9c4e2cde3652b4e85 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -106,7 +106,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -104,7 +104,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); // 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 +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); ++ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // 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 -@@ -159,7 +159,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -157,7 +157,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); // 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 +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition, blockEntity), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state // Paper - add BlockEntity ++ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition, blockEntity), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // CraftBukkit - add state // Paper - add BlockEntity // Purpur return InteractionResult.SUCCESS; } } -@@ -183,7 +183,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -181,7 +181,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -14999,10 +14585,10 @@ index 38fcde81d797dc46409f5a9ed426fe296d79bdfa..83fa72b5a8fde431e7035fe5cacc50e3 @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 0d92bd6f1e4f3470a62f573add3490220e60ef7a..2e89b22de852f43f2694be52043799f07f14800b 100644 +index 8240c32d676a88aa23dcd052ee0136767e54fb0d..372c4ab9d390d5afd98947f21c79aae06b15064d 100644 --- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -@@ -243,7 +243,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone +@@ -244,7 +244,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone BigDripleafBlock.playTiltSound(world, blockposition, soundeffect); } @@ -15012,24 +14598,10 @@ index 0d92bd6f1e4f3470a62f573add3490220e60ef7a..2e89b22de852f43f2694be52043799f0 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 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c38c3eadb 100644 +index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b179d9548ea 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -63,6 +63,13 @@ import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; - import org.slf4j.Logger; - -+// Purpur start -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.ListTag; -+import net.minecraft.nbt.StringTag; -+import net.minecraft.world.Nameable; -+// Purpur end -+ - 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 { +@@ -89,6 +89,10 @@ public class Block extends BlockBehaviour implements ItemLike { public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; @@ -15040,30 +14612,30 @@ index 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c // Paper start public final boolean isDestroyable() { return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || -@@ -320,7 +331,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -312,7 +316,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) -> { - Block.popResource((ServerLevel) world, pos, itemstack); -+ Block.popResource((ServerLevel) world, pos, applyDisplayNameAndLoreFromTile(itemstack, blockEntity)); // Purpur ++ Block.popResource((ServerLevel) world, pos, applyLoreFromTile(itemstack, blockEntity)); // Purpur }); state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); } -@@ -339,7 +350,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -331,7 +335,7 @@ public class Block extends BlockBehaviour implements ItemLike { event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping event.callEvent(); for (org.bukkit.inventory.ItemStack drop : event.getDrops()) { - popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop)); -+ popResource(serverLevel, pos, applyDisplayNameAndLoreFromTile(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop), blockEntity)); // Purpur ++ popResource(serverLevel, pos, applyLoreFromTile(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop), blockEntity)); // Purpur } state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping -@@ -356,13 +367,53 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -348,13 +352,32 @@ 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 ++ Block.popResource(world, pos, applyLoreFromTile(itemstack1, blockEntity)); // Purpur }); state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping } @@ -15071,39 +14643,18 @@ index 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c } + // Purpur start -+ private static ItemStack applyDisplayNameAndLoreFromTile(ItemStack stack, BlockEntity blockEntity) { ++ private static ItemStack applyLoreFromTile(ItemStack stack, @Nullable BlockEntity blockEntity) { + if (stack.getItem() instanceof BlockItem) { -+ if (blockEntity != null && blockEntity.getLevel() instanceof ServerLevel && blockEntity.getLevel().purpurConfig.persistentTileEntityDisplayNames) { -+ String name = blockEntity.getPersistentDisplayName(); -+ ListTag lore = blockEntity.getPersistentLore(); -+ if (blockEntity instanceof Nameable) { -+ Nameable namedTile = (Nameable) blockEntity; -+ if (namedTile.hasCustomName()) { -+ name = Component.Serializer.toJson(namedTile.getCustomName()); -+ } ++ if (blockEntity != null && blockEntity.getLevel() instanceof ServerLevel) { ++ net.minecraft.world.item.component.ItemLore lore = blockEntity.getPersistentLore(); ++ net.minecraft.core.component.DataComponentPatch.Builder builder = net.minecraft.core.component.DataComponentPatch.builder(); ++ if (blockEntity.getLevel().purpurConfig.persistentTileEntityLore && lore != null) { ++ builder.set(net.minecraft.core.component.DataComponents.LORE, lore); + } -+ -+ if (name != null || lore != null) { -+ CompoundTag display = stack.getTagElement("display"); -+ if (display == null) { -+ display = new CompoundTag(); -+ } -+ -+ if (name != null) { -+ display.put("Name", StringTag.valueOf(name)); -+ } -+ if (lore != null) { -+ display.put("Lore", lore); -+ } -+ -+ CompoundTag tag = stack.getTag(); -+ if (tag == null) { -+ tag = new CompoundTag(); -+ } -+ tag.put("display", display); -+ -+ stack.setTag(tag); ++ if (!blockEntity.getLevel().purpurConfig.persistentTileEntityDisplayName) { ++ builder.remove(net.minecraft.core.component.DataComponents.CUSTOM_NAME); + } ++ stack.applyComponents(builder.build()); + } + } + return stack; @@ -15113,7 +14664,7 @@ index 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c 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); -@@ -446,7 +497,17 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -438,7 +461,17 @@ public class Block extends BlockBehaviour implements ItemLike { } // Paper - fix drops not preventing stats/food exhaustion } @@ -15132,7 +14683,7 @@ index 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c public boolean isPossibleToRespawnInThis(BlockState state) { return !state.isSolid() && !state.liquid(); -@@ -465,7 +526,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -457,7 +490,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -15142,10 +14693,10 @@ index 154b5a8520b13928686c6eb0e2481c3dd1d1de28..8c242b67f162a40311d7d987fd76771c 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 e7c8313cafc25858ac002e3c45e63db9e8cefee9..04eace0873f1133ccca9696282948dc7ebc6f398 100644 +index 260906f493416d98ab574a7262fce5e9b7e40c64..ce639e4a2d87202a10ef4fc73274c4b2c4e95720 100644 --- a/src/main/java/net/minecraft/world/level/block/Blocks.java +++ b/src/main/java/net/minecraft/world/level/block/Blocks.java -@@ -7380,6 +7380,7 @@ public class Blocks { +@@ -7389,6 +7389,7 @@ public class Blocks { BlockBehaviour.Properties.of() .mapColor(MapColor.PLANT) .forceSolidOff() @@ -15153,7 +14704,7 @@ index e7c8313cafc25858ac002e3c45e63db9e8cefee9..04eace0873f1133ccca9696282948dc7 .instabreak() .sound(SoundType.AZALEA) .noOcclusion() -@@ -7392,6 +7393,7 @@ public class Blocks { +@@ -7401,6 +7402,7 @@ public class Blocks { BlockBehaviour.Properties.of() .mapColor(MapColor.PLANT) .forceSolidOff() @@ -15162,12 +14713,12 @@ index e7c8313cafc25858ac002e3c45e63db9e8cefee9..04eace0873f1133ccca9696282948dc7 .sound(SoundType.FLOWERING_AZALEA) .noOcclusion() 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 bed3d9c781c7d3ca260027b4737970889a54689c..db1941ed32d141327a8b11e54b3ff9900072ad36 100644 +index a7b4b5600e3c889c69ac22294899713d50b5fe5c..a27e298ffdfa6956be9cde429d2cd45483a51fed 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java @@ -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); + protected boolean isPathfindable(BlockState state, PathComputationType type) { + return type == PathComputationType.AIR && !this.hasCollision ? true : super.isPathfindable(state, type); } + + // Purpur start @@ -15191,7 +14742,7 @@ index bed3d9c781c7d3ca260027b4737970889a54689c..db1941ed32d141327a8b11e54b3ff990 + // 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 ba4aaf850af36a84517c70581e141157c4f15b99..02ea708a5b5df9f753194cdc9312fc830af85c68 100644 +index ff4dda48116a2969704b355ff96407ba869b466e..066181ed274a492762baebf05bf51ac7848878cc 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java @@ -23,7 +23,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; @@ -15213,7 +14764,7 @@ index ba4aaf850af36a84517c70581e141157c4f15b99..02ea708a5b5df9f753194cdc9312fc83 return false; } @@ -134,4 +134,34 @@ public class CactusBlock extends Block { - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { + protected boolean isPathfindable(BlockState state, PathComputationType type) { return false; } + @@ -15248,7 +14799,7 @@ index ba4aaf850af36a84517c70581e141157c4f15b99..02ea708a5b5df9f753194cdc9312fc83 + // 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 9c7ee02d3aa3c33b45db4dc5c079495a69d60b15..5eed401d3d722c6553240aba4a8e2337ee32b263 100644 +index d6fffb0953494e8667cc456137cac0f5deebfbb6..f7a2244b998aebe354d38eec7aa22fd94ce404c9 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java @@ -133,7 +133,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB @@ -15261,7 +14812,7 @@ index 9c7ee02d3aa3c33b45db4dc5c079495a69d60b15..5eed401d3d722c6553240aba4a8e2337 @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 cdd7ab3fe589d089c0c03508721f46f6c136fc8a..6f148028c0fe503e9f6b327596d0954ce9e53269 100644 +index 655f51902e5d24643d41c4ec981743543c0890a5..e6a299eeda5d18274fa3b1fb542b217a074c1d83 100644 --- a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java @@ -71,7 +71,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { @@ -15300,10 +14851,10 @@ index cdd7ab3fe589d089c0c03508721f46f6c136fc8a..6f148028c0fe503e9f6b327596d0954c 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 47b6b83842201620bd6620f5acf11bb14334e35d..b4d2499ae39fd3f14b2600a9663ea8a823bdfbe4 100644 +index c9968934f4ecaa8d81e545f279b3001c7b1ce545..03e4fce6f8226451365fc2831b5bf1e5e6091730 100644 --- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java -@@ -36,7 +36,7 @@ public class CauldronBlock extends AbstractCauldronBlock { +@@ -37,7 +37,7 @@ public class CauldronBlock extends AbstractCauldronBlock { } protected static boolean shouldHandlePrecipitation(Level world, Biome.Precipitation precipitation) { @@ -15313,10 +14864,10 @@ index 47b6b83842201620bd6620f5acf11bb14334e35d..b4d2499ae39fd3f14b2600a9663ea8a8 @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 bdd9f38dcb16b74c5916b75713dbe5082b32497d..65bae6630a11aa1d8d1b08d1f8e2519545ad850c 100644 +index 635fc086d832c641f840cf36d18cdc0fcc3beef3..e3ff7b8059da499cfde1106f6d51156931b292dc 100644 --- a/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java -@@ -95,4 +95,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); } @@ -15342,10 +14893,10 @@ index daae7fd6e0148cfba8e359d990748a0c83a3376e..0e06b1bcd906e92c083dc74d56d6d0a2 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 305bce4d833116cc21e64fdcdfe13f03e94ff4ba..58838f3c443f80eb53c33f8aa764645240263da2 100644 +index 491474b66856fccb038ee436968c9a5d3e4bf75c..a66499c9bd9af9da5d261a3c1aa23b1d436d4008 100644 --- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -@@ -358,6 +358,7 @@ public class ChestBlock extends AbstractChestBlock implements +@@ -343,6 +343,7 @@ public class ChestBlock extends AbstractChestBlock implements } private static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) { @@ -15354,79 +14905,76 @@ index 305bce4d833116cc21e64fdcdfe13f03e94ff4ba..58838f3c443f80eb53c33f8aa7646452 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 689ba0cc4d3571efc2664e45fde00af724007934..1eebce1bb69dbf8888e5ad3818af3bff43c0ff93 100644 +index e467b96c028d0da3b1fe7c57fdf3220c63c1c6fa..9d07ed11c30bc3e7c68ecc1a8ccf5fe0af458f49 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -238,20 +238,28 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { - ItemStack itemstack = player.getItemInHand(hand); +@@ -239,18 +239,27 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { + int i = (Integer) state.getValue(ComposterBlock.LEVEL); - if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(itemstack.getItem())) { + if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { - if (i < 7 && !world.isClientSide) { -- BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, itemstack); +- BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack); - // Paper start - handle cancelled events - if (iblockdata1 == null) { -- return InteractionResult.PASS; +- return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; - } - // Paper end -+ // Purpur start -+ BlockState newState = process(i, state, world, itemstack, pos, player); -+ if (newState == null) { -+ return InteractionResult.PASS; -+ } - +- - world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0); -- player.awardStat(Stats.ITEM_USED.get(itemstack.getItem())); -- if (!player.getAbilities().instabuild) { -- itemstack.shrink(1); -- } +- player.awardStat(Stats.ITEM_USED.get(stack.getItem())); +- stack.consume(1, player); ++ // Purpur start - sneak to bulk process composter ++ BlockState newState = process(i, player, state, world, pos, stack); ++ if (newState == null) { ++ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; + } + if (world.purpurConfig.composterBulkProcess && player.isShiftKeyDown() && newState != state) { + BlockState oldState; + int oldCount, newCount, oldLevel, newLevel; + do { + oldState = newState; -+ oldCount = itemstack.getCount(); ++ oldCount = stack.getCount(); + oldLevel = oldState.getValue(ComposterBlock.LEVEL); -+ newState = process(oldLevel, oldState, world, itemstack, pos, player); ++ newState = process(oldLevel, player, oldState, world, pos, stack); + if (newState == null) { -+ return InteractionResult.PASS; ++ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; + } -+ newCount = itemstack.getCount(); ++ newCount = stack.getCount(); + newLevel = newState.getValue(ComposterBlock.LEVEL); + } while (newCount > 0 && (newCount != oldCount || newLevel != oldLevel || newState != oldState)); - } ++ } + // Purpur end - return InteractionResult.sidedSuccess(world.isClientSide); - } else if (i == 8) { -@@ -262,6 +270,26 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { + return ItemInteractionResult.sidedSuccess(world.isClientSide); + } else { +@@ -258,6 +267,25 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { } } -+ private static BlockState process(int level, BlockState state, Level world, ItemStack itemstack, BlockPos pos, Player player) { ++ // Purpur start - sneak to bulk process composter ++ private static @Nullable BlockState process(int level, Player player, BlockState state, Level world, BlockPos pos, ItemStack stack) { + if (level < 7 && !world.isClientSide) { -+ BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, itemstack); ++ BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack); + // Paper start - handle cancelled events + if (iblockdata1 == null) { -+ return iblockdata1; ++ return null; + } + // Paper end + + world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0); -+ player.awardStat(Stats.ITEM_USED.get(itemstack.getItem())); -+ if (!player.getAbilities().instabuild) { -+ itemstack.shrink(1); -+ } ++ player.awardStat(Stats.ITEM_USED.get(stack.getItem())); ++ stack.consume(1, player); + return iblockdata1; + } + return state; + } + // Purpur end + - public static BlockState insertItem(Entity user, BlockState state, ServerLevel world, ItemStack stack, BlockPos pos) { + @Override + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { 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 8fd8285e07de4a0457da507501e49a807542f3b1..e580c5a141bebdc45893b5abde01e633c864fc13 100644 +index 81fe0dea8e6e23c4a78f07fc2f9c0d68cd683f11..bff97b7d3909f2ec9e58a341b901b3741927543f 100644 --- a/src/main/java/net/minecraft/world/level/block/CoralBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CoralBlock.java @@ -59,6 +59,7 @@ public class CoralBlock extends Block { @@ -15438,12 +14986,12 @@ index 8fd8285e07de4a0457da507501e49a807542f3b1..e580c5a141bebdc45893b5abde01e633 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 5b96d1ae4bd8546311e986bc312b1f85883a67f4..2077cb5dcf2352c9d5b502744aeb9a66df256939 100644 +index 112d2feba5f75a2a873b595617780515945c10e4..5a190834baef60c7b61074393f8856a933902d81 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java @@ -179,7 +179,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @Override - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + protected 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 - Add EntityInsideBlockEvent - if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit + if (entity instanceof Ravager && world.purpurConfig.ravagerGriefableBlocks.contains(world.getBlockState(pos).getBlock()) && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)))) { // CraftBukkit // Purpur @@ -15467,18 +15015,18 @@ index 5b96d1ae4bd8546311e986bc312b1f85883a67f4..2077cb5dcf2352c9d5b502744aeb9a66 + // 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 ed57fbcfcff29a71026b0600b02daf4178d78429..31a5d3a5642123983b8c7df49be04f25141d15a2 100644 +index 42d43b7a7e3b7c53cc80b8706c130e660f2c72da..96199441202ad929ad0274574704635c538a93c7 100644 --- a/src/main/java/net/minecraft/world/level/block/DoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoorBlock.java @@ -198,6 +198,7 @@ public class DoorBlock extends Block { - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { if (!this.type.canOpenByHand()) { return InteractionResult.PASS; + } else if (requiresRedstone(world, state, pos)) { return InteractionResult.CONSUME; // Purpur } else { state = (BlockState) state.cycle(DoorBlock.OPEN); world.setBlock(pos, state, 10); -@@ -301,4 +302,18 @@ public class DoorBlock extends Block { +@@ -299,4 +300,18 @@ public class DoorBlock extends Block { flag = false; return flag; } @@ -15498,10 +15046,10 @@ index ed57fbcfcff29a71026b0600b02daf4178d78429..31a5d3a5642123983b8c7df49be04f25 + // 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 7f365143ce5c62e734eceb855ba0a02ab3a99b27..bbb266cbe23da2573d3dfb3a6edd57461988d3c5 100644 +index fbe15cdd5b9bca2ab4b1e871abbbdbff49ade8a4..23d113842bf774bdc74e0dffcc97b642bc8684f1 100644 --- a/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java -@@ -49,8 +49,8 @@ public class DragonEggBlock extends FallingBlock { +@@ -48,8 +48,8 @@ public class DragonEggBlock extends FallingBlock { } private void teleport(BlockState state, Level world, BlockPos pos) { @@ -15511,21 +15059,12 @@ index 7f365143ce5c62e734eceb855ba0a02ab3a99b27..bbb266cbe23da2573d3dfb3a6edd5746 for (int i = 0; i < 1000; ++i) { 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 f2157de3b52095657401a780a467da1f816eff98..b19461aafdb281a4eb6db6701fe7f97572ca321c 100644 ---- a/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -@@ -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; -+import net.minecraft.world.Containers; // Purpur -+import net.minecraft.world.item.Items; // Purpur - - public class EnchantmentTableBlock extends BaseEntityBlock { - public static final MapCodec CODEC = simpleCodec(EnchantmentTableBlock::new); -@@ -137,4 +139,18 @@ public class EnchantmentTableBlock extends BaseEntityBlock { - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { +diff --git a/src/main/java/net/minecraft/world/level/block/EnchantingTableBlock.java b/src/main/java/net/minecraft/world/level/block/EnchantingTableBlock.java +index 151e856dda3aa262c846ce8793650ee582bfb749..be0ed8a14e5726d5fcea1864302b18fb75fde2b4 100644 +--- a/src/main/java/net/minecraft/world/level/block/EnchantingTableBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/EnchantingTableBlock.java +@@ -124,4 +124,18 @@ public class EnchantingTableBlock extends BaseEntityBlock { + protected boolean isPathfindable(BlockState state, PathComputationType type) { return false; } + @@ -15534,8 +15073,8 @@ index f2157de3b52095657401a780a467da1f816eff98..b19461aafdb281a4eb6db6701fe7f975 + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean moved) { + BlockEntity blockEntity = level.getBlockEntity(pos); + -+ if (level.purpurConfig.enchantmentTableLapisPersists && blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) { -+ Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.LAPIS_LAZULI, enchantmentTable.getLapis())); ++ if (level.purpurConfig.enchantmentTableLapisPersists && blockEntity instanceof EnchantingTableBlockEntity enchantmentTable) { ++ net.minecraft.world.Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.LAPIS_LAZULI, enchantmentTable.getLapis())); + level.updateNeighbourForOutputSignal(pos, this); + } + @@ -15544,11 +15083,11 @@ index f2157de3b52095657401a780a467da1f816eff98..b19461aafdb281a4eb6db6701fe7f975 + // 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 4ba24bced9a2de4616a0418857d3738e0e322ea0..6660bea735dda46ab9493601f1f53b8e0075ca83 100644 +index 7272d70c672b54dcf595beafd7a2ed33c96e35cb..d7f33c676bba279661583d908d3a58c86d853545 100644 --- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java @@ -54,6 +54,14 @@ public class EndPortalBlock extends BaseEntityBlock { - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + protected 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 - Add EntityInsideBlockEvent 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)) { + // Purpur start @@ -15563,19 +15102,19 @@ index 4ba24bced9a2de4616a0418857d3738e0e322ea0..6660bea735dda46ab9493601f1f53b8e ServerLevel worldserver = ((ServerLevel) world).getServer().getLevel(resourcekey); 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 280041cc5f2a630571d9f4c8610c46e175ccf0c1..33511748479d233be0033616715661634f1275e1 100644 +index 5f9858ef8d0ec1a74d469ab4426eb1db068873fd..d7ef772444b301d0a3f167679027195e4150b064 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -@@ -92,7 +92,7 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -91,7 +91,7 @@ public class EnderChestBlock extends AbstractChestBlock i EnderChestBlockEntity enderChestBlockEntity = (EnderChestBlockEntity)blockEntity; playerEnderChestContainer.setActiveChest(enderChestBlockEntity); player.openMenu( -- new SimpleMenuProvider((syncId, inventory, playerx) -> ChestMenu.threeRows(syncId, inventory, playerEnderChestContainer), CONTAINER_TITLE) -+ new SimpleMenuProvider((syncId, inventory, playerx) -> org.purpurmc.purpur.PurpurConfig.enderChestSixRows ? getEnderChestSixRows(syncId, inventory, player, playerEnderChestContainer) : ChestMenu.threeRows(syncId, inventory, playerEnderChestContainer), CONTAINER_TITLE) // Purpur +- new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) ++ new SimpleMenuProvider((i, inventory, playerx) -> org.purpurmc.purpur.PurpurConfig.enderChestSixRows ? getEnderChestSixRows(i, inventory, player, playerEnderChestContainer) : ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) // Purpur ); player.awardStat(Stats.OPEN_ENDERCHEST); PiglinAi.angerNearbyPiglins(player, true); -@@ -103,6 +103,35 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -102,6 +102,35 @@ public class EnderChestBlock extends AbstractChestBlock i } } @@ -15612,10 +15151,10 @@ index 280041cc5f2a630571d9f4c8610c46e175ccf0c1..33511748479d233be003361671566163 public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new EnderChestBlockEntity(pos, state); 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 6e4c852c93f2418ea69e485ed3a10cbe3a6e3bd2..0c39126ce51439cce05747161aba43bce33a12d8 100644 +index d59e33e7326489c6d55d316d0130f22235f4c63c..d0ec0722496ed931b48c4e7076fddbb1ed36e111 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -110,7 +110,7 @@ public class FarmBlock extends Block { +@@ -111,7 +111,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. @@ -15624,7 +15163,7 @@ index 6e4c852c93f2418ea69e485ed3a10cbe3a6e3bd2..0c39126ce51439cce05747161aba43bc // CraftBukkit start - Interact soil org.bukkit.event.Cancellable cancellable; if (entity instanceof Player) { -@@ -124,6 +124,22 @@ public class FarmBlock extends Block { +@@ -125,6 +125,22 @@ public class FarmBlock extends Block { return; } @@ -15638,8 +15177,8 @@ index 6e4c852c93f2418ea69e485ed3a10cbe3a6e3bd2..0c39126ce51439cce05747161aba43bc + } + } + if (world.purpurConfig.farmlandTramplingFeatherFalling) { -+ Iterator armor = entity.getArmorSlots().iterator(); -+ if (armor.hasNext() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FALL_PROTECTION, armor.next()) >= (int) entity.fallDistance) { ++ Iterator armor = ((LivingEntity) entity).getArmorSlots().iterator(); ++ if (armor.hasNext() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING, armor.next()) >= (int) entity.fallDistance) { + return; + } + } @@ -15647,7 +15186,7 @@ index 6e4c852c93f2418ea69e485ed3a10cbe3a6e3bd2..0c39126ce51439cce05747161aba43bc if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { return; } -@@ -171,7 +187,7 @@ public class FarmBlock extends Block { +@@ -172,7 +188,7 @@ public class FarmBlock extends Block { } } @@ -15657,7 +15196,7 @@ index 6e4c852c93f2418ea69e485ed3a10cbe3a6e3bd2..0c39126ce51439cce05747161aba43bc } 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 30300ef3ec839dfa944c992ab50db4d3859bb02e..0d64b19dbbca9d563d90cabf0e2d32f76bfc0c62 100644 +index cf05da1c86e3018db11dc079bf50317b6639e5cc..8e9903899ac91e9431f00675c1f5ac4a18e61593 100644 --- a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +++ b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java @@ -34,12 +34,12 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements @@ -15669,7 +15208,7 @@ index 30300ef3ec839dfa944c992ab50db4d3859bb02e..0d64b19dbbca9d563d90cabf0e2d32f7 } @Override - public boolean isRandomlyTicking(BlockState state) { + protected boolean isRandomlyTicking(BlockState state) { - return (Integer) state.getValue(GrowingPlantHeadBlock.AGE) < 25; + return (Integer) state.getValue(GrowingPlantHeadBlock.AGE) < getMaxGrowthAge(); // Purpur } @@ -15734,7 +15273,7 @@ index ef364aa171a48482a45bc18cfe730ec20c3f7be6..74971d90506aa253d5ee821b5390fb25 } } 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 9c8c1df5187daefb1c8098b4d4a0976c71a7bbfd..cf4c1097d54c84b309ab02e9892d1b9e39d57490 100644 +index 013302623d3ca3ff88f242d740af935dcf4844a6..13dd8bc7d2f6b71a5f1779dde53c5c84d83538ce 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java @@ -41,7 +41,7 @@ public class IceBlock extends HalfTransparentBlock { @@ -15756,11 +15295,11 @@ index 9c8c1df5187daefb1c8098b4d4a0976c71a7bbfd..cf4c1097d54c84b309ab02e9892d1b9e } 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 1b83d44291029ce978187467832595b6dfd76dd5..69f2c6cae089aa7e1306c9dbe83d4ff582ec777c 100644 +index 784b19bc78c8ad9476b6dac37b6778a409a7c675..d49dd8b20d3785cc9482ed2a34fbd7aed4c9e537 100644 --- a/src/main/java/net/minecraft/world/level/block/KelpBlock.java +++ b/src/main/java/net/minecraft/world/level/block/KelpBlock.java @@ -72,4 +72,11 @@ public class KelpBlock extends GrowingPlantHeadBlock implements LiquidBlockConta - public FluidState getFluidState(BlockState state) { + protected FluidState getFluidState(BlockState state) { return Fluids.WATER.getSource(false); } + @@ -15772,38 +15311,38 @@ index 1b83d44291029ce978187467832595b6dfd76dd5..69f2c6cae089aa7e1306c9dbe83d4ff5 + // 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 9b3dcf1a4d4cece92a629506d341f6bfe79d13d0..0ed39daf88a98f7fa887fb45d4f7c0348a607551 100644 +index 84623c632d8c2f0fa7ec939c711316d757117d23..1851035b9fdcc076442d0699567a3b020e6425d6 100644 --- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -@@ -139,7 +139,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -137,7 +137,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override - public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { + protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - if (this.shouldSpreadLiquid(world, pos, state)) { + if (world.purpurConfig.tickFluids && this.shouldSpreadLiquid(world, pos, state)) { // Purpur world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava } -@@ -167,7 +167,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -165,7 +165,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) { + if (world.getMinecraftWorld().purpurConfig.tickFluids && state.getFluidState().isSource() || neighborState.getFluidState().isSource()) { // Purpur world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world)); } -@@ -176,7 +176,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -174,7 +174,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override - public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { + protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { - if (this.shouldSpreadLiquid(world, pos, state)) { + if (world.purpurConfig.tickFluids && this.shouldSpreadLiquid(world, pos, state)) { // Purpur world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava } 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 746c211b575ca588deadbbcd5c55b614e8660ba8..2f38bac9efc224084505e802546623260830b6d4 100644 +index 77bbdc15472d656fd40e841a70e34d3d31580819..55ae530fac54236ea5614f8e92c30febc744f179 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java @@ -29,7 +29,7 @@ public class MagmaBlock extends Block { @@ -15816,20 +15355,20 @@ index 746c211b575ca588deadbbcd5c55b614e8660ba8..2f38bac9efc224084505e80254662326 } 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 1b5cc5d6aa0b4313da980ce175c54145852d0db0..f7b724696151b73343feac1ce406fca9377f2508 100644 +index a9e3078cefcae8cc4672d514a7add162590d48df..8d5e841d8cc69bf09a9f1b6248633a72ce5fe1d7 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java @@ -60,7 +60,7 @@ public class NetherPortalBlock extends Block { @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { // Spigot + if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(world.purpurConfig.piglinPortalSpawnModifier) < world.getDifficulty().getId()) { // Spigot // Purpur while (world.getBlockState(pos).is((Block) this)) { pos = pos.below(); } @@ -92,6 +92,14 @@ public class NetherPortalBlock extends Block { - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + protected 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 - Add EntityInsideBlockEvent if (entity.canChangeDimensions()) { + // Purpur start @@ -15844,7 +15383,7 @@ index 1b5cc5d6aa0b4313da980ce175c54145852d0db0..f7b724696151b73343feac1ce406fca9 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 0fc333f240d6918e841a9221be42973839408802..13eb4dffd60ea7902d620f484df5e3f2c4688402 100644 +index acbd60a2f162fe0e254e36d0e8e7face3fc8a7b3..b8355ea1de26c4b6905f477fb4e110f1762447b4 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java @@ -16,7 +16,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; @@ -15890,10 +15429,10 @@ index 0fc333f240d6918e841a9221be42973839408802..13eb4dffd60ea7902d620f484df5e3f2 + // 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 a541dc3a6e373b30fff0abf5305e77854c190f10..ac88cb949808752a340637ffcb9d7256b7d09478 100644 +index 1d82cfe7af0dc42f88901fb0c44896771fdf8a93..43dd972b374daa1072608f3a68e812e7fb733a2b 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -@@ -94,7 +94,7 @@ public class NoteBlock extends Block { +@@ -95,7 +95,7 @@ public class NoteBlock extends Block { } private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { @@ -15903,22 +15442,22 @@ index a541dc3a6e373b30fff0abf5305e77854c190f10..ac88cb949808752a340637ffcb9d7256 // 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 713352b68f82d4c4a19a712d5207de0f99456713..d056e80c98973e9ba64adc5a8554acc8a5f3eac9 100644 +index b38fbe5121f293f425d7673a6ce49b11d0ced0d9..2a74f42672b92393b52a61c27c5b8af77c8c6070 100644 --- a/src/main/java/net/minecraft/world/level/block/ObserverBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ObserverBlock.java @@ -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) { + protected 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)) { + if (!world.getMinecraftWorld().purpurConfig.disableObserverClocks || !(neighborState.getBlock() instanceof ObserverBlock) || neighborState.getValue(ObserverBlock.FACING).getOpposite() != direction) // Purpur this.startSignal(world, pos); } 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 5835872df922b859a31b44e3723c67097f21a641..ecb595ddf21b593175c27d59fd9587e7f2d56517 100644 +index a2bd54dae4b0460d200f6d5300194a7ef5a28830..bf189a171530abfc9bba5db5a305feb391f2cbee 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -189,7 +189,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -190,7 +190,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @VisibleForTesting public static void maybeTransferFluid(BlockState state, ServerLevel world, BlockPos pos, float dripChance) { @@ -15927,7 +15466,7 @@ index 5835872df922b859a31b44e3723c67097f21a641..ecb595ddf21b593175c27d59fd9587e7 if (PointedDripstoneBlock.isStalactiteStartPos(state, world, pos)) { Optional optional = PointedDripstoneBlock.getFluidAboveStalactite(world, pos, state); -@@ -198,13 +198,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -199,13 +199,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate float f1; if (fluidtype == Fluids.WATER) { @@ -15944,7 +15483,7 @@ index 5835872df922b859a31b44e3723c67097f21a641..ecb595ddf21b593175c27d59fd9587e7 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 0dfcac8cfcbb09fe04486bff60119f7985714454..2dbf71e421156093c8bc387941eae991f5e6c957 100644 +index a6e6545402904141ffc6218a0158b0e9c67217c8..5eac1a54398dfa5571b98fb6eefca9d2bf9b2793 100644 --- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java @@ -80,7 +80,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { @@ -15957,7 +15496,7 @@ index 0dfcac8cfcbb09fe04486bff60119f7985714454..2dbf71e421156093c8bc387941eae991 } // 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 b84c48902ef24fdae17578a304e6c93dc20c5dce..e03125281767845564c48c98c3e6b6bbd269ade1 100644 +index 9603d8c84ff483030dc08e82d3579b89e5c1f6e9..8fc65c32a3c6e6842a76b36f45e1b1c23abbc480 100644 --- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java @@ -30,7 +30,7 @@ public class PoweredRailBlock extends BaseRailBlock { @@ -15970,23 +15509,23 @@ index b84c48902ef24fdae17578a304e6c93dc20c5dce..e03125281767845564c48c98c3e6b6bb } 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 088262f306755a9cb785c7a0cf0a9c66ed0965a8..000429c15117b1bcb6c60c2e692ffb3178144f51 100644 +index 0699211428f182d8d56a2ba019d89ce05c920430..351fb74d2cccd7f63c2efee197a2968f822eda42 100644 --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java -@@ -148,7 +148,7 @@ public class RespawnAnchorBlock extends Block { +@@ -149,7 +149,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 - 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 +- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, state, explodedPos, null), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state // Paper ++ if (world.purpurConfig.respawnAnchorExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, state, explodedPos, null), explosiondamagecalculator, vec3d, (float) world.purpurConfig.respawnAnchorExplosionPower, world.purpurConfig.respawnAnchorExplosionFire, world.purpurConfig.respawnAnchorExplosionEffect); // CraftBukkit - add state // Paper // 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 09c61eb5ba129e9630a756b452ef6aa61745c533..837c8399b2f490d98ca556e66018bfd471cf05bf 100644 +index b6b367492ebe2af3e63381bef935c6077f6ddb27..09f34c30d9a03751ed826b26375ac5aee778cce4 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java -@@ -137,7 +137,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -134,7 +134,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo @Nullable @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { @@ -15996,7 +15535,7 @@ index 09c61eb5ba129e9630a756b452ef6aa61745c533..837c8399b2f490d98ca556e66018bfd4 @Override 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 481611d1759c161925524a8756060fb2cc0c0bf4..04852b896fc57028a970cce04d15c304749b592d 100644 +index fa29eb15934b3dad171d27c21d99b2451cfe553b..ba4aa69425d796d306791ea193f9c6b21a065f0b 100644 --- a/src/main/java/net/minecraft/world/level/block/SlabBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SlabBlock.java @@ -138,4 +138,25 @@ public class SlabBlock extends Block implements SimpleWaterloggedBlock { @@ -16026,11 +15565,11 @@ index 481611d1759c161925524a8756060fb2cc0c0bf4..04852b896fc57028a970cce04d15c304 + // 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 a3da9536c3a3ad33d1c795673bdd7b05d6534054..9b057f3967aae5d0ca621b19d1212db91aaaee22 100644 +index 93e8e5107ac047c1f2579b4fe6b0a202edb695f6..f82d275aac7bf3949d3dcc412c7e39e115c69458 100644 --- a/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnowLayerBlock.java @@ -88,6 +88,12 @@ public class SnowLayerBlock extends Block { - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { BlockState iblockdata1 = world.getBlockState(pos.below()); + // Purpur start @@ -16043,10 +15582,10 @@ index a3da9536c3a3ad33d1c795673bdd7b05d6534054..9b057f3967aae5d0ca621b19d1212db9 } 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 e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b7b24875c 100644 +index 4f190a40b8474aa06a92c8afcc06d0044120ff7b..66c17bdfecdfbcfb2d853e561432dd51a8f7ed46 100644 --- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java -@@ -42,6 +42,60 @@ public class SpawnerBlock extends BaseEntityBlock { +@@ -42,6 +42,57 @@ public class SpawnerBlock extends BaseEntityBlock { return createTickerHelper(type, BlockEntityType.MOB_SPAWNER, world.isClientSide ? SpawnerBlockEntity::clientTick : SpawnerBlockEntity::serverTick); } @@ -16054,46 +15593,43 @@ index e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b + @Override + 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)) { -+ 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()); -+ 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")) { -+ net.kyori.adventure.text.Component displayName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName)); -+ if (name.startsWith("")) { -+ displayName = displayName.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); -+ } -+ display.put("Name", net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(displayName, java.util.Locale.ROOT))); -+ tag.put("display", display); -+ } -+ -+ List lore = level.purpurConfig.silkTouchSpawnerLore; -+ if (lore != null && !lore.isEmpty()) { -+ net.minecraft.nbt.ListTag list = new net.minecraft.nbt.ListTag(); -+ for (String line : lore) { -+ net.kyori.adventure.text.Component lineComponent = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(line, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName)); -+ if (line.startsWith("")) { -+ lineComponent = lineComponent.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); -+ } -+ list.add(net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(lineComponent, java.util.Locale.ROOT))); -+ } -+ display.put("Lore", list); -+ tag.put("display", display); -+ } -+ + ItemStack item = new ItemStack(Blocks.SPAWNER.asItem()); -+ if (entityType != null) { -+ tag.putDouble("HideFlags", ItemStack.TooltipPart.ADDITIONAL.getMask()); // hides the "Interact with Spawn Egg" tooltip -+ item.setTag(tag); ++ ++ net.minecraft.world.level.SpawnData nextSpawnData = blockEntity instanceof SpawnerBlockEntity spawnerBlock ? spawnerBlock.getSpawner().nextSpawnData : null; ++ java.util.Optional> type = java.util.Optional.empty(); ++ if (nextSpawnData != null) { ++ type = net.minecraft.world.entity.EntityType.by(nextSpawnData.getEntityToSpawn()); ++ net.minecraft.world.level.SpawnData.CODEC.encodeStart(net.minecraft.nbt.NbtOps.INSTANCE, nextSpawnData).result().ifPresent(tag -> item.set(net.minecraft.core.component.DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY.update(compoundTag -> compoundTag.put("Purpur.SpawnData", tag)))); + } + ++ if (type.isPresent()) { ++ final net.kyori.adventure.text.Component mobName = io.papermc.paper.adventure.PaperAdventure.asAdventure(type.get().getDescription()); ++ ++ String name = level.purpurConfig.silkTouchSpawnerName; ++ if (name != null && !name.isEmpty() && !name.equals("Monster Spawner")) { ++ net.kyori.adventure.text.Component displayName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName)); ++ if (name.startsWith("")) { ++ displayName = displayName.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); ++ } ++ item.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName)); ++ } ++ ++ List lore = level.purpurConfig.silkTouchSpawnerLore; ++ if (lore != null && !lore.isEmpty()) { ++ ++ List loreComponentList = new java.util.ArrayList<>(); ++ for (String line : lore) { ++ net.kyori.adventure.text.Component lineComponent = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(line, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName)); ++ if (line.startsWith("")) { ++ lineComponent = lineComponent.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); ++ } ++ loreComponentList.add(io.papermc.paper.adventure.PaperAdventure.asVanilla(lineComponent)); ++ } ++ ++ item.set(net.minecraft.core.component.DataComponents.LORE, new net.minecraft.world.item.component.ItemLore(loreComponentList, loreComponentList)); ++ } ++ item.set(net.minecraft.core.component.DataComponents.HIDE_ADDITIONAL_TOOLTIP, net.minecraft.util.Unit.INSTANCE); ++ } + popResource(level, pos, item); + } + super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops, dropExp); @@ -16105,9 +15641,9 @@ index e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b + // Purpur end + @Override - public void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { + protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { super.spawnAfterBreak(state, world, pos, tool, dropExperience); -@@ -50,6 +104,7 @@ public class SpawnerBlock extends BaseEntityBlock { +@@ -50,6 +101,7 @@ public class SpawnerBlock extends BaseEntityBlock { @Override public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { @@ -16116,7 +15652,7 @@ index e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b 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 8f3cca228f8ec1ea9379fa43af4baa7b18012dd2..7e87b4299979c9e46abb582da7a8e54a36e8dfc5 100644 +index 902825ec9ea05f4418b45f56a008d73f217bd178..6fe44572e34ad3e3a1851e73138bd8b778eb7849 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java @@ -58,7 +58,7 @@ public class SpongeBlock extends Block { @@ -16149,11 +15685,11 @@ index 8f3cca228f8ec1ea9379fa43af4baa7b18012dd2..7e87b4299979c9e46abb582da7a8e54a 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 7c41b940dd915a27856f6fa6f9e536e296deeb53..51ba321172acc9908aac456f8209dd6af6987aa8 100644 +index c6ecb378d0cb2ac05b8f22f92fb85df060038f77..b0199a8ffb1ea4cafeadedb8b833063db177b3cd 100644 --- a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -@@ -99,4 +99,14 @@ public class StonecutterBlock extends Block { - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { +@@ -98,4 +98,14 @@ public class StonecutterBlock extends Block { + protected boolean isPathfindable(BlockState state, PathComputationType type) { return false; } + @@ -16168,7 +15704,7 @@ index 7c41b940dd915a27856f6fa6f9e536e296deeb53..51ba321172acc9908aac456f8209dd6a + // 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 04957d461d0e968d443737068aaeec1d0bce78b2..7a283fbe4663cb321739f8e42ade4039d84e462b 100644 +index c48c622e92cedeaa46b929c7adfedec98dd5a3fb..6449b5c424443b5f0ee7e3fce803449418fbed2a 100644 --- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java @@ -20,7 +20,7 @@ import net.minecraft.world.level.material.FluidState; @@ -16216,10 +15752,10 @@ index 04957d461d0e968d443737068aaeec1d0bce78b2..7a283fbe4663cb321739f8e42ade4039 + // 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 b4646e26965e0f1f26c5019e7c6a13fdf22bdb47..9a76665c6369b4106d152370dc3d2f5645cb02b1 100644 +index a6f408e56fa6c9de82fd93555fe21e1b11ce1022..08ba90f760abb9fb62311dddd7b5bdbd0d9518d7 100644 --- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -169,7 +169,7 @@ public class TurtleEggBlock extends Block { +@@ -170,7 +170,7 @@ public class TurtleEggBlock extends Block { private boolean shouldUpdateHatchLevel(Level world) { float f = world.getTimeOfDay(1.0F); @@ -16228,7 +15764,7 @@ index b4646e26965e0f1f26c5019e7c6a13fdf22bdb47..9a76665c6369b4106d152370dc3d2f56 } @Override -@@ -202,6 +202,31 @@ public class TurtleEggBlock extends Block { +@@ -203,6 +203,31 @@ public class TurtleEggBlock extends Block { } private boolean canDestroyEgg(Level world, Entity entity) { @@ -16250,8 +15786,8 @@ index b4646e26965e0f1f26c5019e7c6a13fdf22bdb47..9a76665c6369b4106d152370dc3d2f56 + return false; + } + if (world.purpurConfig.turtleEggsTramplingFeatherFalling) { -+ java.util.Iterator armor = entity.getArmorSlots().iterator(); -+ return !armor.hasNext() || net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FALL_PROTECTION, armor.next()) < (int) entity.fallDistance; ++ java.util.Iterator armor = ((LivingEntity) entity).getArmorSlots().iterator(); ++ return !armor.hasNext() || net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING, armor.next()) < (int) entity.fallDistance; + } + if (entity instanceof Player) { + return true; @@ -16294,10 +15830,10 @@ index 3dec5a082606ee35a8c8d7f746480262d6a189c5..b2f6ccae9576c176263e51a232e17a08 + // 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 fb180f0bcd20e51d41cfc924029c0b23d3d26258..688d161cd6725f494366c23668ebd6ff709b1587 100644 +index bbf59b2577812e74ffd45f694b83a42e043273c0..5cb06959aeaceeb98cfee34b1df804e6642f305f 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -@@ -76,6 +76,7 @@ public class WitherSkullBlock extends SkullBlock { +@@ -79,6 +79,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(); @@ -16306,10 +15842,10 @@ index fb180f0bcd20e51d41cfc924029c0b23d3d26258..688d161cd6725f494366c23668ebd6ff 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 a6d2de3b8231168c7c38b4a83e99b2836c00af7c..7e560a28608a1016fb87cdf23d7c6a1e41ffbdf8 100644 +index 360f96689b2b0015b56d3a9954b8454193a3316f..6b3401c866d7597bea392739b32e0c20280f258a 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 -@@ -46,6 +46,7 @@ import net.minecraft.world.level.Level; +@@ -47,6 +47,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.AbstractFurnaceBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -16317,8 +15853,8 @@ index a6d2de3b8231168c7c38b4a83e99b2836c00af7c..7e560a28608a1016fb87cdf23d7c6a1e import net.minecraft.world.phys.Vec3; // CraftBukkit start import org.bukkit.craftbukkit.block.CraftBlock; -@@ -210,6 +211,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - // Paper end - cache burn durations +@@ -215,6 +216,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + } } + // Purpur start @@ -16326,21 +15862,21 @@ index a6d2de3b8231168c7c38b4a83e99b2836c00af7c..7e560a28608a1016fb87cdf23d7c6a1e + Map map = Maps.newLinkedHashMap(); + map.putAll(getFuel()); + map.put(itemStack.getItem(), burnTime); -+ cachedBurnDurations = com.google.common.collect.ImmutableMap.copyOf(map); ++ AbstractFurnaceBlockEntity.fuelCache = com.google.common.collect.ImmutableMap.copyOf(map); + } + + public static void removeFuel(ItemStack itemStack) { + Map map = Maps.newLinkedHashMap(); + map.putAll(getFuel()); + map.remove(itemStack.getItem()); -+ cachedBurnDurations = com.google.common.collect.ImmutableMap.copyOf(map); ++ AbstractFurnaceBlockEntity.fuelCache = com.google.common.collect.ImmutableMap.copyOf(map); + } + // Purpur End + // CraftBukkit start - add fields and methods private int maxStack = MAX_STACK; public List transaction = new java.util.ArrayList(); -@@ -332,6 +349,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -337,6 +354,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } ItemStack itemstack = (ItemStack) blockEntity.items.get(1); @@ -16362,7 +15898,7 @@ index a6d2de3b8231168c7c38b4a83e99b2836c00af7c..7e560a28608a1016fb87cdf23d7c6a1e boolean flag2 = !((ItemStack) blockEntity.items.get(0)).isEmpty(); boolean flag3 = !itemstack.isEmpty(); -@@ -417,6 +449,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -422,6 +454,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit setChanged(world, pos, state); } @@ -16371,10 +15907,10 @@ index a6d2de3b8231168c7c38b4a83e99b2836c00af7c..7e560a28608a1016fb87cdf23d7c6a1e private static boolean canBurn(RegistryAccess registryManager, @Nullable RecipeHolder recipe, NonNullList slots, int count) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -index 416aa989ebb18a8741cc9d605a1180ab830f6643..e38a0adf5463c48311ad08b8d2e5b5c2d989a3b5 100644 +index 6186e55014bbb9d5bedaa0e9d196879c55339d42..f4f11292d6d00f4a7c65e3e2a157bba595f70889 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -@@ -67,7 +67,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { +@@ -68,7 +68,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { public BarrelBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BARREL, pos, state); @@ -16392,7 +15928,7 @@ index 416aa989ebb18a8741cc9d605a1180ab830f6643..e38a0adf5463c48311ad08b8d2e5b5c2 this.openersCounter = new ContainerOpenersCounter() { @Override protected void onOpen(Level world, BlockPos pos, BlockState state) { -@@ -118,7 +127,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { +@@ -119,7 +128,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { @Override public int getContainerSize() { @@ -16410,7 +15946,7 @@ index 416aa989ebb18a8741cc9d605a1180ab830f6643..e38a0adf5463c48311ad08b8d2e5b5c2 } @Override -@@ -138,7 +156,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { +@@ -139,7 +157,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { @Override protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) { @@ -16429,10 +15965,10 @@ 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 4b81b0180dfc96fc6a88646838a886ca5b5d301b..2c2e819fb8d92e2de0b4981333219ed529138520 100644 +index a6ffbbc1b5021564864e42c0756342352c2b8290..5ad48d2003fbd83e60f6faa68532496131935828 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 +@@ -92,6 +92,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name public double getEffectRange() { if (this.effectRange < 0) { @@ -16449,7 +15985,7 @@ index 4b81b0180dfc96fc6a88646838a886ca5b5d301b..2c2e819fb8d92e2de0b4981333219ed5 return this.levels * 10 + 10; } else { return effectRange; -@@ -164,6 +174,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name +@@ -168,6 +178,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name int j = pos.getY(); int k = pos.getZ(); BlockPos blockposition1; @@ -16457,7 +15993,7 @@ index 4b81b0180dfc96fc6a88646838a886ca5b5d301b..2c2e819fb8d92e2de0b4981333219ed5 if (blockEntity.lastCheckY < j) { blockposition1 = pos; -@@ -197,6 +208,9 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name +@@ -201,6 +212,9 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name } } } else { @@ -16467,20 +16003,20 @@ index 4b81b0180dfc96fc6a88646838a886ca5b5d301b..2c2e819fb8d92e2de0b4981333219ed5 if (tileentitybeacon_beaconcolortracker == null || iblockdata1.getLightBlock(world, blockposition1) >= 15 && !iblockdata1.is(Blocks.BEDROCK)) { blockEntity.checkingBeamSections.clear(); blockEntity.lastCheckY = l; -@@ -216,7 +230,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name +@@ -220,7 +234,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name blockEntity.levels = BeaconBlockEntity.updateBase(world, i, j, k); } - if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) { -+ if (blockEntity.levels > 0 && (!blockEntity.beamSections.isEmpty() || (world.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { // Purpur ++ if (blockEntity.levels > 0 && (!blockEntity.beamSections.isEmpty() || (world.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper - Custom beacon ranges 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 d445ed0895293dd45c36226051f5809be8587ebe..6afaab31539667667481f7e9bfc0c6846abe661a 100644 +index 7b263fab4f0014400b3b8e7e33db32f9a125f6ba..f7a6ab35c95ffda73f17843916ddb624ad290b42 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 -@@ -47,7 +47,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -59,7 +59,7 @@ public class BeehiveBlockEntity extends BlockEntity { private final List stored = Lists.newArrayList(); @Nullable public BlockPos savedFlowerPos; @@ -16489,15 +16025,15 @@ index d445ed0895293dd45c36226051f5809be8587ebe..6afaab31539667667481f7e9bfc0c684 public BeehiveBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BEEHIVE, pos, state); -@@ -134,6 +134,22 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -146,11 +146,33 @@ public class BeehiveBlockEntity extends BlockEntity { return list; } + // Purpur start -+ public List releaseBee(BlockState iblockdata, BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { ++ public List releaseBee(BlockState iblockdata, BeehiveBlockEntity.BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { + List list = Lists.newArrayList(); + -+ BeehiveBlockEntity.releaseBee(this.level, this.worldPosition, iblockdata, data, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); ++ BeehiveBlockEntity.releaseOccupant(this.level, this.worldPosition, iblockdata, data.occupant, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); + + if (!list.isEmpty()) { + stored.remove(data); @@ -16509,10 +16045,8 @@ index d445ed0895293dd45c36226051f5809be8587ebe..6afaab31539667667481f7e9bfc0c684 + } + // Purpur end + - public void addOccupant(Entity entity, boolean hasNectar) { - this.addOccupantWithPresetTicks(entity, hasNectar, 0); - } -@@ -143,6 +159,12 @@ public class BeehiveBlockEntity extends BlockEntity { + @VisibleForDebug + public int getOccupantCount() { return this.stored.size(); } @@ -16525,125 +16059,82 @@ index d445ed0895293dd45c36226051f5809be8587ebe..6afaab31539667667481f7e9bfc0c684 // Paper start - Add EntityBlockStorage clearEntities public void clearBees() { this.stored.clear(); -@@ -207,7 +229,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -212,7 +234,7 @@ public class BeehiveBlockEntity extends BlockEntity { } - private static boolean releaseBee(Level world, BlockPos blockposition, BlockState iblockdata, BeehiveBlockEntity.BeeData tileentitybeehive_hivebee, @Nullable List list, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPos blockposition1, boolean force) { + private static boolean releaseOccupant(Level world, BlockPos blockposition, BlockState iblockdata, BeehiveBlockEntity.Occupant tileentitybeehive_c, @Nullable List list, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPos blockposition1, boolean force) { - if (!force && (world.isNight() || world.isRaining()) && tileentitybeehive_releasestatus != BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY) { + if (!force && ((world.isNight() && !world.purpurConfig.beeCanWorkAtNight) || (world.isRaining() && !world.purpurConfig.beeCanWorkInRain)) && tileentitybeehive_releasestatus != BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY) { // Purpur // CraftBukkit end return false; } else { -@@ -435,9 +457,9 @@ public class BeehiveBlockEntity extends BlockEntity { - private BeeReleaseStatus() {} +@@ -471,9 +493,9 @@ public class BeehiveBlockEntity extends BlockEntity { + } } - private static class BeeData { + public static class BeeData { // Purpur - change from private to public -- final CompoundTag entityData; -+ public final CompoundTag entityData; // Purpur - make public - int ticksInHive; - int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts - final int minOccupationTicks; +- private final BeehiveBlockEntity.Occupant occupant; ++ public final BeehiveBlockEntity.Occupant occupant; // Purpur - make public + private int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts + private int ticksInHive; + 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 9ea74d37cd951e0dc76d20ed8234b5871035566c..07a83e06e9cb6e30c600445809e49a3fd23a391a 100644 +index 7963afff4b32a0e46be9bdeb413657718cfc14f5..5168e8e9ebb54b6c00acb7f2939262eb06a7426d 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; - import net.minecraft.core.BlockPos; - import net.minecraft.core.registries.BuiltInRegistries; - import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.ListTag; -+import net.minecraft.nbt.StringTag; - import net.minecraft.network.protocol.Packet; - import net.minecraft.network.protocol.game.ClientGamePacketListener; - import net.minecraft.resources.ResourceLocation; -@@ -73,10 +75,27 @@ public abstract class BlockEntity { +@@ -87,6 +87,12 @@ public abstract class BlockEntity { if (persistentDataTag instanceof CompoundTag) { this.persistentDataContainer.putAll((CompoundTag) persistentDataTag); } + // Purpur start -+ if (nbt.contains("Purpur.persistentDisplayName")) { -+ this.persistentDisplayName = nbt.getString("Purpur.persistentDisplayName"); -+ } + if (nbt.contains("Purpur.persistentLore")) { -+ this.persistentLore = nbt.getList("Purpur.persistentLore", 8); ++ net.minecraft.world.item.component.ItemLore.CODEC.decode(net.minecraft.nbt.NbtOps.INSTANCE, nbt.getCompound("Purpur.persistentLore")).result() ++ .ifPresent(tag -> this.persistentLore = tag.getFirst()); + } + // Purpur end } // CraftBukkit end -- protected void saveAdditional(CompoundTag nbt) {} -+ protected void saveAdditional(CompoundTag nbt) { -+ // Purpur start -+ if (this.persistentDisplayName != null) { -+ nbt.put("Purpur.persistentDisplayName", StringTag.valueOf(this.persistentDisplayName)); -+ } -+ if (this.persistentLore != null) { -+ nbt.put("Purpur.persistentLore", this.persistentLore); -+ } -+ // Purpur end -+ } - - public final CompoundTag saveWithFullMetadata() { - CompoundTag nbttagcompound = this.saveWithoutMetadata(); -@@ -186,10 +205,24 @@ public abstract class BlockEntity { - - @Nullable - public Packet getUpdatePacket() { -+ // Purpur start -+ if (this instanceof net.minecraft.world.Nameable nameable && nameable.hasCustomName()) { -+ CompoundTag nbt = this.saveWithoutMetadata(); -+ nbt.remove("Items"); -+ return net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket.create(this, $ -> nbt); -+ } -+ // Purpur end - return null; +@@ -103,6 +109,15 @@ public abstract class BlockEntity { + this.loadAdditional(nbt, registryLookup); } - public CompoundTag getUpdateTag() { -+ // Purpur start -+ if (this instanceof net.minecraft.world.Nameable nameable && nameable.hasCustomName()) { -+ CompoundTag nbt = this.saveWithoutMetadata(); -+ nbt.remove("Items"); -+ return nbt; -+ } -+ // Purpur end - return new CompoundTag(); - } - -@@ -262,4 +295,25 @@ public abstract class BlockEntity { - return tag; - } - // Paper end - Sanitize sent data -+ + // Purpur start -+ private String persistentDisplayName = null; -+ private ListTag persistentLore = null; -+ -+ public void setPersistentDisplayName(String json) { -+ this.persistentDisplayName = json; ++ protected void saveAdditional(CompoundTag nbt) { ++ if (this.persistentLore != null) { ++ net.minecraft.world.item.component.ItemLore.CODEC.encodeStart(net.minecraft.nbt.NbtOps.INSTANCE, this.persistentLore).result() ++ .ifPresent(tag -> nbt.put("Purpur.persistentLore", tag)); ++ } + } ++ // Purpur end + -+ public void setPersistentLore(ListTag lore) { + protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {} + + public final CompoundTag saveWithFullMetadata(HolderLookup.Provider registryLookup) { +@@ -397,4 +412,16 @@ public abstract class BlockEntity { + + T getOrDefault(DataComponentType type, T fallback); + } ++ // Purpur start ++ @Nullable ++ private net.minecraft.world.item.component.ItemLore persistentLore = null; ++ ++ public void setPersistentLore(net.minecraft.world.item.component.ItemLore lore) { + this.persistentLore = lore; + } + -+ public String getPersistentDisplayName() { -+ return this.persistentDisplayName; -+ } -+ -+ public ListTag getPersistentLore() { ++ public @org.jetbrains.annotations.Nullable net.minecraft.world.item.component.ItemLore getPersistentLore() { + return this.persistentLore; + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -index 37e0b762b86e74f607a4541ecb7b24ad7a591d0e..7e3edd41f3a39ef14382e18b20af21e63ce0677b 100644 +index 73e532dc998e5701c1a73da846da3d3a79871b81..ff6fea842ca80c2ba51693fe62e5b74f9affdc19 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -@@ -167,7 +167,7 @@ public class ConduitBlockEntity extends BlockEntity { +@@ -168,7 +168,7 @@ public class ConduitBlockEntity extends BlockEntity { if ((l > 1 || i1 > 1 || j1 > 1) && (i == 0 && (i1 == 2 || j1 == 2) || j == 0 && (l == 2 || j1 == 2) || k == 0 && (l == 2 || i1 == 2))) { BlockPos blockposition2 = pos.offset(i, j, k); BlockState iblockdata = world.getBlockState(blockposition2); @@ -16652,43 +16143,51 @@ index 37e0b762b86e74f607a4541ecb7b24ad7a591d0e..7e3edd41f3a39ef14382e18b20af21e6 int k1 = ablock.length; for (int l1 = 0; l1 < k1; ++l1) { -@@ -187,7 +187,7 @@ public class ConduitBlockEntity extends BlockEntity { +@@ -188,13 +188,13 @@ public class ConduitBlockEntity extends BlockEntity { private static void applyEffects(Level world, BlockPos pos, List activatingBlocks) { - int i = activatingBlocks.size(); -- int j = i / 7 * 16; // Paper - Conduit API; diff on change -+ int j = i / 7 * world.purpurConfig.conduitDistance; // Paper - Conduit API; diff on change // Purpur - int k = pos.getX(); - int l = pos.getY(); - int i1 = pos.getZ(); -@@ -218,20 +218,20 @@ public class ConduitBlockEntity extends BlockEntity { - blockEntity.destroyTarget = ConduitBlockEntity.findDestroyTarget(world, pos, blockEntity.destroyTargetUUID); - blockEntity.destroyTargetUUID = null; - } else if (blockEntity.destroyTarget == null) { -- List list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(pos), (entityliving1) -> { -+ List list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(pos, world), (entityliving1) -> { // Purpur + // CraftBukkit start +- ConduitBlockEntity.applyEffects(world, pos, ConduitBlockEntity.getRange(activatingBlocks)); ++ ConduitBlockEntity.applyEffects(world, pos, ConduitBlockEntity.getRange(activatingBlocks, world)); // Purpur + } + +- public static int getRange(List list) { ++ public static int getRange(List list, Level world) { // Purpur + // CraftBukkit end + int i = list.size(); +- int j = i / 7 * 16; ++ int j = i / 7 * world.purpurConfig.conduitDistance; // Purpur + // CraftBukkit start + return j; + } +@@ -237,20 +237,20 @@ public class ConduitBlockEntity extends BlockEntity { + tileentityconduit.destroyTarget = ConduitBlockEntity.findDestroyTarget(world, blockposition, tileentityconduit.destroyTargetUUID); + tileentityconduit.destroyTargetUUID = null; + } else if (tileentityconduit.destroyTarget == null) { +- List list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(blockposition), (entityliving1) -> { ++ List list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(blockposition, world), (entityliving1) -> { // Purpur return entityliving1 instanceof Enemy && entityliving1.isInWaterOrRain(); }); if (!list1.isEmpty()) { - blockEntity.destroyTarget = (LivingEntity) list1.get(world.random.nextInt(list1.size())); + tileentityconduit.destroyTarget = (LivingEntity) list1.get(world.random.nextInt(list1.size())); } -- } else if (!blockEntity.destroyTarget.isAlive() || !pos.closerThan(blockEntity.destroyTarget.blockPosition(), 8.0D)) { -+ } else if (!blockEntity.destroyTarget.isAlive() || !pos.closerThan(blockEntity.destroyTarget.blockPosition(), world.purpurConfig.conduitDamageDistance)) { // Purpur - blockEntity.destroyTarget = null; +- } else if (!tileentityconduit.destroyTarget.isAlive() || !blockposition.closerThan(tileentityconduit.destroyTarget.blockPosition(), 8.0D)) { ++ } else if (!tileentityconduit.destroyTarget.isAlive() || !blockposition.closerThan(tileentityconduit.destroyTarget.blockPosition(), world.purpurConfig.conduitDamageDistance)) { // Purpur + tileentityconduit.destroyTarget = null; } - if (blockEntity.destroyTarget != null) { - // CraftBukkit start -- if (blockEntity.destroyTarget.hurt(world.damageSources().magic().directBlock(world, pos), 4.0F)) { // CraftBukkit -+ if (blockEntity.destroyTarget.hurt(world.damageSources().magic().directBlock(world, pos), world.purpurConfig.conduitDamageAmount)) { // CraftBukkit // Purpur - world.playSound(null, blockEntity.destroyTarget.getX(), blockEntity.destroyTarget.getY(), blockEntity.destroyTarget.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F); + // CraftBukkit start + if (damageTarget && tileentityconduit.destroyTarget != null) { +- if (tileentityconduit.destroyTarget.hurt(world.damageSources().magic().directBlock(world, blockposition), 4.0F)) { ++ if (tileentityconduit.destroyTarget.hurt(world.damageSources().magic().directBlock(world, blockposition), world.purpurConfig.conduitDamageAmount)) { // Purpur + world.playSound(null, tileentityconduit.destroyTarget.getX(), tileentityconduit.destroyTarget.getY(), tileentityconduit.destroyTarget.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F); } // CraftBukkit end -@@ -256,16 +256,22 @@ public class ConduitBlockEntity extends BlockEntity { +@@ -275,16 +275,22 @@ public class ConduitBlockEntity extends BlockEntity { } - private static AABB getDestroyRangeAABB(BlockPos pos) { + public static AABB getDestroyRangeAABB(BlockPos pos) { + // Purpur start + return getDestroyRangeAABB(pos, null); + } @@ -16710,37 +16209,37 @@ index 37e0b762b86e74f607a4541ecb7b24ad7a591d0e..7e3edd41f3a39ef14382e18b20af21e6 return entityliving.getUUID().equals(uuid); }); -diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java -index 4d1a895f3749bdcb132de199e81a9d93330c0ee6..5978f6bee32d31db8dd6af5c22ff0282fd81416a 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java -@@ -24,6 +24,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable - public float tRot; +diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java +index d47bc2f54c4722a0b8c419b99ee57eb3cb25d750..fdeabdcc781b605d6f3ee18528fd380ffff95660 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java +@@ -28,6 +28,7 @@ public class EnchantingTableBlockEntity extends BlockEntity implements Nameable private static final RandomSource RANDOM = RandomSource.create(); + @Nullable private Component name; + private int lapis = 0; // Purpur - public EnchantmentTableBlockEntity(BlockPos pos, BlockState state) { + public EnchantingTableBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.ENCHANTING_TABLE, pos, state); -@@ -35,6 +36,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable +@@ -39,6 +40,7 @@ public class EnchantingTableBlockEntity extends BlockEntity implements Nameable if (this.hasCustomName()) { - nbt.putString("CustomName", Component.Serializer.toJson(this.name)); + nbt.putString("CustomName", Component.Serializer.toJson(this.name, registryLookup)); } + nbt.putInt("Purpur.Lapis", this.lapis); // Purpur } @Override -@@ -43,6 +45,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable +@@ -47,6 +49,7 @@ public class EnchantingTableBlockEntity extends BlockEntity implements Nameable if (nbt.contains("CustomName", 8)) { - this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException + this.name = parseCustomNameSafe(nbt.getString("CustomName"), registryLookup); } + this.lapis = nbt.getInt("Purpur.Lapis"); // Purpur } - public static void bookAnimationTick(Level world, BlockPos pos, BlockState state, EnchantmentTableBlockEntity blockEntity) { -@@ -117,4 +120,14 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable - public Component getCustomName() { - return this.name; + public static void bookAnimationTick(Level world, BlockPos pos, BlockState state, EnchantingTableBlockEntity blockEntity) { +@@ -138,4 +141,14 @@ public class EnchantingTableBlockEntity extends BlockEntity implements Nameable + public void removeComponentsFromTag(CompoundTag nbt) { + nbt.remove("CustomName"); } + + // Purpur start @@ -16753,80 +16252,13 @@ index 4d1a895f3749bdcb132de199e81a9d93330c0ee6..5978f6bee32d31db8dd6af5c22ff0282 + } + // 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 927c7ea03560be0c86884cec70ee8e408e66cb07..93764bf849ad8e427bf119f6ff3dbcbcc4c2415e 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 -@@ -200,16 +200,31 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C - return this.setText((SignText) textChanger.apply(signtext), front); - } - -+ // Purpur start -+ private Component translateColors(org.bukkit.entity.Player player, String line, Style style) { -+ if (level.purpurConfig.signAllowColors) { -+ if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1"); -+ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1"); -+ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1"); -+ -+ return io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line)); -+ } else { -+ return Component.literal(line).setStyle(style); -+ } -+ } -+ // Purpur end -+ - private SignText setMessages(net.minecraft.world.entity.player.Player entityhuman, List list, SignText signtext, boolean front) { // CraftBukkit - SignText originalText = signtext; // CraftBukkit - for (int i = 0; i < list.size(); ++i) { - FilteredText filteredtext = (FilteredText) list.get(i); - Style chatmodifier = signtext.getMessage(i, entityhuman.isTextFilteringEnabled()).getStyle(); - -+ org.bukkit.entity.Player player = (org.bukkit.craftbukkit.entity.CraftPlayer) entityhuman.getBukkitEntity(); // Purpur - if (entityhuman.isTextFilteringEnabled()) { -- signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only -+ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur - } else { -- signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.raw())).setStyle(chatmodifier), Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only -+ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.raw()), chatmodifier), translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur - } - } - -@@ -349,6 +364,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C - return ClientboundBlockEntityDataPacket.create(this); - } - -+ // Purpur start -+ public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) { -+ final CompoundTag nbt = new CompoundTag(); -+ this.saveAdditional(nbt); -+ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered); -+ final String side = front ? "front_text" : "back_text"; -+ for (int i = 0; i < 4; i++) { -+ final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]); -+ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component); -+ final var text = net.kyori.adventure.text.Component.text(line); -+ final String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(text); -+ if (!nbt.contains(side)) nbt.put(side, new CompoundTag()); -+ final CompoundTag sideNbt = nbt.getCompound(side); -+ if (!sideNbt.contains("messages")) sideNbt.put("messages", new net.minecraft.nbt.ListTag()); -+ final net.minecraft.nbt.ListTag messagesNbt = sideNbt.getList("messages", Tag.TAG_STRING); -+ messagesNbt.set(i, net.minecraft.nbt.StringTag.valueOf(json)); -+ } -+ nbt.putString("PurpurEditor", "true"); -+ return ClientboundBlockEntityDataPacket.create(this, entity -> nbt); -+ } -+ // Purpur end -+ - @Override - 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 610f1d50b91ffe4b84026681cf65b237bb1d4931..5717b1c2fd5b16d439499296edd35d72b6613212 100644 +index 3a3182544ca338e81edfa64fd116092775ca0c6c..0e58011d22536051a18388c2d45fd1a30c2f5ffd 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 -@@ -172,6 +172,14 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { +@@ -168,6 +168,14 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { public static void teleportEntity(Level world, BlockPos pos, BlockState state, Entity entity, TheEndGatewayBlockEntity blockEntity) { - if (world instanceof ServerLevel && !blockEntity.isCoolingDown()) { + if (world instanceof ServerLevel worldserver && !blockEntity.isCoolingDown()) { if (entity.level().galeConfig().gameplayMechanics.fixes.checkCanChangeDimensionsBeforeUseEndGateway && world.galeConfig().gameplayMechanics.fixes.checkCanChangeDimensionsBeforeUseEndGateway && !entity.canChangeDimensions()) return; // Gale - Purpur - end gateway should check if entity can use portal + // Purpur start + if (world.purpurConfig.imposeTeleportRestrictionsOnGateways && (entity.isVehicle() || entity.isPassenger())) { @@ -16836,9 +16268,9 @@ index 610f1d50b91ffe4b84026681cf65b237bb1d4931..5717b1c2fd5b16d439499296edd35d72 + return; + } + // Purpur end - ServerLevel worldserver = (ServerLevel) world; - blockEntity.teleportCooldown = 100; + BlockPos blockposition1; + diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java b/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java index 205e223c356634bd6bc6bd58c6f0b7fda61a6f5f..bea05cb928d540a2f19b51bb7352d032b2dd69cd 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java @@ -16871,10 +16303,10 @@ index 205e223c356634bd6bc6bd58c6f0b7fda61a6f5f..bea05cb928d540a2f19b51bb7352d032 } 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 2892e586146cbc560f0bcf4b9af6d0575cb0a82e..d38d8fc7ef22fb68e867cc29dab1171c9aa6ac35 100644 +index 2034ca2edd3aff61d94416266e75402babd3e741..031fc626d2075cbe0941fecc188406712ab9953f 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 -@@ -84,7 +84,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -86,7 +86,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; @@ -16883,20 +16315,20 @@ index 2892e586146cbc560f0bcf4b9af6d0575cb0a82e..d38d8fc7ef22fb68e867cc29dab1171c protected final boolean isRandomlyTicking; protected final SoundType soundType; protected final float friction; -@@ -92,7 +92,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -94,7 +94,7 @@ public abstract class BlockBehaviour implements FeatureElement { protected final float jumpFactor; protected final boolean dynamicShape; protected final FeatureFlagSet requiredFeatures; - protected final BlockBehaviour.Properties properties; + public final BlockBehaviour.Properties properties; // Purpur - protected -> public @Nullable - protected ResourceLocation drops; + protected ResourceKey drops; diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index 995fbfa225efe40274c20608b9b30b8afa847698..c70f04cdee1e8ba6f8a15c9e38edbe0023b5ab96 100644 +index bee39dee1b96023c907407877aedf3aafaf5e1b8..5b6bc200381a486c99061f9f5b7121c2c355b477 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -111,6 +111,7 @@ public class EntityStorage implements EntityPersistentStorage { +@@ -107,6 +107,7 @@ public class EntityStorage implements EntityPersistentStorage { ListTag listTag = new ListTag(); final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk entities.forEach((entity) -> { // diff here: use entities parameter @@ -16905,10 +16337,10 @@ index 995fbfa225efe40274c20608b9b30b8afa847698..c70f04cdee1e8ba6f8a15c9e38edbe00 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 3380125f68b865977ac627579615820405bc98df..8a28952257fd6c01b0f2a4d6dffbd91c1cd1d534 100644 +index ae1e164285f5675371bf036c8a564d9f5c1dd395..976ac286b4a6b8a843d275583dacb4ca2b0c4cb2 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 { +@@ -48,7 +48,7 @@ public class PhantomSpawner implements CustomSpawner { int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds; this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; // Paper end - Ability to control player's insomnia and phantoms @@ -16917,7 +16349,7 @@ index 3380125f68b865977ac627579615820405bc98df..8a28952257fd6c01b0f2a4d6dffbd91c return 0; } else { int i = 0; -@@ -61,10 +61,10 @@ public class PhantomSpawner implements CustomSpawner { +@@ -60,10 +60,10 @@ public class PhantomSpawner implements CustomSpawner { if (!entityplayer.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityplayer.isCreative())) { // Paper - Add phantom creative and insomniac controls BlockPos blockposition = entityplayer.blockPosition(); @@ -16930,7 +16362,7 @@ index 3380125f68b865977ac627579615820405bc98df..8a28952257fd6c01b0f2a4d6dffbd91c ServerStatsCounter serverstatisticmanager = entityplayer.getStats(); int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE); boolean flag2 = true; -@@ -84,7 +84,7 @@ public class PhantomSpawner implements CustomSpawner { +@@ -83,7 +83,7 @@ public class PhantomSpawner implements CustomSpawner { if (NaturalSpawner.isValidEmptySpawnBlock(world, blockposition1, iblockdata, fluid, EntityType.PHANTOM)) { SpawnGroupData groupdataentity = null; @@ -16940,7 +16372,7 @@ index 3380125f68b865977ac627579615820405bc98df..8a28952257fd6c01b0f2a4d6dffbd91c for (int l = 0; l < k; ++l) { // Paper start - PhantomPreSpawnEvent diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 05273fa3b59d67858abffcb1ff18a6ff5885c316..6b27719bed1963183015207b21bfd4d6cc84e020 100644 +index 761c7a4a12990043bd5f4a3b970d02acdb0843a8..9707422821747c0051e2444a2ddc67fd4c70ec08 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java @@ -227,7 +227,7 @@ public abstract class FlowingFluid extends Fluid { @@ -17011,38 +16443,29 @@ index 109f71401c65f476ccf6813137386fc9fef10254..9dcdb2f4001115db0c26fdbf86531dbe @Override protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { 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 1cd7f0f1c7d62552e6609997c83f3df8dae13316..a6f745d21d982dfcbfb458472a7b2a8867d13504 100644 +index d5004290e40a1ff5e0fcfe75f8da34ae15962359..f26383cf896785333dbd6f86348d5a5f67a6731f 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -@@ -259,7 +259,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -240,7 +240,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { if ((node == null || node.costMalus < 0.0F) && maxYStep > 0 - && (blockPathTypes != BlockPathTypes.FENCE || this.canWalkOverFences()) -- && blockPathTypes != BlockPathTypes.UNPASSABLE_RAIL -+ && (this.mob.level().purpurConfig.mobsIgnoreRails || blockPathTypes != BlockPathTypes.UNPASSABLE_RAIL) // Purpur - && blockPathTypes != BlockPathTypes.TRAPDOOR - && blockPathTypes != BlockPathTypes.POWDER_SNOW) { - node = this.findAcceptedNode(x, y + 1, z, maxYStep - 1, prevFeetY, direction, nodeType); -@@ -475,7 +475,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { - return BlockPathTypes.BLOCKED; - } else { - // Paper end - Do not load chunks during pathfinding -- if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH)) { -+ if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH) || blockState.is(Blocks.STONECUTTER)) { // Purpur - return BlockPathTypes.DANGER_OTHER; - } - -@@ -509,7 +509,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { - return BlockPathTypes.TRAPDOOR; + && (pathType != PathType.FENCE || this.canWalkOverFences()) +- && pathType != PathType.UNPASSABLE_RAIL ++ && (this.mob.level().purpurConfig.mobsIgnoreRails || pathType != PathType.UNPASSABLE_RAIL) // Purpur + && pathType != PathType.TRAPDOOR + && pathType != PathType.POWDER_SNOW) { + node = this.tryJumpOn(x, y, z, maxYStep, prevFeetY, direction, nodeType, mutableBlockPos); +@@ -491,7 +491,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { + return PathType.TRAPDOOR; } else if (blockState.is(Blocks.POWDER_SNOW)) { - return BlockPathTypes.POWDER_SNOW; + return PathType.POWDER_SNOW; - } else if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH)) { + } else if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH) || blockState.is(Blocks.STONECUTTER)) { // Purpur - return BlockPathTypes.DAMAGE_OTHER; + return PathType.DAMAGE_OTHER; } else if (blockState.is(Blocks.HONEY_BLOCK)) { - return BlockPathTypes.STICKY_HONEY; + return PathType.STICKY_HONEY; 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 912cee9ec45876f831ca230b59a1be3b48ce6aa5..46910a3bdacc9df1835e16b300f9e107744d2660 100644 +index af24467ee37cfc06f692b3b02e68f6cfbaaa8d59..afe6b2170846273b41b694aa53dca4c31bf78b3f 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java @@ -33,7 +33,7 @@ public class PortalShape { @@ -17055,10 +16478,10 @@ index 912cee9ec45876f831ca230b59a1be3b48ce6aa5..46910a3bdacc9df1835e16b300f9e107 private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F; private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0D; diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index 45269115e63cfc3bd7dc740a5694e2cc7c35bcb1..e1498d496aa01c433b6fa198608e33916eadecf3 100644 +index 973f1d2c1db383eed5fccb7ccbad8f9a6b81d824..ac3341ea02985fdbafa405a4a3bc232439ff2e62 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -67,6 +67,7 @@ public class MapItemSavedData extends SavedData { +@@ -79,6 +79,7 @@ public class MapItemSavedData extends SavedData { private final Map frameMarkers = Maps.newHashMap(); private int trackedDecorationCount; private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper @@ -17067,7 +16490,7 @@ index 45269115e63cfc3bd7dc740a5694e2cc7c35bcb1..e1498d496aa01c433b6fa198608e3391 // CraftBukkit start public final CraftMapView mapView; diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java -index 3fb1e558c3510243c94981211f9a0e5e0ef1895b..e5177e5ffcac360f935f2139db4554c6586b551e 100644 +index cfe953bc924f46b570e37395ac0f05ebcb82eb39..5500e7ada2dd783cc1317968a3e54696bdd73bf8 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java @@ -57,6 +57,13 @@ public class LootingEnchantFunction extends LootItemConditionalFunction { @@ -17100,7 +16523,7 @@ index 92394960fc76886f393cba02ac33c57739a4b383..494808b7bc2fb296b78e229ce138a937 + // Purpur } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index 4a875bce9563f3b9351ebecde9b0eb1287beb50e..d3fd9a8752e501f45c154e28d8ffd49b01514979 100644 +index 9d93130f23addb18b97d7f5ec013faef17a74529..29d2fb87a65778926aea2cfc7a5b486cad596515 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -335,14 +335,26 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa @@ -17123,12 +16546,12 @@ index 4a875bce9563f3b9351ebecde9b0eb1287beb50e..d3fd9a8752e501f45c154e28d8ffd49b - ListTag rotation = (ListTag) data.get("Rotation"); + // Purpur start - OfflinePlayer API + //if (data.contains("Pos") && data.contains("Rotation")) { -+ ListTag position = data.getList("Pos", net.minecraft.nbt.Tag.TAG_DOUBLE); -+ ListTag rotation = data.getList("Rotation", net.minecraft.nbt.Tag.TAG_FLOAT); ++ ListTag position = data.getList("Pos", net.minecraft.nbt.Tag.TAG_DOUBLE); ++ ListTag rotation = data.getList("Rotation", net.minecraft.nbt.Tag.TAG_FLOAT); + -+ if (position.isEmpty() && rotation.isEmpty()) { -+ return null; -+ } ++ if (position.isEmpty() && rotation.isEmpty()) { ++ return null; ++ } + // Purpur end - OfflinePlayer API UUID uuid = new UUID(data.getLong("WorldUUIDMost"), data.getLong("WorldUUIDLeast")); @@ -17338,10 +16761,10 @@ index 4a875bce9563f3b9351ebecde9b0eb1287beb50e..d3fd9a8752e501f45c154e28d8ffd49b + // 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 8ecf6ffa93610261d27fafadfff016a2d6047c90..f4fb23ebdd35e23b022bdd78421dec6d86342260 100644 +index 1231a1e2106a75417d1da9dc3e1488704b91a3f1..339b16641a7548d89fb15baad8edf0c5f95db635 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -404,6 +404,20 @@ public final class CraftServer implements Server { +@@ -407,6 +407,20 @@ public final class CraftServer implements Server { this.serverTickManager = new CraftServerTickManager(console.tickRateManager()); Bukkit.setServer(this); @@ -17386,7 +16809,7 @@ index 8ecf6ffa93610261d27fafadfff016a2d6047c90..f4fb23ebdd35e23b022bdd78421dec6d this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -1590,6 +1607,55 @@ public final class CraftServer implements Server { +@@ -1595,6 +1612,55 @@ public final class CraftServer implements Server { return true; } @@ -17442,7 +16865,7 @@ index 8ecf6ffa93610261d27fafadfff016a2d6047c90..f4fb23ebdd35e23b022bdd78421dec6d @Override public List getRecipesFor(ItemStack result) { Preconditions.checkArgument(result != null, "ItemStack cannot be null"); -@@ -3045,6 +3111,18 @@ public final class CraftServer implements Server { +@@ -3065,6 +3131,18 @@ public final class CraftServer implements Server { } // Gale end - Gale configuration - API @@ -17461,7 +16884,7 @@ index 8ecf6ffa93610261d27fafadfff016a2d6047c90..f4fb23ebdd35e23b022bdd78421dec6d @Override public void restart() { org.spigotmc.RestartCommand.restart(); -@@ -3331,4 +3409,15 @@ public final class CraftServer implements Server { +@@ -3350,4 +3428,15 @@ public final class CraftServer implements Server { } // Gale end - YAPFA - last tick time - API @@ -17478,10 +16901,10 @@ index 8ecf6ffa93610261d27fafadfff016a2d6047c90..f4fb23ebdd35e23b022bdd78421dec6d + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index ac9b60e9a0f727ff267f3adf6a27d82a609afa93..60cd33602908937dbfec2cebd041d147c0a5dbab 100644 +index 2abe6131cc04ed397446c2aa08f77f9da00ce8c5..f27cf4efa3675cee8e6dd45c6f366cda35eb6abf 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2416,6 +2416,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2424,6 +2424,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } @@ -17531,10 +16954,10 @@ index ac9b60e9a0f727ff267f3adf6a27d82a609afa93..60cd33602908937dbfec2cebd041d147 public Collection getStructures(int x, int z) { return this.getStructures(x, z, struct -> true); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 8d3959614ce42c996d93ffe00e7900d60c9b8184..bac135289e34c69ff0d02ff23b8a95d72505e1bc 100644 +index cd8ca1c9c8253e54c0b34d30b08fb0c2341cc98e..42f08f65207673125b288d4a74fc6d18eb713e9e 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -195,6 +195,14 @@ public class Main { +@@ -196,6 +196,14 @@ public class Main { .describedAs("Jar file"); // Paper end @@ -17549,7 +16972,7 @@ index 8d3959614ce42c996d93ffe00e7900d60c9b8184..bac135289e34c69ff0d02ff23b8a95d7 // Paper start acceptsAll(asList("server-name"), "Name of the server") .withRequiredArg() -@@ -314,7 +322,7 @@ public class Main { +@@ -315,7 +323,7 @@ public class Main { System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper } @@ -17559,7 +16982,7 @@ index 8d3959614ce42c996d93ffe00e7900d60c9b8184..bac135289e34c69ff0d02ff23b8a95d7 Calendar deadline = Calendar.getInstance(); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java -index 2e51fab98d95c93d2095f7be6dbb5d5474158bfb..32285c8e0f42897793759fba85a1e8658750c843 100644 +index 1a2a05160ba51d9c75f1ae6ae61d944d81428722..3beb26ad2ef0fded49a8da8c5dec64f9508c1995 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java @@ -16,8 +16,15 @@ import org.bukkit.entity.Bee; @@ -17577,7 +17000,7 @@ index 2e51fab98d95c93d2095f7be6dbb5d5474158bfb..32285c8e0f42897793759fba85a1e865 + // Purpur end } - protected CraftBeehive(CraftBeehive state) { + protected CraftBeehive(CraftBeehive state, Location location) { @@ -75,15 +82,54 @@ public class CraftBeehive extends CraftBlockEntityState impl bees.add((Bee) bee.getBukkitEntity()); } @@ -17622,20 +17045,20 @@ index 2e51fab98d95c93d2095f7be6dbb5d5474158bfb..32285c8e0f42897793759fba85a1e865 public void addEntity(Bee entity) { Preconditions.checkArgument(entity != null, "Entity must not be null"); -- this.getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); +- this.getSnapshot().addOccupant(((CraftBee) entity).getHandle()); + int length = this.getSnapshot().getStored().size(); // Purpur -+ getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); ++ getSnapshot().addOccupant(((CraftBee) entity).getHandle()); + + // Purpur start - check if new bee was added, and if yes, add to stored bees -+ List s = this.getSnapshot().getStored(); -+ if(length < s.size()) { -+ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(s.get(s.size() - 1), this)); ++ List storedBeeData = this.getSnapshot().getStored(); ++ if(length < storedBeeData.size()) { ++ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(storedBeeData.getLast(), this)); + } + // Purpur end } @Override -@@ -95,6 +141,7 @@ public class CraftBeehive extends CraftBlockEntityState impl +@@ -100,6 +146,7 @@ public class CraftBeehive extends CraftBlockEntityState impl @Override public void clearEntities() { getSnapshot().clearBees(); @@ -17644,15 +17067,15 @@ index 2e51fab98d95c93d2095f7be6dbb5d5474158bfb..32285c8e0f42897793759fba85a1e865 // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java b/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java -index f0b0348e105fb27c829ec29e638433c57bfd5f64..57ce4b7c5fcfe7a88928cd4124f29af39e117ed9 100644 +index c1759aeb3e6ad0e4eb66cba3da1b120dd1dce812..1a91bc2e422db0eba65694ac046f1b362c6b0cd6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java -@@ -29,7 +29,7 @@ public class CraftConduit extends CraftBlockEntityState impl - @Override +@@ -73,7 +73,7 @@ public class CraftConduit extends CraftBlockEntityState impl public int getRange() { - requirePlaced(); -- return this.getTileEntity().effectBlocks.size() / 7 * 16; -+ return this.getTileEntity().effectBlocks.size() / 7 * this.world.getHandle().purpurConfig.conduitDistance; // Purpur + this.ensureNoWorldGeneration(); + ConduitBlockEntity conduit = (ConduitBlockEntity) this.getTileEntityFromWorld(); +- return (conduit != null) ? ConduitBlockEntity.getRange(conduit.effectBlocks) : 0; ++ return (conduit != null) ? ConduitBlockEntity.getRange(conduit.effectBlocks, this.world.getHandle()) : 0; // Purpur } @Override @@ -17683,19 +17106,6 @@ index 4e56018b64d11f76c8da43fd8f85c6de72204e36..aa8212432825db65cf485cd93f734ccd } @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -index a151b5d7c6e41b08e57c806bc43e067af48263ed..40d385c7865726545bb66f9a1856ed4e73e60202 100644 ---- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -@@ -71,6 +71,8 @@ public class CraftEnchantment extends Enchantment implements Handleable 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 @@ -17716,13 +17126,23 @@ 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 e8e4489bcd64fde1b3226bdc7a7cc612508bda3f..b6ecb58718b7de7ba9c90236f3dc11715652daa9 100644 +index a2d336ceb52b63db5c03432ee7bc94dc6a742b82..0ed18542fd8e2a992dc56a5f421eaa840e0af193 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -84,6 +84,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -84,6 +84,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); } ++ @Override ++ public boolean isImmuneToFire() { ++ return getHandle().fireImmune(); ++ } ++ ++ @Override ++ public void setImmuneToFire(Boolean fireImmune) { ++ getHandle().immuneToFire = fireImmune; ++ } ++ + @Override + public boolean isInDaylight() { + return getHandle().isSunBurnTick(); @@ -17731,7 +17151,7 @@ index e8e4489bcd64fde1b3226bdc7a7cc612508bda3f..b6ecb58718b7de7ba9c90236f3dc1171 public static CraftEntity getEntity(CraftServer server, T entity) { Preconditions.checkArgument(entity != null, "Unknown entity"); -@@ -253,6 +258,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -253,6 +268,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Paper end if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API @@ -17742,7 +17162,7 @@ index e8e4489bcd64fde1b3226bdc7a7cc612508bda3f..b6ecb58718b7de7ba9c90236f3dc1171 return false; } -@@ -1270,4 +1279,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1280,4 +1299,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getScoreboardName(); } // Paper end - entity scoreboard name @@ -17771,10 +17191,10 @@ index e8e4489bcd64fde1b3226bdc7a7cc612508bda3f..b6ecb58718b7de7ba9c90236f3dc1171 + // 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 7984365c8290ac9e526a413b56e1c8c0841e330c..a8b30fa294e088c0b604a5d8ac5667e32ed1b287 100644 +index 41f3cdec7deabf34358b8087df77169f85a5b919..90265b6f2acd43713b61e277799dd31311b6b7e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -267,6 +267,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -265,6 +265,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public void recalculatePermissions() { this.perm.recalculatePermissions(); @@ -17805,10 +17225,10 @@ 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 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..9b1dd59df1f7faea2fc74d82d003bd442fd52248 100644 +index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..5c1cda88080850314dac196dbe71ff12e48a8aca 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -@@ -151,4 +151,46 @@ public class CraftItem extends CraftEntity implements Item { +@@ -151,4 +151,51 @@ public class CraftItem extends CraftEntity implements Item { public String toString() { return "CraftItem"; } @@ -17835,8 +17255,13 @@ index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..9b1dd59df1f7faea2fc74d82d003bd44 + } + + @Override ++ public void setImmuneToFire(@org.jetbrains.annotations.Nullable Boolean immuneToFire) { ++ this.getHandle().immuneToFire = (immuneToFire != null && immuneToFire); ++ } ++ ++ @Override + public void setImmuneToFire(boolean immuneToFire) { -+ this.getHandle().immuneToFire = immuneToFire; ++ this.setImmuneToFire((Boolean) immuneToFire); + } + + @Override @@ -17856,10 +17281,10 @@ index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..9b1dd59df1f7faea2fc74d82d003bd44 + // 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 c4a166a0c226c6083c25c58145d9631d4296e615..ccc5eb9d048e90174b9a7963d8a6dfe79307d8ec 100644 +index aa351df679f300018367244c7ccb3e5a59e9276f..b452ebbe11145987fb5e66b39993898457322080 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -506,7 +506,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -505,7 +505,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; @@ -17868,23 +17293,13 @@ index c4a166a0c226c6083c25c58145d9631d4296e615..ccc5eb9d048e90174b9a7963d8a6dfe7 } // Paper end -@@ -1210,4 +1210,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1173,4 +1173,22 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().setYBodyRot(bodyYaw); } // Paper end - body yaw API + + // Purpur start + @Override -+ public float getSafeFallDistance() { -+ return getHandle().safeFallDistance; -+ } -+ -+ @Override -+ public void setSafeFallDistance(float safeFallDistance) { -+ getHandle().safeFallDistance = safeFallDistance; -+ } -+ -+ @Override + public void broadcastItemBreak(org.bukkit.inventory.EquipmentSlot slot) { + if (slot == null) return; + getHandle().broadcastBreakEvent(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); @@ -17923,10 +17338,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 44f4665db613c558078df5bb49106e4ca5679dfe..fb2d05e43df3bfb72b1f6e325736dd3cbc6c3096 100644 +index 0ff9bb5f5d312503ec4b3cf3bf8c532b09a8f08b..1c1159867c78a54984219a9d56a3838c630c58d8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -489,10 +489,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -565,10 +565,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setPlayerListName(String name) { @@ -17943,7 +17358,7 @@ index 44f4665db613c558078df5bb49106e4ca5679dfe..fb2d05e43df3bfb72b1f6e325736dd3c if (this.getHandle().connection == null) return; // Paper - Updates are possible before the player has fully joined for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { -@@ -1353,6 +1358,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1429,6 +1434,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API @@ -17954,7 +17369,7 @@ index 44f4665db613c558078df5bb49106e4ca5679dfe..fb2d05e43df3bfb72b1f6e325736dd3c return false; } -@@ -2661,6 +2670,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2727,6 +2736,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -17983,7 +17398,7 @@ index 44f4665db613c558078df5bb49106e4ca5679dfe..fb2d05e43df3bfb72b1f6e325736dd3c private void validateSpeed(float value) { Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); } -@@ -3456,4 +3487,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3513,4 +3544,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setSendViewDistance(final int viewDistance) { this.getHandle().setSendViewDistance(viewDistance); } @@ -18115,12 +17530,12 @@ index 7a8ce6956db56061af93ba9761f5d1057a90bc49..6d286b23806666f7b00ac88c59221446 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -index 38b6d2c377800134de592a780b737b45c8096a11..449acd9dc983be1cd51208bc8f8d843d2ddaa923 100644 +index 86574da257731de7646a712ed73384955fe35aa3..e223234dd64b0e41441c3b9f649f0b64dc6d98c4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -@@ -57,4 +57,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { - public void setInterested(boolean flag) { - this.getHandle().setIsInterested(flag); +@@ -146,4 +146,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { + return this.getKey().hashCode(); + } } + + // Purpur start @@ -18136,10 +17551,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 c0823c612de9dc2a64cc797f061eef25c5f31359..b82a6143526bd1d4ecd4591c1253cdb0b913fe09 100644 +index 547ab158cd0cbf51da06ea97740cfce34bca651b..6fed586c9a778f7a57e1b4ca2e6f2dbc15c8769d 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -593,6 +593,15 @@ public class CraftEventFactory { +@@ -592,6 +592,15 @@ public class CraftEventFactory { // Paper end craftServer.getPluginManager().callEvent(event); @@ -18155,7 +17570,7 @@ index c0823c612de9dc2a64cc797f061eef25c5f31359..b82a6143526bd1d4ecd4591c1253cdb0 return event; } -@@ -1124,7 +1133,7 @@ public class CraftEventFactory { +@@ -1121,7 +1130,7 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.LAVA, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } else if (source.getDirectBlock() != null) { DamageCause cause; @@ -18164,7 +17579,7 @@ index c0823c612de9dc2a64cc797f061eef25c5f31359..b82a6143526bd1d4ecd4591c1253cdb0 cause = DamageCause.CONTACT; } else if (source.is(DamageTypes.HOT_FLOOR)) { cause = DamageCause.HOT_FLOOR; -@@ -1182,6 +1191,7 @@ public class CraftEventFactory { +@@ -1179,6 +1188,7 @@ public class CraftEventFactory { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical); @@ -18250,76 +17665,6 @@ 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 71aac5d4cf29cea9daa378fc8ac584750de4d1ca..3e0372d3572431bdc417779888bcdcdd672c1531 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -596,4 +596,17 @@ public final class CraftItemFactory implements ItemFactory { - return CraftItemStack.asCraftMirror(enchanted); - } - // Paper end - enchantWithLevels API -+ -+ // Purpur start -+ @Override -+ public @org.jetbrains.annotations.NotNull java.util.List getHoverLines(@org.jetbrains.annotations.NotNull ItemStack itemStack, boolean advanced) { -+ return io.papermc.paper.adventure.PaperAdventure.asAdventure( -+ CraftItemStack.asNMSCopy(itemStack).getTooltipLines( -+ null, -+ advanced ? net.minecraft.world.item.TooltipFlag.ADVANCED -+ : net.minecraft.world.item.TooltipFlag.NORMAL -+ ) -+ ); -+ } -+ // Purpur end - } -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -index bac3a5c378054481e1a5abaec1f83afde5d64ac1..f1050bf2b9efc54a894426b08989d44566acd875 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -@@ -45,6 +45,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - static final ItemMetaKey POTION_COLOR = new ItemMetaKey("CustomPotionColor", "custom-color"); - static final ItemMetaKey ID = new ItemMetaKey("id", "potion-id"); - static final ItemMetaKey DEFAULT_POTION = new ItemMetaKey("Potion", "potion-type"); -+ static final ItemMetaKey KEY = new ItemMetaKey("key", "namespacedkey"); // Purpur - add key - - // Having an initial "state" in ItemMeta seems bit dirty but the UNCRAFTABLE potion type - // is treated as the empty form of the meta because it represents an empty potion with no effect -@@ -97,7 +98,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - boolean ambient = effect.getBoolean(CraftMetaPotion.AMBIENT.NBT); - boolean particles = effect.contains(CraftMetaPotion.SHOW_PARTICLES.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(CraftMetaPotion.SHOW_PARTICLES.NBT) : true; - boolean icon = effect.contains(CraftMetaPotion.SHOW_ICON.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(CraftMetaPotion.SHOW_ICON.NBT) : particles; -- this.customEffects.add(new PotionEffect(type, duration, amp, ambient, particles, icon)); -+ // Purpur start -+ NamespacedKey key = null; -+ if (tag.contains(CraftMetaPotion.KEY.NBT)) { -+ key = NamespacedKey.fromString(effect.getString(CraftMetaPotion.KEY.NBT)); -+ } -+ this.customEffects.add(new PotionEffect(type, duration, amp, ambient, particles, icon, key)); -+ // Purpur end - } - } - } -@@ -150,6 +157,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - effectData.putBoolean(CraftMetaPotion.AMBIENT.NBT, effect.isAmbient()); - effectData.putBoolean(CraftMetaPotion.SHOW_PARTICLES.NBT, effect.hasParticles()); - effectData.putBoolean(CraftMetaPotion.SHOW_ICON.NBT, effect.hasIcon()); -+ // Purpur start -+ if (effect.hasKey()) { -+ effectData.putString(CraftMetaPotion.KEY.NBT, effect.getKey().toString()); -+ } -+ // Purpur end - effectList.add(effectData); - } - } -@@ -225,7 +237,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { - if (index != -1) { - if (overwrite) { - PotionEffect old = this.customEffects.get(index); -- if (old.getAmplifier() == effect.getAmplifier() && old.getDuration() == effect.getDuration() && old.isAmbient() == effect.isAmbient()) { -+ if (old.getAmplifier() == effect.getAmplifier() && old.getDuration() == effect.getDuration() && old.isAmbient() == effect.isAmbient() && old.getKey() == effect.getKey()) { // Purpur - add key - return false; - } - 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 6ba29875d78ede4aa7978ff689e588f7fed11528..4afec4387971612f62b825e9e56c2ead7424a7c2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -18333,10 +17678,10 @@ index 6ba29875d78ede4aa7978ff689e588f7fed11528..4afec4387971612f62b825e9e56c2ead throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java -index 15e9dd8844f893de5e8372b847c9e8295d6f69ca..b4b105c0190502328d5aeb680dd8e67c2875618f 100644 +index 0cbbd915631904fe8c6effefb92895422b33eff6..aef19cfbecb4ddfc8dc71c4f3b2a011364c12dc2 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java -@@ -46,4 +46,10 @@ public class CraftMapRenderer extends MapRenderer { +@@ -47,4 +47,10 @@ public class CraftMapRenderer extends MapRenderer { } } @@ -18347,30 +17692,8 @@ 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 e938255fcc5db0c289d3e132175a541187e4a748..f7a747ea73a80c97d863e0fd3772a0c333aef3c8 100644 ---- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java -+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java -@@ -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) { -@@ -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(), 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) { 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 dd95b3bfe59f2bb635afe92317288efcd2986326..11f43f44f359ce57d3a8f3322e58b9f5dfdaf00a 100644 +index 52649f82351ab4f675c3cc3cd6640956b0f76b91..eb51c88c7a0658190d3a8bfd5d18dca79d85fba0 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 { @@ -18392,10 +17715,10 @@ index dd95b3bfe59f2bb635afe92317288efcd2986326..11f43f44f359ce57d3a8f3322e58b9f5 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..0c8bcfbe35f9133a32a31163e5bf2f04786c77a0 +index 0000000000000000000000000000000000000000..8facd29bac314d4b8897113460f78ea7ed3e82b6 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -0,0 +1,646 @@ +@@ -0,0 +1,570 @@ +package org.purpurmc.purpur; + +import com.google.common.base.Throwables; @@ -18473,8 +17796,8 @@ index 0000000000000000000000000000000000000000..0c8bcfbe35f9133a32a31163e5bf2f04 + commands = new HashMap<>(); + commands.put("purpur", new PurpurCommand("purpur")); + -+ version = getInt("config-version", 34); -+ set("config-version", 34); ++ version = getInt("config-version", 35); ++ set("config-version", 35); + + readConfig(PurpurConfig.class, null); + @@ -18768,7 +18091,7 @@ index 0000000000000000000000000000000000000000..0c8bcfbe35f9133a32a31163e5bf2f04 + beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive); + anvilCumulativeCost = getBoolean("settings.blocks.anvil.cumulative-cost", anvilCumulativeCost); + lightningRodRange = getInt("settings.blocks.lightning_rod.range", lightningRodRange); -+ ArrayList defaultCurses = new ArrayList<>(){{ ++ ArrayList defaultCurses = new ArrayList<>() {{ + add("minecraft:binding_curse"); + add("minecraft:vanishing_curse"); + }}; @@ -18808,7 +18131,7 @@ index 0000000000000000000000000000000000000000..0c8bcfbe35f9133a32a31163e5bf2f04 + } + + public static boolean allowInfinityMending = false; -+ public static boolean allowCrossbowInfinity = false; ++ public static boolean allowCrossbowInfinity = true; + public static boolean allowShearsLooting = false; + public static boolean allowUnsafeEnchants = false; + public static boolean allowInapplicableEnchants = true; @@ -18880,82 +18203,6 @@ index 0000000000000000000000000000000000000000..0c8bcfbe35f9133a32a31163e5bf2f04 + usernameValidCharactersPattern = java.util.regex.Pattern.compile(setPattern == null || setPattern.isBlank() ? defaultPattern : setPattern); + } + -+ private static void foodSettings() { -+ ConfigurationSection properties = config.getConfigurationSection("settings.food-properties"); -+ if (properties == null) { -+ config.addDefault("settings.food-properties", new HashMap<>()); -+ return; -+ } -+ -+ Map> effectDefaults = new HashMap<>(); -+ Map EFFECT_DEFAULT = Map.of( -+ "chance", 0.0F, -+ "duration", 0, -+ "amplifier", 0, -+ "ambient", false, -+ "visible", true, -+ "show-icon", true -+ ); -+ -+ properties.getKeys(false).forEach(foodKey -> { -+ FoodProperties food = Foods.ALL_PROPERTIES.get(foodKey); -+ if (food == null) { -+ PurpurConfig.log(Level.SEVERE, "Invalid food property: " + foodKey); -+ return; -+ } -+ FoodProperties foodDefaults = Foods.DEFAULT_PROPERTIES.get(foodKey); -+ food.setNutrition(properties.getInt(foodKey + ".nutrition", foodDefaults.getNutrition())); -+ food.setSaturationModifier((float) properties.getDouble(foodKey + ".saturation-modifier", foodDefaults.getSaturationModifier())); -+ food.setIsMeat(properties.getBoolean(foodKey + ".is-meat", foodDefaults.isMeat())); -+ food.setCanAlwaysEat(properties.getBoolean(foodKey + ".can-always-eat", foodDefaults.canAlwaysEat())); -+ food.setFastFood(properties.getBoolean(foodKey + ".fast-food", foodDefaults.isFastFood())); -+ ConfigurationSection effects = properties.getConfigurationSection(foodKey + ".effects"); -+ if (effects != null) { -+ effectDefaults.clear(); -+ foodDefaults.getEffects().forEach(pair -> { -+ MobEffectInstance effect = pair.getFirst(); -+ effectDefaults.put(effect.getEffect(), Map.of( -+ "chance", pair.getSecond(), -+ "duration", effect.getDuration(), -+ "amplifier", effect.getAmplifier(), -+ "ambient", effect.isAmbient(), -+ "visible", effect.isVisible(), -+ "show-icon", effect.showIcon() -+ )); -+ }); -+ effects.getKeys(false).forEach(effectKey -> { -+ MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(new ResourceLocation(effectKey)); -+ if (effect == null) { -+ PurpurConfig.log(Level.SEVERE, "Invalid food property effect for " + foodKey + ": " + effectKey); -+ return; -+ } -+ -+ Map effectDefault = effectDefaults.get(effect); -+ if (effectDefault == null) { -+ effectDefault = EFFECT_DEFAULT; -+ } -+ -+ food.getEffects().removeIf(pair -> pair.getFirst().getEffect() == effect); -+ float chance = (float) effects.getDouble(effectKey + ".chance", ((Float) effectDefault.get("chance")).doubleValue()); -+ int duration = effects.getInt(effectKey + ".duration", (int) effectDefault.get("duration")); -+ if (chance <= 0.0F || duration < 0) { -+ return; -+ } -+ int amplifier = effects.getInt(effectKey + ".amplifier", (int) effectDefault.get("amplifier")); -+ boolean ambient = effects.getBoolean(effectKey + ".ambient", (boolean) effectDefault.get("ambient")); -+ boolean visible = effects.getBoolean(effectKey + ".visible", (boolean) effectDefault.get("visible")); -+ boolean showIcon = effects.getBoolean(effectKey + ".show-icon", (boolean) effectDefault.get("show-icon")); -+ food.getEffects().add(Pair.of(new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon), chance)); -+ }); -+ } -+ }); -+ } -+ -+ public static boolean fixNetworkSerializedItemsInCreative = false; -+ private static void fixNetworkSerializedCreativeItems() { -+ fixNetworkSerializedItemsInCreative = getBoolean("settings.fix-network-serialized-items-in-creative", fixNetworkSerializedItemsInCreative); -+ } -+ + public static boolean fixProjectileLootingTransfer = false; + private static void fixProjectileLootingTransfer() { + fixProjectileLootingTransfer = getBoolean("settings.fix-projectile-looting-transfer", fixProjectileLootingTransfer); @@ -19044,10 +18291,10 @@ index 0000000000000000000000000000000000000000..0c8bcfbe35f9133a32a31163e5bf2f04 +} 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..d15d8984cd53bec826fa2507b91acff10d9711cf +index 0000000000000000000000000000000000000000..dde2e82e8f3686f6b77fefdaad9beaeb90059c23 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3289 @@ +@@ -0,0 +1,3284 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -19163,11 +18410,6 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + armorstandPlaceWithArms = getBoolean("gameplay-mechanics.armorstand.place-with-arms-visible", armorstandPlaceWithArms); + } + -+ public boolean arrowMovementResetsDespawnCounter = true; -+ private void arrowSettings() { -+ arrowMovementResetsDespawnCounter = getBoolean("gameplay-mechanics.arrow.movement-resets-despawn-counter", arrowMovementResetsDespawnCounter); -+ } -+ + public boolean useBetterMending = false; + public double mendingMultiplier = 1.0; + public boolean alwaysTameInCreative = false; @@ -19182,7 +18424,8 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + public boolean milkClearsBeneficialEffects = true; + public boolean noteBlockIgnoreAbove = false; + public boolean persistentDroppableEntityDisplayNames = true; -+ public boolean persistentTileEntityDisplayNames = false; ++ public boolean persistentTileEntityLore = false; ++ public boolean persistentTileEntityDisplayName = true; + public boolean projectilesBypassMobGriefing = false; + public boolean tickFluids = true; + public double mobsBlindnessMultiplier = 1; @@ -19210,7 +18453,14 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); + milkClearsBeneficialEffects = getBoolean("gameplay-mechanics.milk-clears-beneficial-effects", milkClearsBeneficialEffects); + noteBlockIgnoreAbove = getBoolean("gameplay-mechanics.note-block-ignore-above", noteBlockIgnoreAbove); -+ persistentTileEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-tileentity-display-names-and-lore", persistentTileEntityDisplayNames); ++ if (PurpurConfig.version < 35) { ++ boolean oldVal = getBoolean("gameplay-mechanics.persistent-tileentity-display-names-and-lore", persistentTileEntityLore); ++ set("gameplay-mechanics.persistent-tileentity-display-names-and-lore", null); ++ set("gameplay-mechanics.persistent-tileentity-lore", oldVal); ++ set("gameplay-mechanics.persistent-tileentity-display-name", !oldVal); ++ } ++ persistentTileEntityLore = getBoolean("gameplay-mechanics.persistent-tileentity-lore", persistentTileEntityLore); ++ persistentTileEntityDisplayName = getBoolean("gameplay-mechanics.persistent-tileentity-display-name", persistentTileEntityDisplayName); + persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames); + projectilesBypassMobGriefing = getBoolean("gameplay-mechanics.projectiles-bypass-mob-griefing", projectilesBypassMobGriefing); + tickFluids = getBoolean("gameplay-mechanics.tick-fluids", tickFluids); @@ -19520,6 +18770,38 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + playerVoidTrading = getBoolean("gameplay-mechanics.player.allow-void-trading", playerVoidTrading); + } + ++ public boolean silkTouchEnabled = false; ++ public String silkTouchSpawnerName = "Monster Spawner"; ++ public List silkTouchSpawnerLore = new ArrayList<>(); ++ public List silkTouchTools = new ArrayList<>(); ++ public int minimumSilkTouchSpawnerRequire = 1; ++ private void silkTouchSettings() { ++ if (PurpurConfig.version < 21) { ++ String oldName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); ++ set("gameplay-mechanics.silk-touch.spawner-name", "" + ChatColor.toMM(oldName.replace("{mob}", ""))); ++ List list = new ArrayList<>(); ++ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a ")) ++ .forEach(line -> list.add("" + ChatColor.toMM(line.toString().replace("{mob}", "")))); ++ set("gameplay-mechanics.silk-touch.spawner-lore", list); ++ } ++ silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled); ++ silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); ++ minimumSilkTouchSpawnerRequire = getInt("gameplay-mechanics.silk-touch.minimal-level", minimumSilkTouchSpawnerRequire); ++ silkTouchSpawnerLore.clear(); ++ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a ")) ++ .forEach(line -> silkTouchSpawnerLore.add(line.toString())); ++ silkTouchTools.clear(); ++ getList("gameplay-mechanics.silk-touch.tools", List.of( ++ "minecraft:iron_pickaxe", ++ "minecraft:golden_pickaxe", ++ "minecraft:diamond_pickaxe", ++ "minecraft:netherite_pickaxe" ++ )).forEach(key -> { ++ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ if (item != Items.AIR) silkTouchTools.add(item); ++ }); ++ } ++ + private static boolean projectileDespawnRateSettingsMigrated = false; + private void projectileDespawnRateSettings() { + if (PurpurConfig.version < 28 && !projectileDespawnRateSettingsMigrated) { @@ -19575,38 +18857,6 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage); + } + -+ public boolean silkTouchEnabled = false; -+ public String silkTouchSpawnerName = "Monster Spawner"; -+ public List silkTouchSpawnerLore = new ArrayList<>(); -+ public List silkTouchTools = new ArrayList<>(); -+ public int minimumSilkTouchSpawnerRequire = 1; -+ private void silkTouchSettings() { -+ if (PurpurConfig.version < 21) { -+ String oldName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); -+ set("gameplay-mechanics.silk-touch.spawner-name", "" + ChatColor.toMM(oldName.replace("{mob}", ""))); -+ List list = new ArrayList<>(); -+ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a ")) -+ .forEach(line -> list.add("" + ChatColor.toMM(line.toString().replace("{mob}", "")))); -+ set("gameplay-mechanics.silk-touch.spawner-lore", list); -+ } -+ silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled); -+ silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); -+ minimumSilkTouchSpawnerRequire = getInt("gameplay-mechanics.silk-touch.minimal-level", minimumSilkTouchSpawnerRequire); -+ silkTouchSpawnerLore.clear(); -+ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a ")) -+ .forEach(line -> silkTouchSpawnerLore.add(line.toString())); -+ silkTouchTools.clear(); -+ getList("gameplay-mechanics.silk-touch.tools", List.of( -+ "minecraft:iron_pickaxe", -+ "minecraft:golden_pickaxe", -+ "minecraft:diamond_pickaxe", -+ "minecraft:netherite_pickaxe" -+ )).forEach(key -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); -+ if (item != Items.AIR) silkTouchTools.add(item); -+ }); -+ } -+ + public Map axeStrippables = new HashMap<>(); + public Map axeWaxables = new HashMap<>(); + public Map axeWeatherables = new HashMap<>(); @@ -20152,11 +19402,6 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + sculkShriekerCanSummonDefault = getBoolean("blocks.sculk_shrieker.can-summon-default", sculkShriekerCanSummonDefault); + } + -+ public boolean signAllowColors = false; -+ private void signSettings() { -+ signAllowColors = getBoolean("blocks.sign.allow-colors", signAllowColors); -+ } -+ + public boolean slabHalfBreak = false; + private void slabSettings() { + slabHalfBreak = getBoolean("blocks.slab.break-individual-slabs-when-sneaking", slabHalfBreak); @@ -20217,13 +19462,10 @@ index 0000000000000000000000000000000000000000..d15d8984cd53bec826fa2507b91acff1 + public boolean allayRidable = false; + public boolean allayRidableInWater = true; + public boolean allayControllable = true; -+ public List allayRespectNBT = new ArrayList<>(); + private void allaySettings() { + allayRidable = getBoolean("mobs.allay.ridable", allayRidable); + allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); + allayControllable = getBoolean("mobs.allay.controllable", allayControllable); -+ allayRespectNBT.clear(); -+ getList("mobs.allay.respect-nbt", new ArrayList<>()).forEach(key -> allayRespectNBT.add(key.toString())); + } + + public boolean axolotlRidable = false; @@ -23141,7 +22383,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..3e846f38902024875d1961b16a60c50201df309d +index 0000000000000000000000000000000000000000..f25abee6dbf99c8d08f8e09db02b41df86115faa --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java @@ -0,0 +1,107 @@ @@ -23196,7 +22438,7 @@ index 0000000000000000000000000000000000000000..3e846f38902024875d1961b16a60c502 + Vec3 mot = this.getDeltaMovement(); + HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + -+ this.preOnHit(hitResult); ++ this.preHitTargetOrDeflectSelf(hitResult); + + double x = this.getX() + mot.x; + double y = this.getY() + mot.y; @@ -23254,7 +22496,7 @@ index 0000000000000000000000000000000000000000..3e846f38902024875d1961b16a60c502 +} 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..11825590af9346c61d5d15e5ef446b3c77b81b54 +index 0000000000000000000000000000000000000000..75e31aee6e706f042398444f272888f9ad0fa3f4 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java @@ -0,0 +1,121 @@ @@ -23311,7 +22553,7 @@ index 0000000000000000000000000000000000000000..11825590af9346c61d5d15e5ef446b3c + Vec3 mot = this.getDeltaMovement(); + HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + -+ this.preOnHit(hitResult); ++ this.preHitTargetOrDeflectSelf(hitResult); + + double x = this.getX() + mot.x; + double y = this.getY() + mot.y; @@ -23361,7 +22603,7 @@ index 0000000000000000000000000000000000000000..11825590af9346c61d5d15e5ef446b3c + if (canGrief || (target instanceof LivingEntity && !(target instanceof ArmorStand))) { + boolean hurt = target.hurt(target.damageSources().mobProjectile(this, (LivingEntity) shooter), level().purpurConfig.phantomFlameDamage); + if (hurt && level().purpurConfig.phantomFlameFireTime > 0) { -+ target.setSecondsOnFire(level().purpurConfig.phantomFlameFireTime); ++ target.igniteForSeconds(level().purpurConfig.phantomFlameFireTime); + } + } + } @@ -23381,15 +22623,17 @@ index 0000000000000000000000000000000000000000..11825590af9346c61d5d15e5ef446b3c +} diff --git a/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java b/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java new file mode 100644 -index 0000000000000000000000000000000000000000..8efca1d91188ac4db911a8eb0fa9ea2cc3c48e28 +index 0000000000000000000000000000000000000000..9464bca8af6e8e34a5f13aae6ad14051ee325424 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java -@@ -0,0 +1,102 @@ +@@ -0,0 +1,105 @@ +package org.purpurmc.purpur.entity; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; ++import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; ++import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.block.entity.BeehiveBlockEntity; +import org.bukkit.block.EntityBlockStorage; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; @@ -23415,12 +22659,13 @@ index 0000000000000000000000000000000000000000..8efca1d91188ac4db911a8eb0fa9ea2c + this.handle = data; + this.blockStorage = blockStorage; + -+ this.customName = handle.entityData.contains("CustomName", Tag.TAG_STRING) -+ ? PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(handle.entityData.getString("CustomName"))) ++ CompoundTag customData = handle.occupant.entityData().copyTag(); ++ this.customName = customData.contains("CustomName") ++ ? PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(customData.getString("CustomName"), MinecraftServer.getDefaultRegistryAccess())) + : null; + -+ if(handle.entityData.contains("BukkitValues", Tag.TAG_COMPOUND)) { -+ this.persistentDataContainer.putAll(handle.entityData.getCompound("BukkitValues")); ++ if (customData.contains("BukkitValues", Tag.TAG_COMPOUND)) { ++ this.persistentDataContainer.putAll(customData.getCompound("BukkitValues")); + } + } + @@ -23479,11 +22724,11 @@ index 0000000000000000000000000000000000000000..8efca1d91188ac4db911a8eb0fa9ea2c + + @Override + public void update() { -+ handle.entityData.put("BukkitValues", this.persistentDataContainer.toTagCompound()); ++ handle.occupant.entityData().copyTag().put("BukkitValues", this.persistentDataContainer.toTagCompound()); + if(customName == null) { -+ handle.entityData.remove("CustomName"); ++ handle.occupant.entityData().copyTag().remove("CustomName"); + } else { -+ handle.entityData.putString("CustomName", net.minecraft.network.chat.Component.Serializer.toJson(PaperAdventure.asVanilla(customName))); ++ handle.occupant.entityData().copyTag().putString("CustomName", net.minecraft.network.chat.Component.Serializer.toJson(PaperAdventure.asVanilla(customName), MinecraftServer.getDefaultRegistryAccess())); + } + } +} @@ -23722,17 +22967,19 @@ index 0000000000000000000000000000000000000000..550222758bf0e7deff26a6e813a860b7 +} diff --git a/src/main/java/org/purpurmc/purpur/gui/JColorTextPane.java b/src/main/java/org/purpurmc/purpur/gui/JColorTextPane.java new file mode 100644 -index 0000000000000000000000000000000000000000..062eef57117593e013f85b05561aa8843468133a +index 0000000000000000000000000000000000000000..d75fb5e77eff27d86135ed7d605dbc250b660f7d --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/gui/JColorTextPane.java -@@ -0,0 +1,81 @@ +@@ -0,0 +1,83 @@ +package org.purpurmc.purpur.gui; + +import com.google.common.collect.Sets; ++import javax.swing.UIManager; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; + -+import javax.swing.*; ++import javax.swing.JTextPane; ++import javax.swing.Timer; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.SimpleAttributeSet; @@ -23742,12 +22989,12 @@ index 0000000000000000000000000000000000000000..062eef57117593e013f85b05561aa884 + +public class JColorTextPane extends JTextPane { + private static final GUIColor DEFAULT_COLOR; -+ + static { + DEFAULT_COLOR = UIManager.getSystemLookAndFeelClassName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel") -+ ? GUIColor.WHITE : GUIColor.BLACK; ++ ? GUIColor.WHITE : GUIColor.BLACK; + } + ++ + public void append(String msg) { + // TODO: update to use adventure instead + BaseComponent[] components = TextComponent.fromLegacyText(DEFAULT_COLOR.getCode() + msg, DEFAULT_COLOR.getChatColor()); @@ -23841,18 +23088,20 @@ 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..d6cc7e434cb2bacc00e4cad9e1f4be7fcf5d0bee +index 0000000000000000000000000000000000000000..94104908f46df09b1c4f75296ff5b8e7735e8435 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java -@@ -0,0 +1,38 @@ +@@ -0,0 +1,40 @@ +package org.purpurmc.purpur.item; + +import net.minecraft.core.BlockPos; ++import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; @@ -23869,37 +23118,95 @@ index 0000000000000000000000000000000000000000..d6cc7e434cb2bacc00e4cad9e1f4be7f + protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, Player player, ItemStack stack, BlockState state) { + boolean handled = super.updateCustomBlockEntityTag(pos, level, player, stack, state); + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.place.spawners")) { -+ BlockEntity spawner = level.getBlockEntity(pos); -+ if (spawner instanceof SpawnerBlockEntity && stack.hasTag()) { -+ CompoundTag tag = stack.getTag(); -+ 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")); ++ BlockEntity blockEntity = level.getBlockEntity(pos); ++ if (blockEntity instanceof SpawnerBlockEntity spawner) { ++ CompoundTag customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); ++ if (customData.contains("Purpur.mob_type")) { ++ EntityType.byString(customData.getString("Purpur.mob_type")).ifPresent(type -> spawner.getSpawner().setEntityId(type, level, level.random, pos)); ++ } else if (customData.contains("Purpur.SpawnData")) { ++ net.minecraft.world.level.SpawnData.CODEC.parse(net.minecraft.nbt.NbtOps.INSTANCE, customData.getCompound("Purpur.SpawnData")).result() ++ .ifPresent(spawnData -> spawner.getSpawner().nextSpawnData = spawnData); + } + } + } + return handled; + } +} -diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java +diff --git a/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java b/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java new file mode 100644 -index 0000000000000000000000000000000000000000..15e760d5c0465b24969df3e25bf8409faab8b62e +index 0000000000000000000000000000000000000000..57e195fd2d457295cda6c366684be5577aeef071 --- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java -@@ -0,0 +1,96 @@ -+package org.purpurmc.purpur.task; ++++ b/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java +@@ -0,0 +1,27 @@ ++package org.purpurmc.purpur.network; + -+import com.google.common.io.ByteArrayDataInput; -+import com.google.common.io.ByteArrayDataOutput; -+import com.google.common.io.ByteStreams; -+import io.netty.buffer.Unpooled; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; ++import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; ++import org.jetbrains.annotations.NotNull; ++ ++public record ClientboundBeehivePayload(BlockPos pos, int numOfBees) implements CustomPacketPayload { ++ public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ClientboundBeehivePayload::write, ClientboundBeehivePayload::new); ++ public static final Type TYPE = new Type<>(new ResourceLocation("purpur", "beehive_s2c")); ++ ++ public ClientboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { ++ this(friendlyByteBuf.readBlockPos(), friendlyByteBuf.readInt()); ++ } ++ ++ private void write(FriendlyByteBuf friendlyByteBuf) { ++ friendlyByteBuf.writeBlockPos(this.pos); ++ friendlyByteBuf.writeInt(this.numOfBees); ++ } ++ ++ @Override ++ public @NotNull Type type() { ++ return TYPE; ++ } ++} +diff --git a/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java +new file mode 100644 +index 0000000000000000000000000000000000000000..27689754565bf048d1206d540913495d7194a54d +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java +@@ -0,0 +1,26 @@ ++package org.purpurmc.purpur.network; ++ ++import net.minecraft.core.BlockPos; ++import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.network.codec.StreamCodec; ++import net.minecraft.network.protocol.common.custom.CustomPacketPayload; ++import net.minecraft.resources.ResourceLocation; ++import org.jetbrains.annotations.NotNull; ++ ++public record ServerboundBeehivePayload(BlockPos pos) implements CustomPacketPayload { ++ public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ServerboundBeehivePayload::write, ServerboundBeehivePayload::new); ++ public static final Type TYPE = new Type<>(new ResourceLocation("purpur", "beehive_c2s")); ++ ++ public ServerboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { ++ this(friendlyByteBuf.readBlockPos()); ++ } ++ ++ private void write(FriendlyByteBuf friendlyByteBuf) { ++ friendlyByteBuf.writeBlockPos(this.pos); ++ } ++ ++ @Override ++ public @NotNull Type type() { ++ return TYPE; ++ } ++} +diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java +new file mode 100644 +index 0000000000000000000000000000000000000000..56fc359ea32228c2589ac30c9d00a9c4bea30db7 +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java +@@ -0,0 +1,67 @@ ++package org.purpurmc.purpur.task; ++ ++import io.netty.buffer.Unpooled; ++import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.block.entity.BeehiveBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; @@ -23910,10 +23217,10 @@ index 0000000000000000000000000000000000000000..15e760d5c0465b24969df3e25bf8409f +import org.bukkit.plugin.PluginBase; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; ++import org.purpurmc.purpur.network.ClientboundBeehivePayload; ++import org.purpurmc.purpur.network.ServerboundBeehivePayload; + +public class BeehiveTask implements PluginMessageListener { -+ public static final ResourceLocation BEEHIVE_C2S = new ResourceLocation("purpur", "beehive_c2s"); -+ public static final ResourceLocation BEEHIVE_S2C = new ResourceLocation("purpur", "beehive_s2c"); + + private static BeehiveTask instance; + @@ -23930,59 +23237,37 @@ index 0000000000000000000000000000000000000000..15e760d5c0465b24969df3e25bf8409f + } + + public void register() { -+ Bukkit.getMessenger().registerOutgoingPluginChannel(this.plugin, BEEHIVE_S2C.toString()); -+ Bukkit.getMessenger().registerIncomingPluginChannel(this.plugin, BEEHIVE_C2S.toString(), this); ++ Bukkit.getMessenger().registerOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); ++ Bukkit.getMessenger().registerIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString(), this); + } + + public void unregister() { -+ Bukkit.getMessenger().unregisterOutgoingPluginChannel(this.plugin, BEEHIVE_S2C.toString()); -+ Bukkit.getMessenger().unregisterIncomingPluginChannel(this.plugin, BEEHIVE_C2S.toString()); ++ Bukkit.getMessenger().unregisterOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); ++ Bukkit.getMessenger().unregisterIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString()); + } + + @Override -+ public void onPluginMessageReceived(@NotNull String channel, Player player, byte[] bytes) { -+ ByteArrayDataInput in = in(bytes); -+ long packedPos = in.readLong(); -+ BlockPos pos = BlockPos.of(packedPos); ++ public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] bytes) { ++ FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.copiedBuffer(bytes)); ++ ServerboundBeehivePayload payload = ServerboundBeehivePayload.STREAM_CODEC.decode(byteBuf); + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + // targeted block info max range specified in client at net.minecraft.client.gui.hud.DebugHud#render -+ if (!pos.getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20 -+ if (serverPlayer.level().getChunkIfLoaded(pos) == null) return; ++ if (!payload.pos().getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20 ++ if (serverPlayer.level().getChunkIfLoaded(payload.pos()) == null) return; + -+ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(pos); ++ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(payload.pos()); + if (!(blockEntity instanceof BeehiveBlockEntity beehive)) { + return; + } + -+ ByteArrayDataOutput out = out(); -+ -+ out.writeInt(beehive.getOccupantCount()); -+ out.writeLong(packedPos); -+ -+ FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(out.toByteArray())); -+ serverPlayer.connection.send(new ClientboundCustomPayloadPacket(new CustomPacketPayload() { -+ @Override -+ public void write(final FriendlyByteBuf buf) { -+ buf.writeBytes(byteBuf.copy()); -+ } -+ -+ @Override -+ public ResourceLocation id() { -+ return BEEHIVE_S2C; -+ } -+ })); -+ } -+ -+ @SuppressWarnings("UnstableApiUsage") -+ private static ByteArrayDataOutput out() { -+ return ByteStreams.newDataOutput(); -+ } -+ -+ @SuppressWarnings("UnstableApiUsage") -+ private static ByteArrayDataInput in(byte[] bytes) { -+ return ByteStreams.newDataInput(bytes); ++ ClientboundBeehivePayload customPacketPayload = new ClientboundBeehivePayload(payload.pos(), beehive.getOccupantCount()); ++ FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.buffer()); ++ ClientboundBeehivePayload.STREAM_CODEC.encode(friendlyByteBuf, customPacketPayload); ++ byte[] byteArray = new byte[friendlyByteBuf.readableBytes()]; ++ friendlyByteBuf.readBytes(byteArray); ++ player.sendPluginMessage(this.plugin, customPacketPayload.type().id().toString(), byteArray); + } +} diff --git a/src/main/java/org/purpurmc/purpur/task/BossBarTask.java b/src/main/java/org/purpurmc/purpur/task/BossBarTask.java @@ -24644,14 +23929,14 @@ index df50c32482067368b11d2928bd353f4fbe595afe..9edb1e43dc9c55202443ef5f893d8e2b if ( entity instanceof FireworkRocketEntity ) { return true; diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml -index 675cd61221e807aadf28322b46c3daa1370241b5..0769f5c4711a3b7f59489e611ed01ad8367e5db1 100644 +index d2a75850af9c6ad2aca66a5f994f1b587d73eac4..a056aa167887abef9e6d531a9edd2cda433567d2 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -2,7 +2,16 @@ - + -- +- + + + @@ -24666,18 +23951,18 @@ index 675cd61221e807aadf28322b46c3daa1370241b5..0769f5c4711a3b7f59489e611ed01ad8 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 +index 2f3ff50bf3f70b6b404d02d5ffcc079162a63bc1..4e57fdf21d4b7789cd7c3d3a18ddc6227bc77792 100644 --- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java +++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java -@@ -45,6 +45,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { - Set foundPerms = new HashSet<>(); - for (CommandNode child : root.getChildren()) { - final String vanillaPerm = VanillaCommandWrapper.getPermission(child); +@@ -48,6 +48,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { + if ("bukkit.command.paper.pgive".equals(vanillaPerm)) { // skip our custom give command + continue; + } + if (TO_SKIP.contains(vanillaPerm)) continue; // Purpur if (!perms.contains(vanillaPerm)) { missing.add("Missing permission for " + child.getName() + " (" + vanillaPerm + ") command"); } else { -@@ -57,6 +58,25 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { +@@ -60,6 +61,25 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { } private static final List TO_SKIP = List.of( @@ -24703,43 +23988,3 @@ index afeb4271fffb7546209f1e651214065187c88302..81bc3af856b8af019fd13e1da1f7cccd "minecraft.command.selector" ); -diff --git a/src/test/java/org/bukkit/potion/PotionTest.java b/src/test/java/org/bukkit/potion/PotionTest.java -index 8963d93e99bdaf719fa160c11dd5af6a1d86f9a4..d852d8b14f5000415cbb4f06601059b3934b7efc 100644 ---- a/src/test/java/org/bukkit/potion/PotionTest.java -+++ b/src/test/java/org/bukkit/potion/PotionTest.java -@@ -9,6 +9,7 @@ import net.minecraft.resources.ResourceLocation; - import net.minecraft.world.effect.MobEffect; - import net.minecraft.world.effect.MobEffectInstance; - import net.minecraft.world.item.alchemy.Potion; -+import org.bukkit.NamespacedKey; - import org.bukkit.craftbukkit.potion.CraftPotionEffectType; - import org.bukkit.support.AbstractTestingBase; - import org.junit.jupiter.api.Test; -@@ -46,4 +47,27 @@ public class PotionTest extends AbstractTestingBase { - assertEquals(bukkit, byName, "Same type not returned by name " + key); - } - } -+ -+ // Purpur start -+ @Test -+ public void testNamespacedKey() { -+ NamespacedKey key = new NamespacedKey("testnamespace", "testkey"); -+ PotionEffect namedSpacedEffect = new PotionEffect(PotionEffectType.DOLPHINS_GRACE, 20, 0, true, true, true, key); -+ assertNotNull(namedSpacedEffect.getKey()); -+ assertTrue(namedSpacedEffect.hasKey()); -+ assertFalse(namedSpacedEffect.withKey(null).hasKey()); -+ -+ PotionEffect effect = new PotionEffect(PotionEffectType.DOLPHINS_GRACE, 20, 0, true, true, true); -+ assertNull(effect.getKey()); -+ assertFalse(effect.hasKey()); -+ assertTrue(namedSpacedEffect.withKey(key).hasKey()); -+ -+ Map s1 = namedSpacedEffect.serialize(); -+ Map s2 = effect.serialize(); -+ assertTrue(s1.containsKey("namespacedKey")); -+ assertFalse(s2.containsKey("namespacedKey")); -+ assertNotNull(new PotionEffect(s1).getKey()); -+ assertNull(new PotionEffect(s2).getKey()); -+ } -+ // Purpur end - } diff --git a/patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch b/patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch new file mode 100644 index 00000000..d7db7ee3 --- /dev/null +++ b/patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch @@ -0,0 +1,329 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Mon, 29 Apr 2024 14:18:58 -0400 +Subject: [PATCH] Fix Pufferfish and Purpur patches + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 0b4f7dcb082e758cfdce646c61175a48c0c1f5ec..dea8fef7abe8cfb7dabd8ae4aad748134f7bd47f 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -296,7 +296,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { + AtomicReference atomicreference = new AtomicReference(); +@@ -978,6 +978,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= (f - 0.4F) * 2.0F) return false; ++ // Gale end - JettPack - optimize sun burn tick - optimizations and cache eye blockpos + boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; + +- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { ++ if (!flag && this.level().canSeeSky(this.cached_eye_blockpos)) { // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos + return true; + } + } +@@ -891,7 +907,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public void tick() { + // Pufferfish start - entity TTL + if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) { +- discard(); ++ discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur + return; + } + // Pufferfish end - entity TTL +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index 8fdcb4d25f7398aad76f907be60c146413667353..c0eab84d85bdcd01058d3fa4871eb09e10b6171a 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -1068,17 +1068,19 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (entity != null) { + EntityType entitytypes = entity.getType(); + ++ // Gale start - Petal - reduce skull ItemStack lookups for reduced visibility + // Purpur start +- if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) { ++ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) { + d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent; +- } else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) { ++ } else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) { + d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent; +- } else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) { ++ } else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { + d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent; +- } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) { ++ } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD)) { + d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent; + } + // Purpur end ++ // Gale end - Petal - reduce skull ItemStack lookups for reduced visibility + + // Purpur start + if (entity instanceof LivingEntity entityliving) { +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index 446237ffe4f40cf287c57c28a9866dfea39ed1bb..3a153b7f1092c2d4ac6e0115f611d60907619a40 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -747,7 +747,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti + @Override + public void aiStep() { + super.aiStep(); +- if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level().purpurConfig.entitiesPickUpLootBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { ++ if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level().purpurConfig.entitiesPickUpLootBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur + 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(); +@@ -1860,11 +1860,6 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti + return flag; + } + +- // Gale start - JettPack - optimize sun burn tick - cache eye blockpos +- private BlockPos cached_eye_blockpos; +- private int cached_position_hashcode; +- // Gale end - JettPack - optimize sun burn tick - cache eye blockpos +- + public boolean isSunBurnTick() { + return super.isSunBurnTick(); + } +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +index 7db823e9edd70808c5629f0a7efd84fe40f42dd9..833858eacaf5ba788cb9f08a939379f0ff04b2cb 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +@@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; + public class TradeWithVillager extends Behavior { + // Gale start - optimize villager data storage + private static final Item[] WHEAT_SINGLETON_ARRAY = {Items.WHEAT}; ++ private static final Item[] NETHER_WART_SINGLETON_ARRAY = {Items.NETHER_WART}; // Leaf - sync with Gale's Optimize-villager-data-storage.patch + private @NotNull Item @Nullable [] trades = null; + // Gale end - optimize villager data storage + +@@ -65,7 +66,7 @@ public class TradeWithVillager extends Behavior { + + // Purpur start + if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) { +- throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager); ++ throwHalfStack(entity, NETHER_WART_SINGLETON_ARRAY, villager); // Leaf - sync with Gale's Optimize-villager-data-storage.patch + } + // Purpur end + +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +index 9419f230910d0338fc4ac6e2e7b749ee7d5ee362..2fe25397526c77c3b6b5e96d71d3681c6e26a54e 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +@@ -24,19 +24,15 @@ public class SecondaryPoiSensor extends Sensor { + + @Override + protected void doTick(ServerLevel world, Villager entity) { +- // Gale start - Lithium - skip secondary POI sensor if absent +- var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); +- if (secondaryPoi == null) { // Gale - optimize villager data storage +- entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); +- return; +- } +- // Gale end - Lithium - skip secondary POI sensor if absent + // Purpur start - make sure clerics don't wander to soul sand when the option is off + Brain brain = entity.getBrain(); +- if (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) { ++ // Gale start - Lithium - skip secondary POI sensor if absent ++ var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); ++ if (secondaryPoi == null || (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC)) { // Gale - optimize villager data storage + brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); + return; + } ++ // Gale end - Lithium - skip secondary POI sensor if absent + // Purpur end + ResourceKey resourceKey = world.dimension(); + BlockPos blockPos = entity.blockPosition(); +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 6697cd8a632becd72ee132007a61d1221e817abf..b6920eada151e1d282bf4ef70a64558eb592f879 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +@@ -680,7 +680,7 @@ public class ArmorStand extends LivingEntity { + + @Override + public void tick() { +- maxUpStep = level().purpurConfig.armorstandStepHeight; ++ maxUpStep = level().purpurConfig.armorstandStepHeight; // Purpur + // Paper start - Allow ArmorStands not to tick + if (!this.canTick) { + if (this.noTickPoseDirty) { +diff --git a/src/main/java/net/minecraft/world/entity/monster/Blaze.java b/src/main/java/net/minecraft/world/entity/monster/Blaze.java +index 27db17e19dd95e99f7bd67747eba3c3072b48ed5..4c87fa47a97a75a270a0f1332ee6aea69f9cf9c5 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Blaze.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Blaze.java +@@ -72,7 +72,6 @@ public class Blaze extends Monster { + setDeltaMovement(mot.scale(0.9D)); + } + } +- // Purpur end + + @Override + public void initAttributes() { +@@ -83,6 +82,7 @@ public class Blaze extends Monster { + protected boolean isAlwaysExperienceDropper() { + return this.level().purpurConfig.blazeAlwaysDropExp; + } ++ // Purpur end + + @Override + protected void registerGoals() { +diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +index 8f36f113e8eb3236ce53ad9cce320c3d6253d248..ebe79d9ad2934b53085c8a720fdfca0a6eda05ca 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java ++++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +@@ -31,7 +31,7 @@ public record VillagerProfession( + public static final VillagerProfession ARMORER = register("armorer", PoiTypes.ARMORER, SoundEvents.VILLAGER_WORK_ARMORER); + public static final VillagerProfession BUTCHER = register("butcher", PoiTypes.BUTCHER, SoundEvents.VILLAGER_WORK_BUTCHER); + public static final VillagerProfession CARTOGRAPHER = register("cartographer", PoiTypes.CARTOGRAPHER, SoundEvents.VILLAGER_WORK_CARTOGRAPHER); +- public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, ImmutableSet.of(Items.NETHER_WART), ImmutableSet.of(Blocks.SOUL_SAND), SoundEvents.VILLAGER_WORK_CLERIC); // Purpur ++ public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, new Item[] {Items.NETHER_WART}, Blocks.SOUL_SAND, SoundEvents.VILLAGER_WORK_CLERIC); // Purpur // Leaf - sync with Gale's Optimize-villager-data-storage.patch + public static final VillagerProfession FARMER = register( + "farmer", + PoiTypes.FARMER, +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 330d6badfbd096e4aec873dcb419df7975cb60a3..abb950417bf5db30f37e50605e897150bba67352 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +@@ -71,7 +71,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { + int maxChunkLoadsPerProjectile = maxProjectileChunkLoadsConfig.perProjectile.max; + if (maxChunkLoadsPerProjectile >= 0 && this.chunksLoadedByProjectile >= maxChunkLoadsPerProjectile) { + if (maxProjectileChunkLoadsConfig.perProjectile.removeFromWorldAfterReachLimit) { +- this.discard(); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur + } else if (maxProjectileChunkLoadsConfig.perProjectile.resetMovementAfterReachLimit) { + this.setDeltaMovement(0, this.getDeltaMovement().y, 0); + } +diff --git a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java +index 7fee1c2779ab390586b2d3f75f56890846323500..ba8912e1a16ba77db6e194923d797a383041a147 100644 +--- a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java ++++ b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java +@@ -68,7 +68,7 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { + // Gale end - branding changes - version fetcher + final Component history = getHistory(); + +- return history != null ? TextComponent.ofChildren(updateMessage, Component.newline(), history) : updateMessage; ++ return history != null ? Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()), history, updateMessage) : updateMessage; // Purpur + } + + protected @Nullable String getMinecraftVersion() { // Gale - branding changes - version fetcher +@@ -120,13 +120,13 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { + + switch (distance) { + case -1: +- return Component.text("Error obtaining version information", NamedTextColor.YELLOW); ++ return Component.text("* Error obtaining version information", NamedTextColor.RED); // Purpur + case 0: +- return Component.text("You are running the latest version", NamedTextColor.GREEN); ++ return Component.text("* You are running the latest version", NamedTextColor.GREEN); // Purpur + case -2: +- return Component.text("Unknown version", NamedTextColor.YELLOW); ++ return Component.text("* Unknown version", NamedTextColor.YELLOW); // Purpur + default: +- return Component.text("You are " + distance + " version(s) behind", NamedTextColor.YELLOW) ++ return Component.text("* You are " + distance + " version(s) behind", NamedTextColor.YELLOW) // Purpur + .append(Component.newline()) + .append(Component.text("Download the new version at: ") + .append(Component.text(this.downloadPage, NamedTextColor.GOLD) // Gale - branding changes - version fetcher diff --git a/patches/server/0011-Purpur-Configurable-server-mod-name.patch b/patches/server/0012-Purpur-Configurable-server-mod-name.patch similarity index 92% rename from patches/server/0011-Purpur-Configurable-server-mod-name.patch rename to patches/server/0012-Purpur-Configurable-server-mod-name.patch index 3ec55058..df84dc05 100644 --- a/patches/server/0011-Purpur-Configurable-server-mod-name.patch +++ b/patches/server/0012-Purpur-Configurable-server-mod-name.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/PurpurMC/Purpur diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b51f8d8173311a9322f3b63430c99c0e809bf34a..5db1dd834ec47c7a510e86f8eaffde03277a5442 100644 +index dea8fef7abe8cfb7dabd8ae4aad748134f7bd47f..20ec096a3a466f3b97e1723ffc5cc96848ce23e3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1855,7 +1855,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -index b66a7d4aab887309579154815a0d4abf9de506b0..78cb9d7da9bb025ea362028fdc9d0317de95959e 100644 +index 56b07a3306e5735816c8d89601b519cb0db6379a..524d9f0e2cc9a840fdf74bfa98537b5c8d572961 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java @@ -1779,7 +1779,6 @@ public final class NewChunkHolder { @@ -829,19 +829,17 @@ index b66a7d4aab887309579154815a0d4abf9de506b0..78cb9d7da9bb025ea362028fdc9d0317 return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; } diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 2e83fd8f0fd067d6585d66d7b419a39769eee312..c3e6102d1335ec99d1f8f8d6159e1606a1082828 100644 +index 6db7af1f073649dc1a35e00d38e961638ca84022..1bab647e27e72bc9e94454351c86435c4e663a7e 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -1,7 +1,7 @@ +@@ -1,6 +1,5 @@ package io.papermc.paper.configuration; -import co.aikar.timings.MinecraftTimings; import com.mojang.logging.LogUtils; -+import io.papermc.paper.configuration.constraint.Constraint; import io.papermc.paper.configuration.constraint.Constraints; import io.papermc.paper.configuration.type.number.IntOr; - import net.kyori.adventure.text.Component; -@@ -91,39 +91,6 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -91,39 +90,6 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean useDisplayNameInQuitMessage = false; } @@ -910,10 +908,10 @@ index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..a1c9726d25479b5326fe2fa2b0f5a98d } return ret; diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java -index dab211c458311869c61779305580a1c7da830f71..0ddcf3652a2cc9e0cc28f672f103ec7e271fc1fb 100644 +index 097500a59336db1bbfffcd1aa4cff7a8586e46ec..f06076864582ed153c6154fd7f3e9101bf21c4ac 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java -@@ -227,7 +227,7 @@ public class PaperPluginManagerImpl implements PluginManager, DependencyContext +@@ -232,7 +232,7 @@ public class PaperPluginManagerImpl implements PluginManager, DependencyContext @Override public boolean useTimings() { @@ -923,10 +921,10 @@ index dab211c458311869c61779305580a1c7da830f71..0ddcf3652a2cc9e0cc28f672f103ec7e @Override diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 83302c252f54481f239522e5c6861ccfe233070a..070231080052ef3d0da179a8ed8b754ed6f8dd11 100644 +index 57e76b53e5e314c3e6b8856010f7a84188121582..d6daa27a8d7aca00b181e90d789f4249e8437d29 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -49,8 +49,7 @@ public class PacketUtils { +@@ -50,8 +50,7 @@ public class PacketUtils { try { // Paper - detailed watchdog information if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players if (listener.shouldHandleMessage(packet)) { @@ -935,12 +933,12 @@ index 83302c252f54481f239522e5c6861ccfe233070a..070231080052ef3d0da179a8ed8b754e + try { packet.handle(listener); } catch (Exception exception) { - label25: + if (exception instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5c4272a9f25adad0dc21b03e8652a98b1fe2ddf1..8767b09e1b7e4626e2051535648cc45e129d7613 100644 +index 20ec096a3a466f3b97e1723ffc5cc96848ce23e3..10e3eb23c00b2af646f198f789129814beb656b1 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -178,8 +178,6 @@ import org.bukkit.craftbukkit.Main; +@@ -184,8 +184,6 @@ import org.bukkit.craftbukkit.Main; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end @@ -949,7 +947,7 @@ index 5c4272a9f25adad0dc21b03e8652a98b1fe2ddf1..8767b09e1b7e4626e2051535648cc45e public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, CommandSource, AutoCloseable { public static final int SERVER_THREAD_PRIORITY = Integer.getInteger("gale.thread.priority.server", -1); // Gale - server thread priority environment variable -@@ -959,7 +957,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick -@@ -1419,8 +1416,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -1033,7 +1031,7 @@ index 5c4272a9f25adad0dc21b03e8652a98b1fe2ddf1..8767b09e1b7e4626e2051535648cc45e // Paper start - Folia scheduler API ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); getAllLevels().forEach(level -> { -@@ -1668,20 +1651,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur -@@ -1721,14 +1698,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop waitable = new Waitable<>() { @@ -1154,7 +1144,6 @@ index 2d8676336d0bc4cb858e9ed3d7601173a33c0adf..a83fb872a1d186a3547c12f518e1bb00 - co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable)); - } else { - // Paper end -+ ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper); this.server.dispatchServerCommand(event.getSender(), serverCommand); - } // Paper @@ -1162,7 +1151,7 @@ index 2d8676336d0bc4cb858e9ed3d7601173a33c0adf..a83fb872a1d186a3547c12f518e1bb00 // Paper start if (waitableArray[0] != null) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559a373a289 100644 +index c8b898e8482f846641505531e8286d9d113c92f9..c700bb52cd7cfc264c0353d3b832547f7e336e32 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1,6 +1,5 @@ @@ -1172,7 +1161,7 @@ index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559 import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.Iterables; -@@ -538,13 +537,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -541,13 +540,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } protected void tick(BooleanSupplier shouldKeepTicking) { @@ -1186,7 +1175,7 @@ index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559 } } -@@ -1135,25 +1130,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1151,25 +1146,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - optimised tracker private final void processTrackQueue() { @@ -1212,7 +1201,7 @@ index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559 } // Paper end - optimised tracker -@@ -1167,7 +1151,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1183,7 +1167,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider List list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -1220,7 +1209,7 @@ index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559 ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1192,17 +1175,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1208,17 +1191,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -1239,10 +1228,10 @@ index de511a1d43aa78ec79c12d78635175336f77b62c..546028b42544bd62578e415faa245559 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67dbcef2ab4 100644 +index 1af3a2c078dc802aca2297d188c5ac068e073d26..e769e8d8e853b2731d85b75d273b029fd08861fa 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -276,10 +276,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -272,10 +272,8 @@ public class ServerChunkCache extends ChunkSource { if (!completablefuture.isDone()) { // Paper io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads @@ -1251,9 +1240,9 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system - this.level.timings.syncChunkLoad.stopTiming(); // Paper } // Paper - ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { - return ichunkaccess1; -@@ -428,17 +426,13 @@ public class ServerChunkCache extends ChunkSource { + ChunkResult chunkresult = (ChunkResult) completablefuture.join(); + ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error +@@ -423,17 +421,13 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -1271,12 +1260,15 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d } // Paper end - Incremental chunk and player saving -@@ -471,21 +465,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -466,24 +460,18 @@ public class ServerChunkCache extends ChunkSource { @Override public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { - this.level.timings.doChunkMap.startTiming(); // Spigot - this.distanceManager.purgeStaleTickets(); + if (this.level.tickRateManager().runsNormally() || !tickChunks) { + this.distanceManager.purgeStaleTickets(); + } + this.runDistanceManagerUpdates(); - this.level.timings.doChunkMap.stopTiming(); // Spigot if (tickChunks) { @@ -1293,7 +1285,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d this.clearCache(); } -@@ -495,8 +483,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -493,8 +481,6 @@ public class ServerChunkCache extends ChunkSource { this.lastInhabitedUpdate = i; if (!this.level.isDebug()) { @@ -1302,7 +1294,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d // Paper - optimise chunk tick iteration -@@ -508,7 +494,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -506,7 +492,6 @@ public class ServerChunkCache extends ChunkSource { boolean flagAndHasNaturalSpawn = flag && this.anySpawnCategoryIsSpawnedThisTick(); if (flagAndHasNaturalSpawn) { // Gale end - MultiPaper - skip unnecessary mob spawning computations @@ -1310,7 +1302,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d int k = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - Optional per player mob spawns int naturalSpawnChunkCount = k; -@@ -537,7 +522,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -535,7 +520,6 @@ public class ServerChunkCache extends ChunkSource { // Pufferfish end } // Paper end - Optional per player mob spawns @@ -1318,7 +1310,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously // Gale start - MultiPaper - skip unnecessary mob spawning computations -@@ -649,17 +633,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -647,17 +631,13 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -1336,7 +1328,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d // Paper start - optimise chunk tick iteration if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -@@ -673,7 +653,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -671,7 +651,6 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -1345,7 +1337,7 @@ index 6587ce30d88983cb42822e6ff3e012047d3ce16d..93ec0bdece165e5a5058f9a7ed2fd67d } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb4ad26342 100644 +index 8099bcb9e66ddd0ae4518e8a0129d72823cdcff1..2d649d98985203005f3e423d61e88a8ec7dbc380 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1,7 +1,6 @@ @@ -1356,7 +1348,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -862,27 +861,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -868,27 +867,19 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickTime(); } @@ -1384,7 +1376,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb } this.handlingTick = false; -@@ -893,13 +884,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -899,13 +890,11 @@ public class ServerLevel extends Level implements WorldGenLevel { } if (flag1 || this.emptyTime++ < 300) { @@ -1398,7 +1390,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb this.entityTickList.forEach((entity) -> { entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { -@@ -936,8 +925,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -942,8 +931,6 @@ public class ServerLevel extends Level implements WorldGenLevel { } } }); @@ -1407,7 +1399,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb this.tickBlockEntities(); } -@@ -1071,7 +1058,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1077,7 +1064,6 @@ public class ServerLevel extends Level implements WorldGenLevel { } } // Paper - Option to disable ice and snow @@ -1415,7 +1407,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb if (randomTickSpeed > 0) { // Paper start - optimize random block ticking LevelChunkSection[] sections = chunk.getSections(); -@@ -1104,8 +1090,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1110,8 +1096,6 @@ public class ServerLevel extends Level implements WorldGenLevel { } } // Paper end - optimise random block ticking @@ -1424,7 +1416,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb } @VisibleForTesting -@@ -1435,31 +1419,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1441,31 +1425,21 @@ public class ServerLevel extends Level implements WorldGenLevel { currentlyTickingEntity.lazySet(entity); } // Paper end - log detailed entity tick information @@ -1456,7 +1448,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1467,7 +1441,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1473,7 +1447,6 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(entity, entity1); } @@ -1464,7 +1456,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb // Paper start - log detailed entity tick information } finally { if (currentlyTickingEntity.get() == entity) { -@@ -1482,9 +1455,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1488,9 +1461,6 @@ 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); @@ -1474,7 +1466,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb passenger.setOldPosAndRot(); ++passenger.tickCount; // Paper start - EAR 2 -@@ -1505,8 +1475,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1511,8 +1481,6 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(passenger, entity2); } @@ -1483,7 +1475,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb } } else { passenger.stopRiding(); -@@ -1526,14 +1494,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1532,14 +1500,11 @@ public class ServerLevel extends Level implements WorldGenLevel { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); } @@ -1498,7 +1490,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb // Copied from save() // CraftBukkit start - moved from MinecraftServer.saveChunks -@@ -1545,7 +1510,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1551,7 +1516,6 @@ public class ServerLevel extends Level implements WorldGenLevel { this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); } // CraftBukkit end @@ -1506,7 +1498,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb } // Paper end - Incremental chunk and player saving -@@ -1559,7 +1523,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1565,7 +1529,6 @@ public class ServerLevel extends Level implements WorldGenLevel { if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit @@ -1514,7 +1506,7 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1569,11 +1532,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1575,11 +1538,8 @@ public class ServerLevel extends Level implements WorldGenLevel { progressListener.progressStage(Component.translatable("menu.savingChunks")); } @@ -1527,10 +1519,10 @@ index 9eb2bc23a2e7dce3594d67ec97ba120824a80ab1..a04ea23c295b493984eb841253fcb0eb } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4a9c82780cf5b54a2e16d092b485aa131d3aea11..a46b3f0b3a4d6827876c0a1b1bd6ae01ef13466a 100644 +index 45cf2c58fac237fe169a4be75c9a445a002389dd..b36daaeb6372cb217c579d0449a19a71c0c3bef1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2483,7 +2483,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2529,7 +2529,6 @@ 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 @@ -1538,7 +1530,7 @@ index 4a9c82780cf5b54a2e16d092b485aa131d3aea11..a46b3f0b3a4d6827876c0a1b1bd6ae01 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2493,7 +2492,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2539,7 +2538,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -1546,7 +1538,7 @@ index 4a9c82780cf5b54a2e16d092b485aa131d3aea11..a46b3f0b3a4d6827876c0a1b1bd6ae01 return; } -@@ -2505,8 +2503,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2551,8 +2549,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; @@ -1556,7 +1548,7 @@ index 4a9c82780cf5b54a2e16d092b485aa131d3aea11..a46b3f0b3a4d6827876c0a1b1bd6ae01 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b..7d98ba26ccde1e57378253e03c437650051f7843 100644 +index 743e1487048f70ed577452c27c7919d74d26ab19..c9673051ce9f4096b981087eefe8b72bbe34819a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1,6 +1,5 @@ @@ -1566,7 +1558,7 @@ index 3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b..7d98ba26ccde1e57378253e03c437650 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1338,7 +1337,6 @@ public abstract class PlayerList { +@@ -1337,7 +1336,6 @@ public abstract class PlayerList { public void saveAll(int interval) { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main @@ -1574,7 +1566,7 @@ index 3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b..7d98ba26ccde1e57378253e03c437650 int numSaved = 0; long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1349,7 +1347,6 @@ public abstract class PlayerList { +@@ -1348,7 +1346,6 @@ public abstract class PlayerList { } // Paper end - Incremental chunk and player saving } @@ -1583,26 +1575,21 @@ index 3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b..7d98ba26ccde1e57378253e03c437650 } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index a9e2a758669550530eb29475ba99fe42e520f6ae..d617e803f47219621b6b3b42c3bb7f30eb6cb805 100644 +index 32a1b5a1d01fd4dc603a76fde259f3a0d4749fad..4714cbf21f4edb41ee07c7eac180a6806afb7e9e 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -340,15 +340,6 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -356,10 +356,6 @@ public class EntityType implements FeatureElement, EntityTypeT + this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); } - - public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures) { -- // Paper start -- this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); -- } -- public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures, String id) { + public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures, String id) { - this.tickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "tick"); - this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); - this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); - this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); -- // Paper end + // Paper end this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); this.factory = factory; - this.category = spawnGroup; -@@ -720,12 +711,6 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -729,12 +725,6 @@ public class EntityType implements FeatureElement, EntityTypeT return this.updateInterval; } @@ -1615,17 +1602,8 @@ index a9e2a758669550530eb29475ba99fe42e520f6ae..d617e803f47219621b6b3b42c3bb7f30 public boolean trackDeltas() { return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; } -@@ -835,7 +820,7 @@ public class EntityType implements FeatureElement, EntityTypeT - Util.fetchChoiceType(References.ENTITY_TREE, id); - } - -- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions, this.clientTrackingRange, this.updateInterval, this.requiredFeatures, id); // Paper - add id -+ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions, this.clientTrackingRange, this.updateInterval, this.requiredFeatures); - } - } - diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java -index 03092417cd8ab5c6d266f3af9f20f47b34cfaba3..ffa4965ef1290a65d5c0261821e360d48fbad7d9 100644 +index 9379dd4056018b52c93ed4888dcdc94579bd9691..c6a7bb3e710b0e3f7e00a11fa5057a24aee8d7a3 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java @@ -14,10 +14,9 @@ public abstract class Behavior implements BehaviorContro @@ -1647,7 +1625,7 @@ index 03092417cd8ab5c6d266f3af9f20f47b34cfaba3..ffa4965ef1290a65d5c0261821e360d4 this.entryCondition = requiredMemoryState; - // Paper start - configurable behavior tick rate and timings + // Paper start - configurable behavior tick rate - String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()); + String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName(); int lastSeparator = key.lastIndexOf('.'); if (lastSeparator != -1) { key = key.substring(lastSeparator + 1); @@ -1696,7 +1674,7 @@ index 03092417cd8ab5c6d266f3af9f20f47b34cfaba3..ffa4965ef1290a65d5c0261821e360d4 protected void tick(ServerLevel world, E entity, long time) { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -index 9e90cb2f51d1bacacb287e912d14ab9152523205..57665076cbc6b1b506f38080c0c9612ea18d944a 100644 +index 85b4b24361e785acf75571ff98f924c00ae80748..ac67dd7a30616fe70f73426e332972b7b942e91e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java @@ -26,20 +26,18 @@ public abstract class Sensor { @@ -1712,7 +1690,7 @@ index 9e90cb2f51d1bacacb287e912d14ab9152523205..57665076cbc6b1b506f38080c0c9612e public Sensor(int senseInterval) { - // Paper start - configurable sensor tick rate and timings + // Paper start - configurable sensor tick rate - String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()); + String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName(); int lastSeparator = key.lastIndexOf('.'); if (lastSeparator != -1) { key = key.substring(lastSeparator + 1); @@ -1737,7 +1715,7 @@ index 9e90cb2f51d1bacacb287e912d14ab9152523205..57665076cbc6b1b506f38080c0c9612e } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 52fcce3b1c01c221becadc39334dc3b1de12e688..138c14ced11354e67b84956bdd02f90c1bed409e 100644 +index 1397f54cef6cc23ba99a4faa36bf862318da9270..a304242573189b241228a40b7fd831c3326f11b6 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -176,7 +176,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -1748,15 +1726,15 @@ index 52fcce3b1c01c221becadc39334dc3b1de12e688..138c14ced11354e67b84956bdd02f90c public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; -@@ -364,7 +363,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -361,7 +360,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} }); // CraftBukkit end - this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings - this.keepSpawnInMemory = this.paperConfig().spawn.keepSpawnLoaded; // Paper - Option to keep spawn chunks loaded this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); -@@ -1332,15 +1330,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray +@@ -1326,15 +1324,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } protected void tickBlockEntities() { @@ -1772,7 +1750,7 @@ index 52fcce3b1c01c221becadc39334dc3b1de12e688..138c14ced11354e67b84956bdd02f90c // Spigot start // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); -@@ -1369,9 +1364,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1363,9 +1358,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 @@ -1783,10 +1761,10 @@ index 52fcce3b1c01c221becadc39334dc3b1de12e688..138c14ced11354e67b84956bdd02f90c } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 88b13e6eeec956c10b486e4811b1e0dae0fd990e..31003588de8bef9952a688c486049077328e89a3 100644 +index 27fccd091535f7587aaaa1621361dc1835381b89..885d7c9ef96dd3c7576c28606e5ab83d2a75de71 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -132,7 +132,6 @@ public final class NaturalSpawner { +@@ -127,7 +127,6 @@ public final class NaturalSpawner { } public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn) { @@ -1794,7 +1772,7 @@ index 88b13e6eeec956c10b486e4811b1e0dae0fd990e..31003588de8bef9952a688c486049077 MobCategory[] aenumcreaturetype = NaturalSpawner.SPAWNING_CATEGORIES; int i = aenumcreaturetype.length; -@@ -184,8 +183,6 @@ public final class NaturalSpawner { +@@ -179,8 +178,6 @@ public final class NaturalSpawner { // Paper end - Optional per player mob spawns } } @@ -1804,10 +1782,10 @@ index 88b13e6eeec956c10b486e4811b1e0dae0fd990e..31003588de8bef9952a688c486049077 // Paper start - Add mobcaps commands 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 8c242b67f162a40311d7d987fd76771c38c3eadb..f1ca87ab1ab07a5b8ddda959a90f29ea6a16b346 100644 +index 14aaabb6b9595847358f65ff01c81b179d9548ea..3dc9f10f00dd982ca28a66b364e5088c3413d5ef 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -114,13 +114,6 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -107,13 +107,6 @@ public class Block extends BlockBehaviour implements ItemLike { this != Blocks.STRUCTURE_BLOCK && this != Blocks.JIGSAW; } @@ -1822,10 +1800,10 @@ index 8c242b67f162a40311d7d987fd76771c38c3eadb..f1ca87ab1ab07a5b8ddda959a90f29ea @Nullable private String descriptionId; 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 07a83e06e9cb6e30c600445809e49a3fd23a391a..171feda35239281b0ec2416485bead192dd9d0f0 100644 +index 5168e8e9ebb54b6c00acb7f2939262eb06a7426d..4687526a250ef4e6f2aead29cf4ccb1e2e38c20e 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 -@@ -23,14 +23,9 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; +@@ -33,14 +33,9 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; import org.bukkit.inventory.InventoryHolder; // CraftBukkit end @@ -1841,7 +1819,7 @@ index 07a83e06e9cb6e30c600445809e49a3fd23a391a..171feda35239281b0ec2416485bead19 private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); public CraftPersistentDataContainer persistentDataContainer; 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 3efdd1513089c663aa5c33eace0b31a599eca2eb..f52b314dd0ed83682b6a60c66b21eefd2cefb793 100644 +index 35147d7a6649708c2b068065eb44831f40c3ab8e..1a2ef85cd8a62824b23f4212a5e2a70ce89e344f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -792,7 +792,6 @@ public class LevelChunk extends ChunkAccess { @@ -1860,7 +1838,7 @@ index 3efdd1513089c663aa5c33eace0b31a599eca2eb..f52b314dd0ed83682b6a60c66b21eefd } } } -@@ -1167,7 +1165,6 @@ public class LevelChunk extends ChunkAccess { +@@ -1165,7 +1163,6 @@ public class LevelChunk extends ChunkAccess { if (LevelChunk.this.isTicking(blockposition)) { try { @@ -1868,7 +1846,7 @@ index 3efdd1513089c663aa5c33eace0b31a599eca2eb..f52b314dd0ed83682b6a60c66b21eefd BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1190,14 +1187,9 @@ public class LevelChunk extends ChunkAccess { +@@ -1188,14 +1185,9 @@ public class LevelChunk extends ChunkAccess { net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent LevelChunk.this.removeBlockEntity(this.getPos()); // Paper end - Prevent block entity and entity crashes @@ -1884,7 +1862,7 @@ index 3efdd1513089c663aa5c33eace0b31a599eca2eb..f52b314dd0ed83682b6a60c66b21eefd @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f4fb23ebdd35e23b022bdd78421dec6d86342260..3c3b98d13587ce21bffa14a79aed963a7ce1f176 100644 +index 339b16641a7548d89fb15baad8edf0c5f95db635..f17eb11741d09f9b04eac98918261680b600749a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -470,7 +470,6 @@ public final class CraftServer implements Server { @@ -1896,10 +1874,10 @@ index f4fb23ebdd35e23b022bdd78421dec6d86342260..3c3b98d13587ce21bffa14a79aed963a console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index bac135289e34c69ff0d02ff23b8a95d72505e1bc..dcb6ccda0b46dc271be305c93df5c7db574bc07b 100644 +index 42f08f65207673125b288d4a74fc6d18eb713e9e..f236e7c56c6c72f3fcdba8314f258026e6561ecb 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -373,8 +373,6 @@ public class Main { +@@ -374,8 +374,6 @@ public class Main { tryPreloadClass("org.jline.terminal.impl.MouseSupport"); tryPreloadClass("org.jline.terminal.impl.MouseSupport$1"); tryPreloadClass("org.jline.terminal.Terminal$MouseTracking"); @@ -2049,33 +2027,29 @@ index b3e1adeb932da9b3bed16acd94e2f16da48a7c72..e9798517b9211c50a20ea5c69603aab3 } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 53b73cac093797de47a9e61a5fdab44aced54ebb..aff95d844d810fb145b7587fef28df66e47d6530 100644 +index d67089b621f3ba07f3cf4cd64ee6ccb99ed23445..44153969844ac521cc082c9bdb3bd02e100f2b7e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -214,12 +214,6 @@ public final class CraftMagicNumbers implements UnsafeValues { - } - // Paper end +@@ -214,9 +214,7 @@ public final class CraftMagicNumbers implements UnsafeValues { // ======================================================================== -- // Paper start -- @Override + // Paper start + @Override - public void reportTimings() { - co.aikar.timings.TimingsExport.reportTimings(); - } -- // Paper end ++ public void reportTimings() {} // Leaf - Remove Timings + // Paper end public static byte toLegacyData(BlockState data) { - return CraftLegacy.toLegacyData(data); -@@ -495,10 +489,6 @@ public final class CraftMagicNumbers implements UnsafeValues { - return new CraftDamageSourceBuilder(damageType); - } +@@ -502,7 +500,7 @@ public final class CraftMagicNumbers implements UnsafeValues { // Paper start -- @Override -- public String getTimingsServerName() { + @Override + public String getTimingsServerName() { - return io.papermc.paper.configuration.GlobalConfiguration.get().timings.serverName; -- } ++ return org.dreeam.leaf.config.modules.misc.ServerBrand.serverModName; // Leaf - Remove Timings + } @Override - public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { diff --git a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java index b4cca06a583fbb7918237de256f43ee61fd8ec6c..dd4a5f610e6e84a73051a8ed46e1961804356ca3 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java diff --git a/patches/server/0014-Bump-Dependencies.patch b/patches/server/0015-Bump-Dependencies.patch similarity index 68% rename from patches/server/0014-Bump-Dependencies.patch rename to patches/server/0015-Bump-Dependencies.patch index e16307fd..c4d74243 100644 --- a/patches/server/0014-Bump-Dependencies.patch +++ b/patches/server/0015-Bump-Dependencies.patch @@ -5,22 +5,19 @@ Subject: [PATCH] Bump Dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 0d72b6e0a9d9c12b7d4555aa85dcedde9123c5c1..00c01da244709b68448815e9188414d70440d59b 100644 +index 2e0bb52941718f4ae2600e293bbe4126d0889f40..7c663d28213322165245c6946c6a73cbc5cbf50b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -32,9 +32,9 @@ dependencies { - // Leaf end +@@ -31,7 +31,7 @@ dependencies { + // Leaf end - Legacy config // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("org.jline:jline-terminal-jansi:3.26.0") // Leaf - Bump Dependencies implementation("net.minecrell:terminalconsoleappender:1.3.0") -- implementation("net.kyori:adventure-text-serializer-ansi:4.14.0") // Keep in sync with adventureVersion from Paper-API build file -+ implementation("net.kyori:adventure-text-serializer-ansi:4.16.0") // Keep in sync with adventureVersion from Paper-API build file // Leaf - Bump Dependencies - implementation("net.kyori:ansi:1.0.3") // Manually bump beyond above transitive dep + implementation("net.kyori:adventure-text-serializer-ansi:4.16.0") // Keep in sync with adventureVersion from Paper-API build file /* - Required to add the missing Log4j2Plugins.dat file from log4j-core -@@ -42,29 +42,31 @@ dependencies { +@@ -40,28 +40,32 @@ dependencies { all its classes to check if they are plugins. Scanning takes about 1-2 seconds so adding this speeds up the server start. */ @@ -34,18 +31,15 @@ index 0d72b6e0a9d9c12b7d4555aa85dcedde9123c5c1..00c01da244709b68448815e9188414d7 - implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol + implementation("io.netty:netty-codec-haproxy:4.1.109.Final") // Paper - Add support for proxy protocol // Paper end -- implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion +- implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion + implementation("org.apache.logging.log4j:log4j-iostreams:2.23.1") // Paper - remove exclusion ++ // Leaf end - Bump Dependencies implementation("org.ow2.asm:asm-commons:9.7") implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files implementation("commons-lang:commons-lang:2.6") -- implementation("net.fabricmc:mapping-io:0.5.0") // Paper - needed to read mappings for stacktrace deobfuscation -- runtimeOnly("org.xerial:sqlite-jdbc:3.42.0.1") -- runtimeOnly("com.mysql:mysql-connector-j:8.2.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.45.3.0") + runtimeOnly("com.mysql:mysql-connector-j:8.3.0") - runtimeOnly("com.lmax:disruptor:3.4.4") // Paper -+ implementation("net.fabricmc:mapping-io:0.6.1") // Paper - needed to read mappings for stacktrace deobfuscation -+ runtimeOnly("org.xerial:sqlite-jdbc:3.45.3.0") -+ runtimeOnly("com.mysql:mysql-connector-j:8.3.0") + runtimeOnly("com.lmax:disruptor:3.4.4") // Paper // Leaf - Bump Dependencies - Waiting Log4j 3.x to support disruptor 4.0.0 // Paper start - Use Velocity cipher - implementation("com.velocitypowered:velocity-native:3.1.2-SNAPSHOT") { @@ -57,36 +51,37 @@ index 0d72b6e0a9d9c12b7d4555aa85dcedde9123c5c1..00c01da244709b68448815e9188414d7 runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") - runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") - runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") ++ // Leaf start - Bump Dependencies + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.19") + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.19") + // Leaf end // Purpur start implementation("org.mozilla:rhino-runtime:1.7.14") -@@ -72,12 +74,16 @@ dependencies { +@@ -69,7 +73,7 @@ dependencies { implementation("dev.omega24:upnp4j:1.0") // Purpur end - testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test -- testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") -+ // Leaf start - Bump Dependencies -+ testImplementation("io.github.classgraph:classgraph:4.8.172") // Paper - mob goal test -+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") ++ testImplementation("io.github.classgraph:classgraph:4.8.172") // Paper - mob goal test // Leaf - Bump Dependencies + testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.mockito:mockito-core:5.11.0") - testImplementation("org.ow2.asm:asm-tree:9.7") - testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest +@@ -83,6 +87,8 @@ dependencies { + implementation("io.papermc:reflection-rewriter-runtime:$reflectionRewriterVersion") + implementation("io.papermc:reflection-rewriter-proxy-generator:$reflectionRewriterVersion") + // Paper end - Remap reflection + -+ implementation("io.netty:netty-all:4.1.109.Final") -+ // Leaf end ++ implementation("io.netty:netty-all:4.1.109.Final") // Leaf - Bump Dependencies } - val craftbukkitPackageVersion = "1_20_R3" // Paper -@@ -258,3 +264,7 @@ sourceSets { + paperweight { +@@ -270,3 +276,8 @@ sourceSets { } } // Gale end - package license into jar -+ ++// Leaf start - Bump Dependencies +repositories { + mavenCentral() +} ++// Leaf end - Bump Dependencies diff --git a/patches/server/0015-Remove-vanilla-username-check.patch b/patches/server/0016-Remove-vanilla-username-check.patch similarity index 61% rename from patches/server/0015-Remove-vanilla-username-check.patch rename to patches/server/0016-Remove-vanilla-username-check.patch index 4e595f2f..4915bc89 100644 --- a/patches/server/0015-Remove-vanilla-username-check.patch +++ b/patches/server/0016-Remove-vanilla-username-check.patch @@ -5,22 +5,19 @@ Subject: [PATCH] Remove vanilla username check diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 4bd1d7c4328e13ae3e173836ced22125857bcae1..0f3ba1abb609562e92dd9eb0ab7a621b8ed2d09f 100644 +index 52c5ce7339029d7cc3bb1164131a9f96598760c0..1d496b2efc44065e91b4d612e17f38382489e876 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -153,7 +153,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, - public void handleHello(ServerboundHelloPacket packet) { +@@ -181,7 +181,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, // Gale start - JettPack - reduce array allocations Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", ArrayConstants.emptyObjectArray); -- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) Validate.validState(Player.isValidUsername(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); // Paper - config username validation -+ // Leaf start - Remove Vanilla username check -+ if (!org.dreeam.leaf.config.modules.misc.RemoveVanillaUsernameCheck.enabled) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) Validate.validState(Player.isValidUsername(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); // Paper - config username validation -+ } -+ // Leaf end - // Gale end - JettPack - reduce array allocations - this.requestedUsername = packet.name(); - GameProfile gameprofile = this.server.getSingleplayerProfile(); + // Paper start - Validate usernames +- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() ++ if (!org.dreeam.leaf.config.modules.misc.RemoveVanillaUsernameCheck.enabled // Leaf - Remove Vanilla username check ++ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() + && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation + && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) { + Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..2dcdf5adff80f63499e6d160ff24313653cfb315 diff --git a/patches/server/0016-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch b/patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch similarity index 62% rename from patches/server/0016-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch rename to patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch index 8666d7e6..cf16140c 100644 --- a/patches/server/0016-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch +++ b/patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch @@ -5,18 +5,18 @@ Subject: [PATCH] Remove Spigot Check for Broken BungeeCord Configurations diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -index dec666713a1d3b5e3f2aa4bcbe8094ade8be1b05..c72620cce4ca7b6751b00f42b6c3d8f5d9a19132 100644 +index cd9cf7e09d9d271001ef378496fd0955c39bf13e..06d7161008bd80d789780196c4ac91b47ec91cfa 100644 --- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -@@ -147,7 +147,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL - { - this.connection.spoofedProfile = ServerHandshakePacketListenerImpl.gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); - } -- } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { -+ } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) && !(org.dreeam.leaf.config.modules.misc.RemoveSpigotCheckBungee.enabled)) { // Leaf - Remove Spigot check for broken BungeeCord configurations - Component chatmessage = Component.literal("Unknown data in login hostname, did you forget to enable BungeeCord in spigot.yml?"); - this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); - this.connection.disconnect(chatmessage); +@@ -177,7 +177,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL + { + this.connection.spoofedProfile = ServerHandshakePacketListenerImpl.gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); + } +- } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { ++ } else if (!org.dreeam.leaf.config.modules.misc.RemoveSpigotCheckBungee.enabled && ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() )) { // Leaf - Remove Spigot check for broken BungeeCord configurations + Component chatmessage = Component.literal("Unknown data in login hostname, did you forget to enable BungeeCord in spigot.yml?"); + this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); + this.connection.disconnect(chatmessage); diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveSpigotCheckBungee.java b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveSpigotCheckBungee.java new file mode 100644 index 0000000000000000000000000000000000000000..bca9e66deb5afd7ea25ad2532a207771ab93084f diff --git a/patches/server/0017-Remove-UseItemOnPacket-Too-Far-Check.patch b/patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch similarity index 72% rename from patches/server/0017-Remove-UseItemOnPacket-Too-Far-Check.patch rename to patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch index e7aa4053..b116c1df 100644 --- a/patches/server/0017-Remove-UseItemOnPacket-Too-Far-Check.patch +++ b/patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch @@ -7,15 +7,15 @@ This Check is added in 1.17.x -> 1.18.x update by Mojang. By removing this check, it enable hackers to use some modules of hack clients. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1d0c724137c002801b3dbb239278f2a1c82c1d77..8895e7d35af8650503853b6fc7432f66e4f333db 100644 +index a18cbed0089a845eaf31b1ac351c60bbfede7aad..bafe83f2a9b12868a7f310ab3a63c2302cbac28f 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2007,7 +2007,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - Vec3 vec3d2 = vec3d.subtract(vec3d1); +@@ -1984,7 +1984,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + Vec3 vec3d1 = vec3d.subtract(Vec3.atCenterOf(blockposition)); double d0 = 1.0000001D; -- if (Math.abs(vec3d2.x()) < 1.0000001D && Math.abs(vec3d2.y()) < 1.0000001D && Math.abs(vec3d2.z()) < 1.0000001D) { -+ if ((Math.abs(vec3d2.x()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d2.y()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d2.z()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance) || org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.removeUseItemOnPacketTooFarCheck) { // Leaf - Remove UseItemOnPacket Too Far Check and make it configurable +- if (Math.abs(vec3d1.x()) < 1.0000001D && Math.abs(vec3d1.y()) < 1.0000001D && Math.abs(vec3d1.z()) < 1.0000001D) { ++ if (org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.removeUseItemOnPacketTooFarCheck || (Math.abs(vec3d1.x()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d1.y()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d1.z()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance)) { // Leaf - Remove UseItemOnPacket Too Far Check and make it configurable Direction enumdirection = movingobjectpositionblock.getDirection(); this.player.resetLastActionTime(); diff --git a/patches/server/0018-KTP-Allow-unknown-event-thread-execution.patch b/patches/server/0019-KTP-Allow-unknown-event-thread-execution.patch similarity index 100% rename from patches/server/0018-KTP-Allow-unknown-event-thread-execution.patch rename to patches/server/0019-KTP-Allow-unknown-event-thread-execution.patch diff --git a/patches/server/0019-KeYi-Player-Skull-API.patch b/patches/server/0020-KeYi-Player-Skull-API.patch similarity index 53% rename from patches/server/0019-KeYi-Player-Skull-API.patch rename to patches/server/0020-KeYi-Player-Skull-API.patch index 6c144376..fde0835e 100644 --- a/patches/server/0019-KeYi-Player-Skull-API.patch +++ b/patches/server/0020-KeYi-Player-Skull-API.patch @@ -7,30 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index fb2d05e43df3bfb72b1f6e325736dd3cbc6c3096..635f10ca1954b10eaf8e354dd4e1cbf010d7a659 100644 +index 90338017ebcb2a690dff7dad57aa6fbb95e0ff93..fd57b7f69f3a8ee490cd4fa55c0e5480e0a4a14b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -29,6 +29,11 @@ import java.util.Optional; - import java.util.Set; - import java.util.UUID; - import java.util.WeakHashMap; -+// Leaf start - KeYi - Player Skull API -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+// Leaf end - KeYi - import java.util.logging.Level; - import java.util.logging.Logger; - import javax.annotation.Nullable; -@@ -167,6 +172,7 @@ import org.bukkit.event.player.PlayerUnregisterChannelEvent; - import org.bukkit.inventory.EquipmentSlot; - import org.bukkit.inventory.InventoryView.Property; - import org.bukkit.inventory.ItemStack; -+import org.bukkit.inventory.meta.SkullMeta; // Leaf - KeYi - Player Skull API - import org.bukkit.map.MapCursor; - import org.bukkit.map.MapView; - import org.bukkit.metadata.MetadataValue; -@@ -3553,4 +3559,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3610,4 +3610,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket(getEntityId(), io.papermc.paper.adventure.PaperAdventure.asVanilla(message))); } // Purpur end @@ -39,7 +19,7 @@ index fb2d05e43df3bfb72b1f6e325736dd3cbc6c3096..635f10ca1954b10eaf8e354dd4e1cbf0 + @Override + public ItemStack getSkull() { + ItemStack skull = new ItemStack(Material.PLAYER_HEAD, 1); -+ SkullMeta meta = (SkullMeta) skull.getItemMeta(); ++ org.bukkit.inventory.meta.SkullMeta meta = (org.bukkit.inventory.meta.SkullMeta) skull.getItemMeta(); + + meta.setOwningPlayer(this); + skull.setItemMeta(meta); @@ -49,12 +29,12 @@ index fb2d05e43df3bfb72b1f6e325736dd3cbc6c3096..635f10ca1954b10eaf8e354dd4e1cbf0 + + @Override + public CompletableFuture getSkullAsynchronously() { -+ ExecutorService executorService = Executors.newCachedThreadPool(); ++ java.util.concurrent.ExecutorService executorService = java.util.concurrent.Executors.newCachedThreadPool(); + + CompletableFuture future = (CompletableFuture) executorService.submit(this::getSkull); + executorService.shutdown(); + + return future; + } -+ // Leaf end - KeYi ++ // Leaf end - KeYi - Player Skull API } diff --git a/patches/server/0020-KeYi-Disable-arrow-despawn-counter-by-default.patch b/patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch similarity index 86% rename from patches/server/0020-KeYi-Disable-arrow-despawn-counter-by-default.patch rename to patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch index ebdab276..c41842a4 100644 --- a/patches/server/0020-KeYi-Disable-arrow-despawn-counter-by-default.patch +++ b/patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch @@ -7,15 +7,15 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -index 2b8f53fc53dc69aa9afd516ef4a81ecf7b43e62c..356ec77bf63da9a218036c92bde9bf5fa006c1ac 100644 +index 758cc7862121e7c27db5e087f816aab566320162..c3c9fc0d126e3f258fa8f06901fb3cac0d0ab289 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java +++ b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -@@ -138,7 +138,7 @@ public class GaleWorldConfiguration extends ConfigurationPart { +@@ -137,7 +137,7 @@ public class GaleWorldConfiguration extends ConfigurationPart { public boolean loadPortalDestinationChunkBeforeEntityTeleport = false; // Gale - MultiPaper - load portal destination chunk before entity teleport } - public boolean arrowMovementResetsDespawnCounter = true; // Gale - Purpur - make arrow movement resetting despawn counter configurable -+ public boolean arrowMovementResetsDespawnCounter = false; // Gale - Purpur - make arrow movement resetting despawn counter configurable // Leaf - KeYi - disable arrow despawn counter by default ++ public boolean arrowMovementResetsDespawnCounter = false; // Gale - Purpur - make arrow movement resetting despawn counter configurable // Leaf - KeYi - Disable arrow despawn counter by default public boolean entitiesCanRandomStrollIntoNonTickingChunks = true; // Gale - MultiPaper - prevent entities random strolling into non-ticking chunks public double entityWakeUpDurationRatioStandardDeviation = 0.2; // Gale - variable entity wake-up duration public boolean hideFlamesOnEntitiesWithFireResistance = false; // Gale - Slice - hide flames on entities with fire resistance diff --git a/patches/server/0021-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch b/patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch similarity index 93% rename from patches/server/0021-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch rename to patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch index 4de227e2..97e753a4 100644 --- a/patches/server/0021-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch +++ b/patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi 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 84712ae2d9f6024426fe4700f5539a5a33c2fc46..56f9b0c9277aeff3b2d3d7e44f8af6d8d6d23941 100644 +index e380d1ea5b3dd6e91e79f6d7bd5d980a2c32315a..18d1be51ca12c3ccac5a5130667c47c1f1235935 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -350,7 +350,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -356,7 +356,7 @@ public class ItemEntity extends Entity implements TraceableEntity { ItemStack itemstack1 = other.getItem(); if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) { diff --git a/patches/server/0022-Carpet-Fixes-Optimized-getBiome-method.patch b/patches/server/0023-Carpet-Fixes-Optimized-getBiome-method.patch similarity index 97% rename from patches/server/0022-Carpet-Fixes-Optimized-getBiome-method.patch rename to patches/server/0023-Carpet-Fixes-Optimized-getBiome-method.patch index 700bb632..c1b884bb 100644 --- a/patches/server/0022-Carpet-Fixes-Optimized-getBiome-method.patch +++ b/patches/server/0023-Carpet-Fixes-Optimized-getBiome-method.patch @@ -10,7 +10,7 @@ Optimized the getBiome call to be 25% - 75% faster This is a fully vanilla optimization. diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java -index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..bd9c58b0086ea6ba5a73b41e805d4c9af4dc357d 100644 +index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..b90a323c4fc9af141758a73a72e6918300caf470 100644 --- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java +++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java @@ -14,6 +14,7 @@ public class BiomeManager { @@ -117,7 +117,7 @@ index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..bd9c58b0086ea6ba5a73b41e805d4c9a + (smallestX & 2) == 0 ? y : y + 1, + (smallestX & 1) == 0 ? z : z + 1 + ); -+ // Leaf end - Carpet-Fixes ++ // Leaf end - Carpet-Fixes - Optimized getBiome method } public Holder getNoiseBiomeAtPosition(double x, double y, double z) { diff --git a/patches/server/0023-Carpet-Fixes-Use-optimized-RecipeManager.patch b/patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch similarity index 64% rename from patches/server/0023-Carpet-Fixes-Use-optimized-RecipeManager.patch rename to patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch index 4b1e1caf..92343aee 100644 --- a/patches/server/0023-Carpet-Fixes-Use-optimized-RecipeManager.patch +++ b/patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch @@ -11,25 +11,15 @@ This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/S This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -index d87124f5356180a37e581febc6141fdc5f1395a7..800f063f2b9f5803b45ca65f389b3295b27e6f86 100644 +index a31326e24cb68472c81cd781c5e3041772712862..0662e7afca15cab700dc61fe7de1d62eed27405d 100644 --- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java +++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -@@ -11,8 +11,8 @@ import com.google.gson.JsonParseException; - import com.mojang.datafixers.util.Pair; - import com.mojang.logging.LogUtils; - import com.mojang.serialization.JsonOps; -+import java.util.ArrayList; - import java.util.Collection; --import java.util.Collections; - import java.util.Comparator; - import java.util.Iterator; - import java.util.List; -@@ -137,7 +137,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { +@@ -132,7 +132,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { } public > List> getAllRecipesFor(RecipeType type) { -- return List.copyOf(this.byType(type).values()); -+ return new ArrayList<>(this.byType(type).values()); // Leaf - Carpet-Fixes +- return List.copyOf(this.byType(type)); ++ return new java.util.ArrayList<>(this.byType(type)); // Leaf - Carpet-Fixes } public > List> getRecipesFor(RecipeType type, C inventory, Level world) { diff --git a/patches/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/patches/server/0025-Rail-Optimization-optimized-PoweredRailBlock-logic.patch similarity index 99% rename from patches/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch rename to patches/server/0025-Rail-Optimization-optimized-PoweredRailBlock-logic.patch index effdf7b7..1e99850e 100644 --- a/patches/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch +++ b/patches/server/0025-Rail-Optimization-optimized-PoweredRailBlock-logic.patch @@ -12,7 +12,7 @@ powered rail logic from a single rail instead of each block iterating separately expensive but also completely unnecessary and with a lot of massive overhead 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 e03125281767845564c48c98c3e6b6bbd269ade1..4604ea57707ed51601ea53e32c025112536571de 100644 +index 8fc65c32a3c6e6842a76b36f45e1b1c23abbc480..b2a3150f08db32dcfecff0390eec810c9ec18a24 100644 --- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java @@ -29,7 +29,7 @@ public class PoweredRailBlock extends BaseRailBlock { diff --git a/patches/server/0025-Akarin-Save-Json-list-asynchronously.patch b/patches/server/0026-Akarin-Save-Json-list-asynchronously.patch similarity index 72% rename from patches/server/0025-Akarin-Save-Json-list-asynchronously.patch rename to patches/server/0026-Akarin-Save-Json-list-asynchronously.patch index 3025050f..ff3a14d0 100644 --- a/patches/server/0025-Akarin-Save-Json-list-asynchronously.patch +++ b/patches/server/0026-Akarin-Save-Json-list-asynchronously.patch @@ -8,18 +8,10 @@ Original license: GPL v3 Original project: https://github.com/Akarin-project/Akarin diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index c524ca1eab9db011f8203835c43e244ff4101e87..b5a31105ca972f5b6a6b74786904631aa0998ce9 100644 +index 1516232f116f1d48fe383d8c05c7dcc63b38f96a..523255345df9f4d84c5fa514de42620c4605d446 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java +++ b/src/main/java/net/minecraft/server/players/StoredUserList.java -@@ -22,6 +22,7 @@ import java.util.stream.Stream; - import javax.annotation.Nullable; - - import me.titaniumtown.ArrayConstants; -+import io.papermc.paper.util.MCUtil; - import net.minecraft.Util; - import net.minecraft.util.GsonHelper; - import org.slf4j.Logger; -@@ -104,6 +105,7 @@ public abstract class StoredUserList> { +@@ -104,6 +104,7 @@ public abstract class StoredUserList> { } public void save() throws IOException { @@ -27,7 +19,7 @@ index c524ca1eab9db011f8203835c43e244ff4101e87..b5a31105ca972f5b6a6b74786904631a this.removeExpired(); // Paper - remove expired values before saving JsonArray jsonarray = new JsonArray(); Stream stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error -@@ -115,6 +117,8 @@ public abstract class StoredUserList> { +@@ -115,6 +116,8 @@ public abstract class StoredUserList> { Objects.requireNonNull(jsonarray); stream.forEach(jsonarray::add); @@ -36,7 +28,7 @@ index c524ca1eab9db011f8203835c43e244ff4101e87..b5a31105ca972f5b6a6b74786904631a BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8); try { -@@ -135,6 +139,13 @@ public abstract class StoredUserList> { +@@ -135,6 +138,13 @@ public abstract class StoredUserList> { bufferedwriter.close(); } @@ -45,8 +37,8 @@ index c524ca1eab9db011f8203835c43e244ff4101e87..b5a31105ca972f5b6a6b74786904631a + StoredUserList.LOGGER.warn("Failed to async save " + this.file, e); + } + }; -+ MCUtil.scheduleAsyncTask(saveTask); -+ // Leaf end - Akarin ++ io.papermc.paper.util.MCUtil.scheduleAsyncTask(saveTask); ++ // Leaf end - Akarin - Save json list async } public void load() throws IOException { diff --git a/patches/server/0026-Slice-Smooth-Teleports.patch b/patches/server/0027-Slice-Smooth-Teleports.patch similarity index 88% rename from patches/server/0026-Slice-Smooth-Teleports.patch rename to patches/server/0027-Slice-Smooth-Teleports.patch index 31900f94..a1a68b67 100644 --- a/patches/server/0026-Slice-Smooth-Teleports.patch +++ b/patches/server/0027-Slice-Smooth-Teleports.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/Cryptite/Slice diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 82aa92a106f844578959158ce1518eb7d0766951..6568b4541a81d52cc81729eb8590cf3723289bac 100644 +index ada4956a0b204cb098e90979aff14db32455f481..31111babbb119175fa3c7b79624bb2a955b9cba3 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -286,6 +286,7 @@ public class ServerPlayer extends Player { +@@ -303,6 +303,7 @@ public class ServerPlayer extends Player { private boolean tpsBar = false; // Purpur private boolean compassBar = false; // Purpur private boolean ramBar = false; // Purpur @@ -19,10 +19,10 @@ index 82aa92a106f844578959158ce1518eb7d0766951..6568b4541a81d52cc81729eb8590cf37 // 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)); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 7d98ba26ccde1e57378253e03c437650051f7843..42e6754ae5432a41f54064961bd5d66891a30612 100644 +index c9673051ce9f4096b981087eefe8b72bbe34819a..07b9f53d49d9ba8bbd3fa3da99bb7cd05510a00c 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -970,10 +970,10 @@ public abstract class PlayerList { +@@ -969,10 +969,10 @@ public abstract class PlayerList { ServerLevel worldserver2 = entityplayer1.serverLevel(); LevelData worlddata = worldserver2.getLevelData(); @@ -36,10 +36,10 @@ index 7d98ba26ccde1e57378253e03c437650051f7843..42e6754ae5432a41f54064961bd5d668 entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel)); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 635f10ca1954b10eaf8e354dd4e1cbf010d7a659..8b5c1d41f54084299ef1c25f7dd8bc6b3f234db5 100644 +index fd57b7f69f3a8ee490cd4fa55c0e5480e0a4a14b..bdc69aed63d1d84a398c25ccf3dabc7ae123fad8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1268,6 +1268,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1338,6 +1338,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end } diff --git a/patches/server/0027-Parchment-Make-FixLight-use-action-bar.patch b/patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch similarity index 68% rename from patches/server/0027-Parchment-Make-FixLight-use-action-bar.patch rename to patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch index 570a4fef..c2271356 100644 --- a/patches/server/0027-Parchment-Make-FixLight-use-action-bar.patch +++ b/patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch @@ -7,31 +7,24 @@ Original license: GPLv3 Original project: https://github.com/ProjectEdenGG/Parchment diff --git a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -index 463c6d8d5b114816ed9065558285945817c30385..d77fb29ea767fce5b8e00b76625188f19ecdbd24 100644 +index 56524cbe4303901007e1e7fb3703a19efbf79ae7..e461c736e9f386fd7b6c96757f827bec361b78d8 100644 --- a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java +++ b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -@@ -24,6 +24,7 @@ import static net.kyori.adventure.text.format.NamedTextColor.BLUE; - import static net.kyori.adventure.text.format.NamedTextColor.DARK_AQUA; - import static net.kyori.adventure.text.format.NamedTextColor.GREEN; - import static net.kyori.adventure.text.format.NamedTextColor.RED; -+import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; - - @DefaultQualifier(NonNull.class) - public final class FixLightCommand implements PaperSubcommand { -@@ -93,17 +94,20 @@ public final class FixLightCommand implements PaperSubcommand { +@@ -87,18 +87,21 @@ public final class FixLightCommand implements PaperSubcommand { lightengine.relight(chunks, (final ChunkPos chunkPos) -> { ++relitChunks[0]; - sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( - text("Relit chunk ", BLUE), text(chunkPos.toString()), - text(", progress: ", BLUE), text((int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%") +- )); + sender.getBukkitEntity().sendActionBar(text().color(DARK_AQUA).append( + text("Relighting Chunks: ", DARK_AQUA), text(chunkPos.toString()), -+ text(" " + relitChunks[0], YELLOW), ++ text(" " + relitChunks[0], net.kyori.adventure.text.format.NamedTextColor.YELLOW), + text("/", DARK_AQUA), -+ text(pending[0] + " ", YELLOW), -+ text("(" + (int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%)", YELLOW) - )); ++ text(pending[0] + " ", net.kyori.adventure.text.format.NamedTextColor.YELLOW), ++ text("(" + (int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%)", net.kyori.adventure.text.format.NamedTextColor.YELLOW) ++ )); // Leaf - Parchment - Make FixLight use action bar }, (final int totalRelit) -> { final long end = System.nanoTime(); @@ -39,8 +32,10 @@ index 463c6d8d5b114816ed9065558285945817c30385..d77fb29ea767fce5b8e00b76625188f1 sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( - text("Relit ", BLUE), text(totalRelit), - text(" chunks. Took ", BLUE), text(diff + "ms") -+ text("Relit ", DARK_AQUA), text(totalRelit, YELLOW), -+ text(" chunks. Took ", DARK_AQUA), text(diff + "ms", YELLOW) - )); +- )); ++ text("Relit ", DARK_AQUA), text(totalRelit, net.kyori.adventure.text.format.NamedTextColor.YELLOW), ++ text(" chunks. Took ", DARK_AQUA), text(diff + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW) ++ )); // Leaf - Parchment - Make FixLight use action bar if (done != null) { done.run(); + } diff --git a/patches/server/0028-Leaves-Server-Utils.patch b/patches/server/0029-Leaves-Server-Utils.patch similarity index 60% rename from patches/server/0028-Leaves-Server-Utils.patch rename to patches/server/0029-Leaves-Server-Utils.patch index e616490d..5bad5508 100644 --- a/patches/server/0028-Leaves-Server-Utils.patch +++ b/patches/server/0029-Leaves-Server-Utils.patch @@ -7,29 +7,29 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6b7025b4cacdc2b14662d09f8da78bce04392d17..1952c66202f51bdbca52fab03710ca0d76e0312d 100644 +index 7c347b26e9d65acbdc901a7197eee1a1cbb0be40..8b314a1ad2bf833cee950471d63e5538192bb1ab 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -425,6 +425,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - private UUID originWorld; - public boolean freezeLocked = false; // Paper - Freeze Tick Lock API - public boolean fixedPose = false; // Paper - Expand Pose API +@@ -431,6 +431,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public boolean activatedPriorityReset = false; // Pufferfish - DAB + public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) + public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API + private CompoundTag leavesData = new CompoundTag(); // Leaves - Leaves ex data public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -2548,6 +2549,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - nbttagcompound.putBoolean("Paper.FreezeLock", true); +@@ -2627,6 +2628,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + nbttagcompound.putBoolean("Purpur.FireImmune", immuneToFire); } - // Paper end + // Purpur end + nbttagcompound.put("Leaves.Data", leavesData); // Leaves - leaves ex data return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2695,6 +2697,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - freezeLocked = nbt.getBoolean("Paper.FreezeLock"); +@@ -2779,6 +2781,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + immuneToFire = nbt.getBoolean("Purpur.FireImmune"); } - // Paper end + // Purpur end + // Leaves start - leaves ex data + if (nbt.contains("Leaves.Data")) { + leavesData = nbt.getCompound("Leaves.Data"); @@ -38,7 +38,7 @@ index 6b7025b4cacdc2b14662d09f8da78bce04392d17..1952c66202f51bdbca52fab03710ca0d } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -5134,4 +5141,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -5217,4 +5224,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // Purpur end diff --git a/patches/server/0034-Leaves-Disable-moved-wrongly-threshold.patch b/patches/server/0030-Leaves-Disable-moved-wrongly-threshold.patch similarity index 94% rename from patches/server/0034-Leaves-Disable-moved-wrongly-threshold.patch rename to patches/server/0030-Leaves-Disable-moved-wrongly-threshold.patch index 9b0298ed..0240094a 100644 --- a/patches/server/0034-Leaves-Disable-moved-wrongly-threshold.patch +++ b/patches/server/0030-Leaves-Disable-moved-wrongly-threshold.patch @@ -7,10 +7,10 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 451095afa88a2d89d33658042e9a62ef14547cc7..8d4fbf7dd77ef5233936aa5c2bce2e63ecbdebab 100644 +index f0886b4b63adb17ffe73b60f6ff6bdb734a4e8cf..b877dc3f82bdd9640f522e7bd2dc1dbf23610eb1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -579,7 +579,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -589,7 +589,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Prevent moving into unloaded chunks @@ -19,7 +19,7 @@ index 451095afa88a2d89d33658042e9a62ef14547cc7..8d4fbf7dd77ef5233936aa5c2bce2e63 // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -615,7 +615,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -625,7 +625,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -28,7 +28,7 @@ index 451095afa88a2d89d33658042e9a62ef14547cc7..8d4fbf7dd77ef5233936aa5c2bce2e63 flag2 = true; // Paper - diff on change, this should be moved wrongly ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", new Object[]{entity.getName().getString(), this.player.getName().getString(), Math.sqrt(d10)}); } -@@ -1498,7 +1498,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1462,7 +1462,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, toX, toY, toZ, toYaw, toPitch, true); if (!event.isAllowed()) { @@ -37,7 +37,7 @@ index 451095afa88a2d89d33658042e9a62ef14547cc7..8d4fbf7dd77ef5233936aa5c2bce2e63 ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); return; -@@ -1568,7 +1568,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1532,7 +1532,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean movedWrongly = false; // Paper - Add fail move event; rename diff --git a/patches/server/0035-Leaves-Fix-vehicle-teleport-by-end-gateway.patch b/patches/server/0031-Leaves-Fix-vehicle-teleport-by-end-gateway.patch similarity index 94% rename from patches/server/0035-Leaves-Fix-vehicle-teleport-by-end-gateway.patch rename to patches/server/0031-Leaves-Fix-vehicle-teleport-by-end-gateway.patch index 05b02dd8..e6b0c926 100644 --- a/patches/server/0035-Leaves-Fix-vehicle-teleport-by-end-gateway.patch +++ b/patches/server/0031-Leaves-Fix-vehicle-teleport-by-end-gateway.patch @@ -7,10 +7,10 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves 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 5717b1c2fd5b16d439499296edd35d72b6613212..2cc37cf1c3e8f7c8fdd6c1b9cfad02283f8f1dec 100644 +index 0e58011d22536051a18388c2d45fd1a30c2f5ffd..2910af920a746f90529f94038922e2a9e6ad3bc1 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 -@@ -229,7 +229,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { +@@ -223,7 +223,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { entity1.setPortalCooldown(); ((ServerPlayer) entity1).connection.teleport(teleEvent.getTo()); diff --git a/patches/server/0039-Petal-Async-Pathfinding.patch b/patches/server/0032-Petal-Async-Pathfinding.patch similarity index 80% rename from patches/server/0039-Petal-Async-Pathfinding.patch rename to patches/server/0032-Petal-Async-Pathfinding.patch index c7b9ec21..18c6bbda 100644 --- a/patches/server/0039-Petal-Async-Pathfinding.patch +++ b/patches/server/0032-Petal-Async-Pathfinding.patch @@ -15,10 +15,10 @@ This patch was ported downstream from the Petal fork. Makes most pathfinding-related work happen asynchronously diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index ab442ad33124c75c261752d14d0ee209a673209e..4954cdcb642670d876dceb7b7bb3651c5d7a2c9e 100644 +index 3a153b7f1092c2d4ac6e0115f611d60907619a40..8ba2d0884114abd7dd3ff8d6e8a9a86e171bc2c0 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -295,6 +295,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -303,6 +303,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti @Nullable @Override public LivingEntity getTarget() { @@ -27,27 +27,11 @@ index ab442ad33124c75c261752d14d0ee209a673209e..4954cdcb642670d876dceb7b7bb3651c } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index 4d2b6e69ed98aca98ffc50fefc6e535c1afb759d..74cd04a4e197e7d3dcf8986e77ed9a96acce01e4 100644 +index c72ce539f3e339c6e87138e744f033d2143abc7a..4e1ac973102dc2ba8329fb6657f328228b241661 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -@@ -7,7 +7,6 @@ import java.util.HashSet; - import java.util.Optional; - import java.util.Set; - import java.util.function.Predicate; --import java.util.stream.Collectors; - import javax.annotation.Nullable; - import net.minecraft.core.BlockPos; - import net.minecraft.core.GlobalPos; -@@ -23,6 +22,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiManager; - import net.minecraft.world.entity.ai.village.poi.PoiType; - import net.minecraft.world.level.pathfinder.Path; - import org.apache.commons.lang3.mutable.MutableLong; -+import org.dreeam.leaf.async.path.AsyncPathProcessor; - - public class AcquirePoi { - public static final int SCAN_RANGE = 48; @@ -85,6 +85,38 @@ public class AcquirePoi { - io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur + io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur Set, BlockPos>> set = new java.util.HashSet<>(poiposes); // Paper end - optimise POI access + // Kaiiju start - petal - Async path processing @@ -56,26 +40,26 @@ index 4d2b6e69ed98aca98ffc50fefc6e535c1afb759d..74cd04a4e197e7d3dcf8986e77ed9a96 + Path possiblePath = findPathToPois(entity, set); + + // wait on the path to be processed -+ AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { ++ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + // read canReach check + if (path == null || !path.canReach()) { + for (Pair, BlockPos> pair : set) { + long2ObjectMap.computeIfAbsent( + pair.getSecond().asLong(), -+ (m) -> new JitteredLinearRetry(entity.level().random, time) ++ m -> new JitteredLinearRetry(entity.level().random, time) + ); + } + return; + } + BlockPos blockPos = path.getTarget(); -+ poiManager.getType(blockPos).ifPresent((poiType) -> { ++ poiManager.getType(blockPos).ifPresent(poiType -> { + poiManager.take(poiPredicate, + (holder, blockPos2) -> blockPos2.equals(blockPos), + blockPos, + 1 + ); + queryResult.set(GlobalPos.of(world.dimension(), blockPos)); -+ entityStatus.ifPresent((status) -> world.broadcastEntityEvent(entity, status)); ++ entityStatus.ifPresent(status -> world.broadcastEntityEvent(entity, status)); + long2ObjectMap.clear(); + DebugPackets.sendPoiTicketCountPacket(world, blockPos); + }); @@ -219,18 +203,10 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..4010cb7ad8897995c8b850f9279aad2a private boolean tryComputePath(Mob entity, WalkTarget walkTarget, long time) { BlockPos blockPos = walkTarget.getTarget().currentBlockPosition(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java -index 6802e0c4d331c7125114dd86409f6a110465ab82..fb936e7c05f56b7c430b9b725c651fa85ea42c20 100644 +index 6802e0c4d331c7125114dd86409f6a110465ab82..84a36ef3e98af24a24a25b83826f44bb7f746bcc 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java -@@ -20,6 +20,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiTypes; - import net.minecraft.world.level.pathfinder.Path; - import org.apache.commons.lang3.mutable.MutableInt; - import org.apache.commons.lang3.mutable.MutableLong; -+import org.dreeam.leaf.async.path.AsyncPathProcessor; - - public class SetClosestHomeAsWalkTarget { - private static final int CACHE_TIMEOUT = 40; -@@ -60,6 +61,26 @@ public class SetClosestHomeAsWalkTarget { +@@ -60,6 +60,26 @@ public class SetClosestHomeAsWalkTarget { poiType -> poiType.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY ) .collect(Collectors.toSet()); @@ -240,9 +216,9 @@ index 6802e0c4d331c7125114dd86409f6a110465ab82..fb936e7c05f56b7c430b9b725c651fa8 + Path possiblePath = AcquirePoi.findPathToPois(entity, set); + + // wait on the path to be processed -+ AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { ++ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + if (path == null || !path.canReach() || mutableInt.getValue() < 5) { // read canReach check -+ long2LongMap.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < mutableLong.getValue()); ++ long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue()); + return; + } + BlockPos blockPos = path.getTarget(); @@ -257,7 +233,7 @@ index 6802e0c4d331c7125114dd86409f6a110465ab82..fb936e7c05f56b7c430b9b725c651fa8 Path path = AcquirePoi.findPathToPois(entity, set); if (path != null && path.canReach()) { BlockPos blockPos = path.getTarget(); -@@ -71,6 +92,7 @@ public class SetClosestHomeAsWalkTarget { +@@ -71,6 +91,7 @@ public class SetClosestHomeAsWalkTarget { } else if (mutableInt.getValue() < 5) { long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue()); } @@ -279,23 +255,15 @@ index 74aca307b4ebffe4e33c4fca3e07c23ca87622ac..37e61aa259f573cc5b5844026af99f3c Node node = path.getNode(i); this.doorPos = new BlockPos(node.x, node.y + 1, node.z); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java -index ee38e447a810094d2253b85714b74282a4b4c2bc..abcb8a48cf162dd7bf553097ca045b919e7c408a 100644 +index ee38e447a810094d2253b85714b74282a4b4c2bc..e4699174bd7dbd2e24d5d11c385fb40d4aeb79c6 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java -@@ -6,16 +6,34 @@ import net.minecraft.world.level.Level; - import net.minecraft.world.level.pathfinder.AmphibiousNodeEvaluator; - import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.phys.Vec3; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class AmphibiousPathNavigation extends PathNavigation { - public AmphibiousPathNavigation(Mob mob, Level world) { +@@ -12,10 +12,26 @@ public class AmphibiousPathNavigation extends PathNavigation { super(mob, world); } + // Kaiiju start - petal - async path processing -+ private static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + AmphibiousNodeEvaluator nodeEvaluator = new AmphibiousNodeEvaluator(false); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -310,31 +278,23 @@ index ee38e447a810094d2253b85714b74282a4b4c2bc..abcb8a48cf162dd7bf553097ca045b91 this.nodeEvaluator = new AmphibiousNodeEvaluator(false); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java -index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..44ef3262c91c25c956500e1e460e383c6fb60b62 100644 +index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..231664c516ded9bb4619d8afb41e5cb2806209be 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java -@@ -10,16 +10,34 @@ import net.minecraft.world.level.pathfinder.FlyNodeEvaluator; - import net.minecraft.world.level.pathfinder.Path; - import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.phys.Vec3; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class FlyingPathNavigation extends PathNavigation { - public FlyingPathNavigation(Mob entity, Level world) { +@@ -16,10 +16,26 @@ public class FlyingPathNavigation extends PathNavigation { super(entity, world); } + // Kaiiju start - petal - async path processing -+ private static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + FlyNodeEvaluator nodeEvaluator = new FlyNodeEvaluator(); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -349,14 +309,14 @@ index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..44ef3262c91c25c956500e1e460e383c this.nodeEvaluator = new FlyNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } -@@ -49,6 +67,7 @@ public class FlyingPathNavigation extends PathNavigation { +@@ -49,6 +65,7 @@ public class FlyingPathNavigation extends PathNavigation { if (this.hasDelayedRecomputation) { this.recomputePath(); } @@ -365,24 +325,15 @@ index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..44ef3262c91c25c956500e1e460e383c if (!this.isDone()) { if (this.canUpdatePath()) { diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -index 74ae984ac41bcdd2cc45f1bec461cdc5f69977c6..2cf7e2d42a830c1b1cfd3bafd7b22803572e12bd 100644 +index 62634bedd97c5be9ecce24ab0cff205715a68da8..5266cee05a00fefba98a10eb91bb477f189e1ad1 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -@@ -15,6 +15,8 @@ import net.minecraft.world.level.pathfinder.Path; - import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; - import net.minecraft.world.phys.Vec3; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class GroundPathNavigation extends PathNavigation { - private boolean avoidSun; -@@ -23,10 +25,26 @@ public class GroundPathNavigation extends PathNavigation { +@@ -23,10 +23,26 @@ public class GroundPathNavigation extends PathNavigation { super(entity, world); } + // Kaiiju start - petal - async path processing -+ protected static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ protected static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator(); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -397,38 +348,29 @@ index 74ae984ac41bcdd2cc45f1bec461cdc5f69977c6..2cf7e2d42a830c1b1cfd3bafd7b22803 this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653bdb12f177 100644 +index aea01c46bf59ed811356180436fc0789e354d981..8ba2c3855b69ad9ca717675e70df1055cb4a677a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -25,6 +25,8 @@ import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; - import net.minecraft.world.phys.HitResult; - import net.minecraft.world.phys.Vec3; -+import org.dreeam.leaf.async.path.AsyncPath; -+import org.dreeam.leaf.async.path.AsyncPathProcessor; - - public abstract class PathNavigation { - private static final int MAX_TIME_RECOMPUTE = 20; -@@ -152,6 +154,10 @@ public abstract class PathNavigation { +@@ -152,6 +152,10 @@ public abstract class PathNavigation { return null; } else if (!this.canUpdatePath()) { return null; + // Kaiiju start - petal - catch early if it's still processing these positions let it keep processing -+ } else if (this.path instanceof AsyncPath asyncPath && !asyncPath.isProcessed() && asyncPath.hasSameProcessingPositions(positions)) { ++ } else if (this.path instanceof org.dreeam.leaf.async.path.AsyncPath asyncPath && !asyncPath.isProcessed() && asyncPath.hasSameProcessingPositions(positions)) { + return this.path; + // Kaiiju end } else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) { return this.path; } else { -@@ -176,11 +182,29 @@ public abstract class PathNavigation { +@@ -176,11 +180,29 @@ public abstract class PathNavigation { int i = (int)(followRange + (float)range); PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i)); Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, positions, followRange, distance, this.maxVisitedNodesMultiplier); @@ -437,7 +379,7 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b + // assign early a target position. most calls will only have 1 position + if (!positions.isEmpty()) this.targetPos = positions.iterator().next(); + -+ AsyncPathProcessor.awaitProcessing(mob, path, processedPath -> { ++ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(mob, path, processedPath -> { + // check that processing didn't take so long that we calculated a new path + if (processedPath != this.path) return; + @@ -458,7 +400,7 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b return path; } -@@ -227,8 +251,8 @@ public abstract class PathNavigation { +@@ -231,8 +253,8 @@ public abstract class PathNavigation { if (this.isDone()) { return false; } else { @@ -469,7 +411,7 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b return false; } else { this.speedModifier = speed; -@@ -251,6 +275,7 @@ public abstract class PathNavigation { +@@ -255,6 +277,7 @@ public abstract class PathNavigation { if (this.hasDelayedRecomputation) { this.recomputePath(); } @@ -477,7 +419,7 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b if (!this.isDone()) { if (this.canUpdatePath()) { -@@ -277,6 +302,7 @@ public abstract class PathNavigation { +@@ -281,6 +304,7 @@ public abstract class PathNavigation { } protected void followThePath() { @@ -485,7 +427,7 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b Vec3 vec3 = this.getTempMobPos(); this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F; Vec3i vec3i = this.path.getNextNodePos(); -@@ -433,7 +459,7 @@ public abstract class PathNavigation { +@@ -437,7 +461,7 @@ public abstract class PathNavigation { public boolean shouldRecomputePath(BlockPos pos) { if (this.hasDelayedRecomputation) { return false; @@ -495,24 +437,15 @@ index cf57d0f4636ec3f93992626f06fe9c10c7cac19a..54d4260636409bcb06aaf850d7de653b Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0, ((double)node.y + this.mob.getY()) / 2.0, ((double)node.z + this.mob.getZ()) / 2.0); return pos.closerToCenterThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex())); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java -index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..0ccd291a2ed58d7a065f753a0211375203f87d18 100644 +index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..dbf43209417d8453ff39839392eba45b2bc625c1 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java -@@ -7,6 +7,8 @@ import net.minecraft.world.level.Level; - import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.level.pathfinder.SwimNodeEvaluator; - import net.minecraft.world.phys.Vec3; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class WaterBoundPathNavigation extends PathNavigation { - private boolean allowBreaching; -@@ -15,10 +17,26 @@ public class WaterBoundPathNavigation extends PathNavigation { +@@ -15,10 +15,26 @@ public class WaterBoundPathNavigation extends PathNavigation { super(entity, world); } + // Kaiiju start - petal - async path processing -+ private static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + SwimNodeEvaluator nodeEvaluator = new SwimNodeEvaluator(nodeEvaluatorFeatures.allowBreaching()); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -527,45 +460,28 @@ index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..0ccd291a2ed58d7a065f753a02113752 this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN; this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching); + // Kaiiju start - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -index 9104d7010bda6f9f73b478c11490ef9c53f76da2..c7b6f77f368518b62326f6b25979d1bd180feae0 100644 +index 9104d7010bda6f9f73b478c11490ef9c53f76da2..7c56e627cba4e6be6bb72f34cb283621febf6695 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -@@ -7,7 +7,7 @@ import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; - import java.util.Optional; - import java.util.Set; - import java.util.function.Predicate; --import java.util.stream.Collectors; -+ - import net.minecraft.core.BlockPos; - import net.minecraft.core.Holder; - import net.minecraft.server.level.ServerLevel; -@@ -18,6 +18,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiManager; - import net.minecraft.world.entity.ai.village.poi.PoiType; - import net.minecraft.world.entity.ai.village.poi.PoiTypes; - import net.minecraft.world.level.pathfinder.Path; -+import org.dreeam.leaf.async.path.AsyncPathProcessor; - - public class NearestBedSensor extends Sensor { - private static final int CACHE_TIMEOUT = 40; -@@ -57,6 +58,25 @@ public class NearestBedSensor extends Sensor { +@@ -57,6 +57,25 @@ public class NearestBedSensor extends Sensor { java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); // don't ask me why it's unbounded. ask mojang. io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), world.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur + // Kaiiju start - await on async path processing + if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); -+ AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { ++ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + // read canReach check + if ((path == null || !path.canReach()) && this.triedCount < 5) { -+ this.batchCache.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.lastUpdate); ++ this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate); + return; + } + if (path == null) return; @@ -581,7 +497,7 @@ index 9104d7010bda6f9f73b478c11490ef9c53f76da2..c7b6f77f368518b62326f6b25979d1bd Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); // Paper end - optimise POI access if (path != null && path.canReach()) { -@@ -68,6 +88,7 @@ public class NearestBedSensor extends Sensor { +@@ -68,6 +87,7 @@ public class NearestBedSensor extends Sensor { } else if (this.triedCount < 5) { this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate); } @@ -590,10 +506,10 @@ index 9104d7010bda6f9f73b478c11490ef9c53f76da2..c7b6f77f368518b62326f6b25979d1bd } } 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 997ab942be9f742804041b07d607e7dd6473ba96..9ef7be84999ab0ec39d2b58a48cdaebf42db10c9 100644 +index 539170813921de2dfcd7ef84dd7512d73cd27e68..d47576293144efcbfb3906a77d757ce810641990 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -1154,7 +1154,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1135,7 +1135,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } else { Bee.this.pathfindRandomlyTowards(Bee.this.hivePos); } @@ -602,7 +518,7 @@ index 997ab942be9f742804041b07d607e7dd6473ba96..9ef7be84999ab0ec39d2b58a48cdaebf boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos); if (!flag) { -@@ -1216,7 +1216,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1197,7 +1197,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } else { Path pathentity = Bee.this.navigation.getPath(); @@ -612,32 +528,15 @@ index 997ab942be9f742804041b07d607e7dd6473ba96..9ef7be84999ab0ec39d2b58a48cdaebf } } diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index 44b17f1c6367b729d6e8f7f45c5689a12d6b3034..bde190fd608262fcf9eb272316c4984c918252ed 100644 +index 7c4e7d55874fa968d52eab683e9979ba38e91c2e..da026533b15a1981000e73bba6c5209c13de28dc 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -41,7 +41,6 @@ import net.minecraft.world.entity.VariantHolder; - import net.minecraft.world.entity.ai.Brain; - import net.minecraft.world.entity.ai.attributes.AttributeSupplier; - import net.minecraft.world.entity.ai.attributes.Attributes; --import net.minecraft.world.entity.ai.control.LookControl; - import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; - import net.minecraft.world.entity.ai.memory.MemoryModuleType; - import net.minecraft.world.entity.ai.navigation.AmphibiousPathNavigation; -@@ -66,6 +65,8 @@ import net.minecraft.world.level.pathfinder.Node; - import net.minecraft.world.level.pathfinder.PathFinder; - import net.minecraft.world.phys.Vec3; - import org.joml.Vector3f; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class Frog extends Animal implements VariantHolder { - public static final Ingredient TEMPTATION_ITEM = Ingredient.of(Items.SLIME_BALL); -@@ -467,6 +468,17 @@ public class Frog extends Animal implements VariantHolder { +@@ -465,6 +465,17 @@ public class Frog extends Animal implements VariantHolder> { super(frog, world); } + // Kaiiju start - petal - async path processing -+ private static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + Frog.FrogNodeEvaluator nodeEvaluator = new Frog.FrogNodeEvaluator(true); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -648,33 +547,25 @@ index 44b17f1c6367b729d6e8f7f45c5689a12d6b3034..bde190fd608262fcf9eb272316c4984c + // Kaiiju end + @Override - public boolean canCutCorner(BlockPathTypes nodeType) { - return nodeType != BlockPathTypes.WATER_BORDER && super.canCutCorner(nodeType); -@@ -476,6 +488,11 @@ public class Frog extends Animal implements VariantHolder { + public boolean canCutCorner(PathType nodeType) { + return nodeType != PathType.WATER_BORDER && super.canCutCorner(nodeType); +@@ -474,6 +485,11 @@ public class Frog extends Animal implements VariantHolder> { protected PathFinder createPathFinder(int range) { this.nodeEvaluator = new Frog.FrogNodeEvaluator(true); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } } 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 7600e747d91ae888eb801cfafcb09bffb76c8e62..0939ca7c225790c7a294accd820be3ff8000ac75 100644 +index 15afee3c4f6307557321424560d2340e23cd472b..05ed15bcd5974af13395316b50f4ae78385f2ee4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java -@@ -282,7 +282,6 @@ public class Drowned extends Zombie implements RangedAttackMob { - this.setSwimming(false); - } - } -- - } - - @Override -@@ -293,7 +292,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -296,7 +296,7 @@ public class Drowned extends Zombie implements RangedAttackMob { protected boolean closeToNextPos() { Path pathentity = this.getNavigation().getPath(); @@ -684,24 +575,15 @@ index 7600e747d91ae888eb801cfafcb09bffb76c8e62..0939ca7c225790c7a294accd820be3ff if (blockposition != null) { diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java -index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..42f6f629219771f45597cc8a0802fa1ed44d0344 100644 +index 5ea5bf9c0e11b0e1f9fe50093899c6e35ee6cf4f..df439eb41f04ef5e2018cf5bb1222f64b4414171 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Strider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java -@@ -74,6 +74,8 @@ import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.CollisionContext; - import org.joml.Vector3f; -+import org.dreeam.leaf.async.path.NodeEvaluatorFeatures; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class Strider extends Animal implements ItemSteerable, Saddleable { - -@@ -609,10 +611,26 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { +@@ -609,10 +609,26 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { super(entity, world); } + // Kaiiju start - petal - async path processing -+ private static final NodeEvaluatorGenerator nodeEvaluatorGenerator = (NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { ++ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> { + WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator(); + nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors()); + nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat()); @@ -716,49 +598,51 @@ index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..42f6f629219771f45597cc8a0802fa1e this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); -+ else ++ } + // Kaiiju end return new PathFinder(this.nodeEvaluator, range); } 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 07fa613d75f3659145945245926e9068057e3ed2..df0d0868c11c26b2cadc1a07196a0191e16838a0 100644 +index 664774be9fa4422cc76b0f7e362737426e8e1105..3102be6066b0a8065cc0c80b5c4a5d369dc35b72 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 -@@ -623,6 +623,16 @@ public class Warden extends Monster implements VibrationSystem { +@@ -617,6 +617,16 @@ public class Warden extends Monster implements VibrationSystem { protected PathFinder createPathFinder(int range) { this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + return new PathFinder(this.nodeEvaluator, range, GroundPathNavigation.nodeEvaluatorGenerator) { + @Override + protected float distance(Node a, Node b) { + return a.distanceToXZ(b); + } + }; -+ else ++ } + // Kaiiju end - return new PathFinder(this.nodeEvaluator, range) { + return new PathFinder(this.nodeEvaluator, range) { // CraftBukkit - decompile error @Override protected float distance(Node a, Node b) { 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 62ded304c08678750ae8c56c7de876ac5f39940b..4989b597b451e60da38f6e5ec4f790104775ce3e 100644 +index 68431244432a4342041e63218cf7d1eb4eb7ebc0..b828e2dc11770acfcdc419798f7bd82faaafe5d4 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -243,8 +243,13 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -215,8 +215,15 @@ public class ShulkerBoxBlock extends BaseEntityBlock { @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + //if (Thread.currentThread().getName().contains("petal-async-pathfinding-thread")) return Shapes.block(); // Kaiiju - async pathfinding - we cannot get block entities // Leaf - Don't need this BlockEntity blockEntity = world.getBlockEntity(pos); return blockEntity instanceof ShulkerBoxBlockEntity ? Shapes.create(((ShulkerBoxBlockEntity)blockEntity).getBoundingBox(state)) : Shapes.block(); + // Kaiiju start - async pathfinding - workaround // Leaf - Don't need this -+ //} catch (NullPointerException e) { -+ // return Shapes.block(); -+ //} ++ /* ++ } catch (NullPointerException e) { ++ return Shapes.block(); ++ } ++ */ } @Override @@ -793,42 +677,17 @@ index d9d0fff9962131808d54cca20f209df50b8e4af1..f2dcbb40ed43e6ddf6f3dc27fcff04f7 return false; } else if (o.nodes.size() != this.nodes.size()) { diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java -index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f44852170e 100644 +index f890c27c960b6511b7961f380b23e9ca8f86ba0e..89b74ee7bd2b75c4eaee7c7bca6cbadad2d9165b 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java -@@ -1,20 +1,18 @@ - package net.minecraft.world.level.pathfinder; - --import com.google.common.collect.ImmutableSet; - import com.google.common.collect.Lists; --import com.google.common.collect.Sets; -+ - import java.util.Comparator; - import java.util.List; - import java.util.Map; --import java.util.Optional; - import java.util.Set; --import java.util.function.Function; --import java.util.stream.Collectors; - import javax.annotation.Nullable; - import net.minecraft.core.BlockPos; --import net.minecraft.util.profiling.metrics.MetricCategory; - import net.minecraft.world.entity.Mob; - import net.minecraft.world.level.PathNavigationRegion; -+import org.dreeam.leaf.async.path.AsyncPath; -+import org.dreeam.leaf.async.path.NodeEvaluatorCache; -+import org.dreeam.leaf.async.path.NodeEvaluatorGenerator; - - public class PathFinder { - private static final float FUDGING = 1.5F; -@@ -23,35 +21,80 @@ public class PathFinder { +@@ -23,35 +23,80 @@ public class PathFinder { public final NodeEvaluator nodeEvaluator; private static final boolean DEBUG = false; private final BinaryHeap openSet = new BinaryHeap(); -+ private final @Nullable NodeEvaluatorGenerator nodeEvaluatorGenerator; // Kaiiju - petal - we use this later to generate an evaluator ++ private final @Nullable org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator; // Kaiiju - petal - we use this later to generate an evaluator - public PathFinder(NodeEvaluator pathNodeMaker, int range) { -+ public PathFinder(NodeEvaluator pathNodeMaker, int range, @Nullable NodeEvaluatorGenerator nodeEvaluatorGenerator) { // Kaiiju - petal - add nodeEvaluatorGenerator ++ public PathFinder(NodeEvaluator pathNodeMaker, int range, @Nullable org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator) { // Kaiiju - petal - add nodeEvaluatorGenerator this.nodeEvaluator = pathNodeMaker; this.maxVisitedNodes = range; + // Kaiiju start - petal - support nodeEvaluatorgenerators @@ -850,19 +709,19 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 + // Kaiiju start - petal - use a generated evaluator if we have one otherwise run sync + NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null + ? this.nodeEvaluator -+ : NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator); ++ : org.dreeam.leaf.async.path.NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator); + nodeEvaluator.prepare(world, mob); + Node node = nodeEvaluator.getStart(); + // Kaiiju end if (node == null) { -+ NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // Kaiiju - petal - handle nodeEvaluatorGenerator ++ org.dreeam.leaf.async.path.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // Kaiiju - petal - handle nodeEvaluatorGenerator return null; } else { // Paper start - Perf: remove streams and optimize collection List> map = Lists.newArrayList(); - for (BlockPos pos : positions) { -- map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getGoal(pos.getX(), pos.getY(), pos.getZ()), pos)); -+ map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getGoal(pos.getX(), pos.getY(), pos.getZ()), pos)); // Kaiiju - petal - handle nodeEvaluatorGenerator + for (final BlockPos pos : positions) { +- map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); ++ map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); // Kaiiju - petal - handle nodeEvaluatorGenerator } // Paper end - Perf: remove streams and optimize collection - Path path = this.findPath(node, map, followRange, distance, rangeMultiplier); // Gale - Purpur - remove vanilla profiler @@ -871,11 +730,11 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 + // Kaiiju start - petal - async path processing + if (this.nodeEvaluatorGenerator == null) { + // run sync :( -+ NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); ++ org.dreeam.leaf.async.path.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); + return this.findPath(node, map, followRange, distance, rangeMultiplier); // Gale - Purpur - remove vanilla profiler + } + -+ return new AsyncPath(Lists.newArrayList(), positions, () -> { ++ return new org.dreeam.leaf.async.path.AsyncPath(Lists.newArrayList(), positions, () -> { + try { + return this.processPath(nodeEvaluator, node, map, followRange, distance, rangeMultiplier); + } catch (Exception e) { @@ -883,7 +742,7 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 + return null; + } finally { + nodeEvaluator.done(); -+ NodeEvaluatorCache.returnNodeEvaluator(nodeEvaluator); ++ org.dreeam.leaf.async.path.NodeEvaluatorCache.returnNodeEvaluator(nodeEvaluator); + } + }); + // Kaiiju end @@ -910,7 +769,7 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 // Set set = positions.keySet(); startNode.g = 0.0F; startNode.h = this.getBestH(startNode, positions); // Paper - optimize collection -@@ -87,7 +130,7 @@ public class PathFinder { +@@ -87,7 +132,7 @@ public class PathFinder { } if (!(node.distanceTo(startNode) >= followRange)) { @@ -919,7 +778,7 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 for (int l = 0; l < k; l++) { Node node2 = this.neighbors[l]; -@@ -119,6 +162,7 @@ public class PathFinder { +@@ -119,6 +164,7 @@ public class PathFinder { if (best == null || comparator.compare(path, best) < 0) best = path; } @@ -928,16 +787,16 @@ index ad8b94cd37eb00c50af5b9c51c35b098a9ad67a3..d36cb87bd9d1b2127f404130127864f4 // Paper end - Perf: remove streams and optimize collection } diff --git a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java -index 074e9c7f58adebadc3076bfc4b63adea8b1d521d..3cb00814eb7e248104e9a6bd016b6c342ba83220 100644 +index 6308822f819d7cb84c8070c8a7eec1a3f822114b..e49851557f991ca1fc2f78abfb819609e672a526 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java -@@ -16,7 +16,7 @@ import net.minecraft.world.level.block.state.BlockState; +@@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; public class SwimNodeEvaluator extends NodeEvaluator { - private final boolean allowBreaching; + public final boolean allowBreaching; // Kaiiju - make this public - private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap<>(); + private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap<>(); public SwimNodeEvaluator(boolean canJumpOutOfWater) { diff --git a/src/main/java/org/dreeam/leaf/async/path/AsyncPath.java b/src/main/java/org/dreeam/leaf/async/path/AsyncPath.java @@ -1293,7 +1152,7 @@ index 0000000000000000000000000000000000000000..ccee3723679d3740d34bd13c04018baf +} diff --git a/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorCache.java b/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorCache.java new file mode 100644 -index 0000000000000000000000000000000000000000..6958772ff706531b28ba75fbd4e926ca65a74798 +index 0000000000000000000000000000000000000000..7a28c0ef27efbab28274c007068b5c82073a1987 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorCache.java @@ -0,0 +1,45 @@ @@ -1314,7 +1173,7 @@ index 0000000000000000000000000000000000000000..6958772ff706531b28ba75fbd4e926ca + private static final Map nodeEvaluatorToGenerator = new ConcurrentHashMap<>(); + + private static @NotNull Queue getQueueForFeatures(@NotNull NodeEvaluatorFeatures nodeEvaluatorFeatures) { -+ return threadLocalNodeEvaluators.computeIfAbsent(nodeEvaluatorFeatures, (key) -> new ConcurrentLinkedQueue<>()); ++ return threadLocalNodeEvaluators.computeIfAbsent(nodeEvaluatorFeatures, key -> new ConcurrentLinkedQueue<>()); + } + + public static @NotNull NodeEvaluator takeNodeEvaluator(@NotNull NodeEvaluatorGenerator generator, @NotNull NodeEvaluator localNodeEvaluator) { @@ -1344,21 +1203,23 @@ index 0000000000000000000000000000000000000000..6958772ff706531b28ba75fbd4e926ca +} diff --git a/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorFeatures.java b/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorFeatures.java new file mode 100644 -index 0000000000000000000000000000000000000000..9a9e69bc4bd807d62af0cebc05b3186d62202099 +index 0000000000000000000000000000000000000000..2c4876bc001463eea818e429e652f164eca0187c --- /dev/null +++ b/src/main/java/org/dreeam/leaf/async/path/NodeEvaluatorFeatures.java -@@ -0,0 +1,21 @@ +@@ -0,0 +1,23 @@ +package org.dreeam.leaf.async.path; + +import net.minecraft.world.level.pathfinder.NodeEvaluator; +import net.minecraft.world.level.pathfinder.SwimNodeEvaluator; + -+public record NodeEvaluatorFeatures(NodeEvaluatorType type, -+ boolean canPassDoors, -+ boolean canFloat, -+ boolean canWalkOverFences, -+ boolean canOpenDoors, -+ boolean allowBreaching) { ++public record NodeEvaluatorFeatures( ++ NodeEvaluatorType type, ++ boolean canPassDoors, ++ boolean canFloat, ++ boolean canWalkOverFences, ++ boolean canOpenDoors, ++ boolean allowBreaching ++) { + public static NodeEvaluatorFeatures fromNodeEvaluator(NodeEvaluator nodeEvaluator) { + NodeEvaluatorType type = NodeEvaluatorType.fromNodeEvaluator(nodeEvaluator); + boolean canPassDoors = nodeEvaluator.canPassDoors(); diff --git a/patches/server/0040-Petal-Multithreaded-Tracker.patch b/patches/server/0033-Petal-Multithreaded-Tracker.patch similarity index 92% rename from patches/server/0040-Petal-Multithreaded-Tracker.patch rename to patches/server/0033-Petal-Multithreaded-Tracker.patch index 7a636021..9405c1cd 100644 --- a/patches/server/0040-Petal-Multithreaded-Tracker.patch +++ b/patches/server/0033-Petal-Multithreaded-Tracker.patch @@ -25,33 +25,22 @@ Some things are too unsafe to run off the main thread so we don't attempt to do that. This multithreaded tracker remains accurate, non-breaking and fast. diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..cc38235d2b5f3fc5113a4d495f14f81cd24d7cb9 100644 +index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..9be6ddce778f47ce2c8371757ab8d30978b96888 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -3,6 +3,7 @@ package io.papermc.paper.plugin.manager; - import com.destroystokyo.paper.event.server.ServerExceptionEvent; - import com.destroystokyo.paper.exception.ServerEventException; - import com.google.common.collect.Sets; -+import net.minecraft.server.MinecraftServer; - import org.bukkit.Server; - import org.bukkit.Warning; - import org.bukkit.event.Event; -@@ -42,7 +43,14 @@ class PaperEventManager { +@@ -42,6 +42,12 @@ class PaperEventManager { if (isAsync && onPrimaryThread) { throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); } else if (!isAsync && !onPrimaryThread && !this.server.isStopping()) { -- throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); + // Leaf start - petal + if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) { -+ MinecraftServer.getServer().scheduleOnMain(event::callEvent); ++ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent); + return; -+ } else { -+ throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); + } + // Leaf end - petal + throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); } // KTP stop - Optimise spigot event bus - } diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java index 0fd814f1d65c111266a2b20f86561839a4cef755..3fbf6eeb3e835269217a381f00b54a7ec43d5bd2 100644 --- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java @@ -79,10 +68,10 @@ index d8b22d51d28692182cd75affd6cb552971fed42f..63aa94b0004aa2ea5de5dce775453704 public FullChunkStatus status; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c7379898ff2339 100644 +index c700bb52cd7cfc264c0353d3b832547f7e336e32..da9b182bb8d7d4457a66ecbc2adb289956780693 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1128,8 +1128,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1144,8 +1144,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider entity.tracker = null; // Paper - We're no longer tracked } @@ -118,7 +107,7 @@ index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c73798 for (TrackedEntity tracker : this.entityMap.values()) { // update tracker entry tracker.updatePlayers(tracker.entity.getPlayersInTrackRange()); -@@ -1281,10 +1308,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1295,10 +1322,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public class TrackedEntity { public final ServerEntity serverEntity; @@ -129,9 +118,9 @@ index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c73798 - public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl + public final Set seenBy = Sets.newConcurrentHashSet(); // Paper - Perf: optimise map impl // Leaf - Fix tracker NPE - public TrackedEntity(Entity entity, int i, int j, boolean flag) { + public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit -@@ -1296,7 +1323,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1310,7 +1337,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - use distance map to optimise tracker com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet lastTrackerCandidates; @@ -140,7 +129,7 @@ index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c73798 com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet oldTrackerCandidates = this.lastTrackerCandidates; this.lastTrackerCandidates = newTrackerCandidates; -@@ -1338,14 +1365,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1352,14 +1379,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void broadcast(Packet packet) { @@ -158,7 +147,7 @@ index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c73798 } public void broadcastAndSend(Packet packet) { -@@ -1357,18 +1381,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1371,18 +1395,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void broadcastRemoved() { @@ -181,7 +170,7 @@ index 546028b42544bd62578e415faa245559a373a289..29ea09f27f4b0a7f1ab6075e68c73798 if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); } -@@ -1376,7 +1397,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1390,7 +1411,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void updatePlayer(ServerPlayer player) { @@ -204,10 +193,10 @@ index 4f91107f9ae42f96c060c310596db9aa869a8dbc..faad96f04af2e368f0276ade417dd1ba public boolean visible = true; diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 515e3f444e317de1d82421ad414c1ac10d4668ab..60e8bfc89cfb92e2f7d4860b11c16b3bc5e2f095 100644 +index fadacb64803eb0cc6583f94b1abcc5ce24adb106..504711d92cd50f9aa2026cb2311540a5a7825790 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -280,7 +280,11 @@ public class ServerEntity { +@@ -287,7 +287,11 @@ public class ServerEntity { public void removePairing(ServerPlayer player) { this.entity.stopSeenByPlayer(player); @@ -220,7 +209,7 @@ index 515e3f444e317de1d82421ad414c1ac10d4668ab..60e8bfc89cfb92e2f7d4860b11c16b3b } public void addPairing(ServerPlayer player) { -@@ -288,7 +292,7 @@ public class ServerEntity { +@@ -295,7 +299,7 @@ public class ServerEntity { Objects.requireNonNull(list); this.sendPairingData(player, list::add); @@ -229,7 +218,7 @@ index 515e3f444e317de1d82421ad414c1ac10d4668ab..60e8bfc89cfb92e2f7d4860b11c16b3b this.entity.startSeenByPlayer(player); } -@@ -382,19 +386,29 @@ public class ServerEntity { +@@ -384,19 +388,29 @@ public class ServerEntity { if (list != null) { this.trackedDataValues = datawatcher.getNonDefaultValues(); @@ -263,10 +252,10 @@ index 515e3f444e317de1d82421ad414c1ac10d4668ab..60e8bfc89cfb92e2f7d4860b11c16b3b set.clear(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a04ea23c295b493984eb841253fcb0eb4ad26342..667e2f0ce65c457fc656983e305be7e5d91718f1 100644 +index 2d649d98985203005f3e423d61e88a8ec7dbc380..aa831bc5ffa44c55da9eea33c72df1d6d68c861a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2644,7 +2644,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2591,7 +2591,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public LevelEntityGetter getEntities() { @@ -277,7 +266,7 @@ index a04ea23c295b493984eb841253fcb0eb4ad26342..667e2f0ce65c457fc656983e305be7e5 diff --git a/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java b/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java new file mode 100644 -index 0000000000000000000000000000000000000000..83bd78db3affa7bd7ac646f6b56ec2563051fdc3 +index 0000000000000000000000000000000000000000..13ae86d295f22ce0c373ae1246fc7cad8ff7662d --- /dev/null +++ b/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java @@ -0,0 +1,156 @@ @@ -389,7 +378,7 @@ index 0000000000000000000000000000000000000000..83bd78db3affa7bd7ac646f6b56ec256 + + private void runUpdatePlayers() { + try { -+ while (handleChunkUpdates(10)); ++ while (handleChunkUpdates(10)) ; + } finally { + this.finishedTasks.incrementAndGet(); + } diff --git a/patches/server/0041-Petal-reduce-work-done-by-game-event-system.patch b/patches/server/0034-Petal-reduce-work-done-by-game-event-system.patch similarity index 85% rename from patches/server/0041-Petal-reduce-work-done-by-game-event-system.patch rename to patches/server/0034-Petal-reduce-work-done-by-game-event-system.patch index c6e84657..5a176971 100644 --- a/patches/server/0041-Petal-reduce-work-done-by-game-event-system.patch +++ b/patches/server/0034-Petal-reduce-work-done-by-game-event-system.patch @@ -11,10 +11,10 @@ Original project: https://github.com/Bloom-host/Petal 2. EuclideanGameEventListenerRegistry is not used concurrently so we ban that usage for improved performance with allays diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -index 83481539e058e5f428d9951e409fed62ef159e5c..ef2b60aa7686c92d27ce146ef320e05eea127c87 100644 +index 81dd0aa6a90fd9dda9e7752f85b9cf4568e3b575..7d04ff88e6352147e0c00266bd5d251f8efe3a54 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -@@ -65,7 +65,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi +@@ -67,7 +67,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi return this.catalystListener; } @@ -23,14 +23,14 @@ index 83481539e058e5f428d9951e409fed62ef159e5c..ef2b60aa7686c92d27ce146ef320e05e public static final int PULSE_TICKS = 8; final SculkSpreader sculkSpreader; -@@ -135,6 +135,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi +@@ -137,6 +137,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi world.playSound((Player) null, pos, SoundEvents.SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F); } + // Leaf start - petal + @Override + public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) { -+ return !SculkCatalystBlockEntity.this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE && context.sourceEntity() instanceof LivingEntity; ++ return !SculkCatalystBlockEntity.this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE.value() && context.sourceEntity() instanceof LivingEntity; + } + // Leaf end - petal + @@ -38,10 +38,10 @@ index 83481539e058e5f428d9951e409fed62ef159e5c..ef2b60aa7686c92d27ce146ef320e05e LivingEntity entityliving1 = deadEntity.getLastHurtByMob(); 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 f52b314dd0ed83682b6a60c66b21eefd2cefb793..3a13de668a90d50b18214a91fd92d8b287bd76da 100644 +index 1a2ef85cd8a62824b23f4212a5e2a70ce89e344f..8c36a75dbd60b61337ba5c1b061f8c6c2648c4ca 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -80,7 +80,18 @@ public class LevelChunk extends ChunkAccess { +@@ -82,7 +82,18 @@ public class LevelChunk extends ChunkAccess { private Supplier fullStatus; @Nullable private LevelChunk.PostLoadProcessor postLoad; @@ -61,7 +61,7 @@ index f52b314dd0ed83682b6a60c66b21eefd2cefb793..3a13de668a90d50b18214a91fd92d8b2 private final LevelChunkTicks blockTicks; private final LevelChunkTicks fluidTicks; public volatile FullChunkStatus chunkStatus = FullChunkStatus.INACCESSIBLE; // Paper - rewrite chunk system -@@ -105,7 +116,7 @@ public class LevelChunk extends ChunkAccess { +@@ -107,7 +118,7 @@ public class LevelChunk extends ChunkAccess { super(pos, upgradeData, world, net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry this.tickersInLevel = Maps.newHashMap(); this.level = (ServerLevel) world; // CraftBukkit - type @@ -71,9 +71,9 @@ index f52b314dd0ed83682b6a60c66b21eefd2cefb793..3a13de668a90d50b18214a91fd92d8b2 int j = aheightmap_type.length; @@ -303,9 +314,23 @@ public class LevelChunk extends ChunkAccess { - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; + Level world = this.level; + if (world instanceof ServerLevel worldserver) { - return (GameEventListenerRegistry) this.gameEventListenerRegistrySections.computeIfAbsent(ySectionCoord, (j) -> { - return new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry); - }); @@ -107,10 +107,10 @@ index f52b314dd0ed83682b6a60c66b21eefd2cefb793..3a13de668a90d50b18214a91fd92d8b2 private void removeBlockEntityTicker(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java -index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c17ed7791 100644 +index 1e93f3a1b11196a431a1f5a0957036fe0c9191a4..f1f0dbb20d4ee2f3f47e202f2cb3dd4bde9ac0b3 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java +++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java -@@ -13,8 +13,8 @@ import net.minecraft.world.phys.Vec3; +@@ -14,8 +14,8 @@ import net.minecraft.world.phys.Vec3; public class EuclideanGameEventListenerRegistry implements GameEventListenerRegistry { private final List listeners = Lists.newArrayList(); @@ -121,7 +121,7 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c private boolean processing; private final ServerLevel level; private final int sectionY; -@@ -34,7 +34,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi +@@ -35,7 +35,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi @Override public void register(GameEventListener listener) { if (this.processing) { @@ -130,7 +130,7 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c } else { this.listeners.add(listener); } -@@ -45,7 +45,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi +@@ -46,7 +46,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi @Override public void unregister(GameEventListener listener) { if (this.processing) { @@ -139,7 +139,7 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c } else { this.listeners.remove(listener); } -@@ -65,7 +65,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi +@@ -66,7 +66,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi while (iterator.hasNext()) { GameEventListener gameEventListener = iterator.next(); @@ -148,7 +148,7 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c iterator.remove(); } else { Optional optional = getPostableListenerPosition(this.level, pos, gameEventListener); -@@ -79,6 +79,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi +@@ -80,6 +80,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi this.processing = false; } @@ -157,7 +157,7 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c if (!this.listenersToAdd.isEmpty()) { this.listeners.addAll(this.listenersToAdd); this.listenersToAdd.clear(); -@@ -88,6 +90,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi +@@ -89,6 +91,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi this.listeners.removeAll(this.listenersToRemove); this.listenersToRemove.clear(); } @@ -167,23 +167,23 @@ index 95c840f9bee51adef9bb00da5f53a5b011c0575e..1259d5d2ce58dd24b77a01d175a2037c return bl; } diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java -index 37ae0f928440af5b2fdfe68ad6c9c54e8c95c82c..039e31df469742eff5b176b9f269b88025f45721 100644 +index df6c97be1b278c97a20390be5d3e60f429383702..75a34d60d6729f3767dc9bef283db6e9e3baf3a7 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java +++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java -@@ -44,6 +44,7 @@ public class GameEventDispatcher { +@@ -45,6 +45,7 @@ public class GameEventDispatcher { int k1 = SectionPos.blockToSectionCoord(blockposition.getZ() + i); List list = new ArrayList(); GameEventListenerRegistry.ListenerVisitor gameeventlistenerregistry_a = (gameeventlistener, vec3d1) -> { -+ if (!gameeventlistener.listensToEvent(event, emitter)) return; // Leaf - petal - If they don't listen, ignore ++ if (!gameeventlistener.listensToEvent(event.value(), emitter)) return; // Leaf - petal - If they don't listen, ignore if (gameeventlistener.getDeliveryMode() == GameEventListener.DeliveryMode.BY_DISTANCE) { list.add(new GameEvent.ListenerInfo(event, emitterPos, emitter, gameeventlistener, vec3d1)); } else { diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java -index a4148dd326b10b0eb2bc7884691d79dcda60e010..ead325a818dca2e204ec79a06161adbaf439c9c3 100644 +index 0f3a79cc644a5b89fa35fdd413ff5781987c4ef3..9751ddc24899fd4d854899de209e24d9264baebc 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java +++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java -@@ -22,4 +22,10 @@ public interface GameEventListener { - public interface Holder { +@@ -23,4 +23,10 @@ public interface GameEventListener { + public interface Provider { T getListener(); } + @@ -191,5 +191,5 @@ index a4148dd326b10b0eb2bc7884691d79dcda60e010..ead325a818dca2e204ec79a06161adba + default boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) { + return true; + } -+ // Leaf end - petal ++ // Leaf end - petal - Add check for seeing if this listener cares about an event } diff --git a/patches/server/0042-Fix-tracker-NPE.patch b/patches/server/0035-Fix-tracker-NPE.patch similarity index 55% rename from patches/server/0042-Fix-tracker-NPE.patch rename to patches/server/0035-Fix-tracker-NPE.patch index 02b3c0de..d3b9b95b 100644 --- a/patches/server/0042-Fix-tracker-NPE.patch +++ b/patches/server/0035-Fix-tracker-NPE.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix tracker NPE diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 29ea09f27f4b0a7f1ab6075e68c7379898ff2339..80168d2a040c02504af3a4f3f68802afb327046d 100644 +index da9b182bb8d7d4457a66ecbc2adb289956780693..3852985ebf9643f6b1b17a3d090175800bcdd079 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -241,7 +241,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -244,7 +244,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final io.papermc.paper.util.player.NearbyPlayers nearbyPlayers; // Paper end // Paper start - optimise chunk tick iteration @@ -18,52 +18,28 @@ index 29ea09f27f4b0a7f1ab6075e68c7379898ff2339..80168d2a040c02504af3a4f3f68802af // Paper end - optimise chunk tick iteration diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 93ec0bdece165e5a5058f9a7ed2fd67dbcef2ab4..70b35ce82701454017b44e8a2fb3b45fefc6420e 100644 +index e769e8d8e853b2731d85b75d273b029fd08861fa..6e19dc2d167e47ead14aba57bb2ae2fa5eb2282a 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -9,6 +9,7 @@ import java.io.IOException; - import java.util.Arrays; - import java.util.Iterator; - import java.util.List; -+import java.util.ArrayList; // Leaf - import java.util.Objects; - import java.util.Optional; - import java.util.concurrent.CompletableFuture; -@@ -642,7 +643,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -640,7 +640,7 @@ public class ServerChunkCache extends ChunkSource { // Paper - optimise chunk tick iteration // Paper start - optimise chunk tick iteration if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -+ List copy = new ArrayList<>(this.chunkMap.needsChangeBroadcasting); // Leaf - Fix tracker NPE ++ List copy = new java.util.ArrayList<>(this.chunkMap.needsChangeBroadcasting); // Leaf - Fix tracker NPE this.chunkMap.needsChangeBroadcasting.clear(); for (ChunkHolder holder : copy) { holder.broadcastChanges(holder.getFullChunkNowUnchecked()); // LevelChunks are NEVER unloaded 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 7394c2d99499faaa4489a7eee1dd8b73ec08668d..d1603df4f829a7f3690970965f5549c99620db01 100644 +index 894082d9a8e2aa05f86948bfd335090f37a4ba07..679f3295d3e6cf6fa8ff535d60b39ad5fa771b5d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -@@ -1,6 +1,7 @@ - package net.minecraft.world.entity.ai.attributes; - - import com.google.common.collect.Multimap; -+import com.google.common.collect.Sets; // Leaf - import com.mojang.logging.LogUtils; - import java.util.Collection; - import java.util.Map; -@@ -10,7 +11,6 @@ import java.util.stream.Collectors; - import javax.annotation.Nullable; - - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; --import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; - import net.minecraft.Util; - import net.minecraft.core.Holder; - import net.minecraft.core.registries.BuiltInRegistries; -@@ -23,7 +23,7 @@ public class AttributeMap { +@@ -20,7 +20,7 @@ import org.slf4j.Logger; + public class AttributeMap { private static final Logger LOGGER = LogUtils.getLogger(); - // Gale start - Lithium - replace AI attributes with optimized collections - private final Map attributes = new Reference2ReferenceOpenHashMap<>(0); -- private final Set dirtyAttributes = new ReferenceOpenHashSet<>(0); -+ private final Set dirtyAttributes = Sets.newConcurrentHashSet(); // Leaf - Fix tracker NPE - // Gale end - Lithium - replace AI attributes with optimized collections + private final Map, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>(); +- private final Set dirtyAttributes = new ObjectOpenHashSet<>(); ++ private final Set dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); // Leaf - Fix tracker NPE private final AttributeSupplier supplier; - private final java.util.function.Function createInstance; // Gale - Airplane - reduce entity allocations + private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations + private final net.minecraft.world.entity.LivingEntity entity; // Purpur diff --git a/patches/server/0043-Optimize-Minecart-collisions.patch b/patches/server/0036-Optimize-Minecart-collisions.patch similarity index 88% rename from patches/server/0043-Optimize-Minecart-collisions.patch rename to patches/server/0036-Optimize-Minecart-collisions.patch index a4e3376e..d89644f9 100644 --- a/patches/server/0043-Optimize-Minecart-collisions.patch +++ b/patches/server/0036-Optimize-Minecart-collisions.patch @@ -9,20 +9,10 @@ Skip tick collisions to to prevent lag causing by massive stacked Minecart Useful for anarchy server. 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 eb5bd5cfd131042e366872bf599a315d83dc732b..9bf74e76a2b2fef92bef37fbaee2171b7f7a357d 100644 +index e7a1ce585c9e552e6f9ce9acd26fdfe5c43e0b5d..f9ae853fa762f103cfc6d7ad6f975ce099e348a3 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -5,7 +5,8 @@ import com.google.common.collect.ImmutableMap; - import com.google.common.collect.Maps; - import com.google.common.collect.UnmodifiableIterator; - import com.mojang.datafixers.util.Pair; --import java.util.Iterator; -+ -+import java.util.ArrayList; - import java.util.List; - import java.util.Map; - import javax.annotation.Nullable; -@@ -389,15 +390,15 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -386,15 +386,15 @@ public abstract class AbstractMinecart extends VehicleEntity { this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); } // CraftBukkit end @@ -44,7 +34,7 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..9bf74e76a2b2fef92bef37fbaee2171b if (!(entity instanceof Player) && !(entity instanceof IronGolem) && !(entity instanceof AbstractMinecart) && !this.isVehicle() && !entity.isPassenger()) { // CraftBukkit start VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, entity.getBukkitEntity()); -@@ -424,11 +425,7 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -421,11 +421,7 @@ public abstract class AbstractMinecart extends VehicleEntity { } } } else { @@ -57,7 +47,7 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..9bf74e76a2b2fef92bef37fbaee2171b if (!this.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { // CraftBukkit start VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, entity1.getBukkitEntity()); -@@ -442,6 +439,8 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -439,6 +435,8 @@ public abstract class AbstractMinecart extends VehicleEntity { } } } @@ -67,10 +57,10 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..9bf74e76a2b2fef92bef37fbaee2171b this.updateInWaterStateAndDoFluidPushing(); if (this.isInLava()) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ff05efe0b78defe3d25905b6a2984bdb646fcff3..820f5dc02f89a54fab00942a3eaa72f006b3bd89 100644 +index a304242573189b241228a40b7fd831c3326f11b6..a3adc109213885a193f7131405bd4a2f6a90f9be 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1572,12 +1572,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1571,12 +1571,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return this.getChunk(chunkX, chunkZ, ChunkStatus.FULL, false); } diff --git a/patches/server/0044-Reduce-canSee-work.patch b/patches/server/0037-Reduce-canSee-work.patch similarity index 89% rename from patches/server/0044-Reduce-canSee-work.patch rename to patches/server/0037-Reduce-canSee-work.patch index aed882ca..59e09714 100644 --- a/patches/server/0044-Reduce-canSee-work.patch +++ b/patches/server/0037-Reduce-canSee-work.patch @@ -7,10 +7,10 @@ Co-authored by: Martijn Muijsers Co-authored by: MachineBreaker diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 53dd6310617823328210511580d0fb744c8dca2b..998f1fbd581acc3fb654d539ebb25dcea5f110e0 100644 +index a3adc109213885a193f7131405bd4a2f6a90f9be..e971ef13754402f3de118ea24cb9f83b564cd65e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -392,17 +392,19 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -388,17 +388,19 @@ public abstract class Level implements LevelAccessor, AutoCloseable { for (int i = 0, len = entities.size(); i < len; ++i) { Entity entity = entities.get(i); @@ -36,10 +36,10 @@ index 53dd6310617823328210511580d0fb744c8dca2b..998f1fbd581acc3fb654d539ebb25dce if (net.minecraft.world.phys.shapes.Shapes.joinIsNotEmpty(voxelshape, net.minecraft.world.phys.shapes.Shapes.create(entity.getBoundingBox()), net.minecraft.world.phys.shapes.BooleanOp.AND)) { return false; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8b5c1d41f54084299ef1c25f7dd8bc6b3f234db5..857f682840f04734447856ab8386a53562031ae3 100644 +index bdc69aed63d1d84a398c25ccf3dabc7ae123fad8..753e5a1c99e427729c4bcb5378005fc8012996ab 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -557,6 +557,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -627,6 +627,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return false; } OfflinePlayer other = (OfflinePlayer) obj; diff --git a/patches/server/0037-Sync-with-Gale-s-Optimize-villager-data-storage.patc.patch b/patches/server/0037-Sync-with-Gale-s-Optimize-villager-data-storage.patc.patch deleted file mode 100644 index 27c8302e..00000000 --- a/patches/server/0037-Sync-with-Gale-s-Optimize-villager-data-storage.patc.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Sun, 9 Jul 2023 14:50:57 +0800 -Subject: [PATCH] Sync with Gale's Optimize-villager-data-storage.patch - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -index 753587e4d9582605951461f2bea37aff3bf28fcd..77fb2b0c4b9defaa16a2f89b194e8f5084ade12c 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -@@ -22,6 +22,7 @@ public class TradeWithVillager extends Behavior { - private static final float SPEED_MODIFIER = 0.5F; - // Gale start - optimize villager data storage - private static final Item[] WHEAT_SINGLETON_ARRAY = {Items.WHEAT}; -+ private static final Item[] NETHER_WART_SINGLETON_ARRAY = {Items.NETHER_WART}; // Leaf - sync with Gale's Optimize-villager-data-storage.patch - private @NotNull Item @Nullable [] trades = null; - // Gale end - optimize villager data storage - -@@ -67,7 +68,7 @@ public class TradeWithVillager extends Behavior { - - // Purpur start - if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getMaxStackSize() / 2) { -- throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager); -+ throwHalfStack(entity, NETHER_WART_SINGLETON_ARRAY, villager); // Leaf - sync with Gale's Optimize-villager-data-storage.patch - } - // Purpur end - -diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -index 8f36f113e8eb3236ce53ad9cce320c3d6253d248..ebe79d9ad2934b53085c8a720fdfca0a6eda05ca 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -+++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -@@ -31,7 +31,7 @@ public record VillagerProfession( - public static final VillagerProfession ARMORER = register("armorer", PoiTypes.ARMORER, SoundEvents.VILLAGER_WORK_ARMORER); - public static final VillagerProfession BUTCHER = register("butcher", PoiTypes.BUTCHER, SoundEvents.VILLAGER_WORK_BUTCHER); - public static final VillagerProfession CARTOGRAPHER = register("cartographer", PoiTypes.CARTOGRAPHER, SoundEvents.VILLAGER_WORK_CARTOGRAPHER); -- public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, ImmutableSet.of(Items.NETHER_WART), ImmutableSet.of(Blocks.SOUL_SAND), SoundEvents.VILLAGER_WORK_CLERIC); // Purpur -+ public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, new Item[] {Items.NETHER_WART}, Blocks.SOUL_SAND, SoundEvents.VILLAGER_WORK_CLERIC); // Purpur // Leaf - sync with Gale's Optimize-villager-data-storage.patch - public static final VillagerProfession FARMER = register( - "farmer", - PoiTypes.FARMER, diff --git a/patches/server/0045-Faster-Natural-Spawning.patch b/patches/server/0038-Faster-Natural-Spawning.patch similarity index 82% rename from patches/server/0045-Faster-Natural-Spawning.patch rename to patches/server/0038-Faster-Natural-Spawning.patch index 1b8848b3..fc6d61a7 100644 --- a/patches/server/0045-Faster-Natural-Spawning.patch +++ b/patches/server/0038-Faster-Natural-Spawning.patch @@ -22,10 +22,10 @@ index 9c6f5b55b1f1376fa75e216cd366ee47c79fafc4..7762c8186035fdf60e11d9f1844516b6 static RandomSource createThreadSafe() { return new ThreadSafeLegacyRandomSource(RandomSupport.generateUniqueSeed()); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 998f1fbd581acc3fb654d539ebb25dcea5f110e0..ba6ae356130f0147f3cc7886537c52b14926521f 100644 +index e971ef13754402f3de118ea24cb9f83b564cd65e..749fa63c641c1cb54445c85721c795355ffae123 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -126,6 +126,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -128,6 +128,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { protected float oThunderLevel; public float thunderLevel; public final RandomSource random = RandomSource.create(); @@ -34,10 +34,10 @@ index 998f1fbd581acc3fb654d539ebb25dcea5f110e0..ba6ae356130f0147f3cc7886537c52b1 @Deprecated private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 31003588de8bef9952a688c486049077328e89a3..9c4a8b6a4371bf8b1af05fb180b8fee020226e05 100644 +index 885d7c9ef96dd3c7576c28606e5ab83d2a75de71..31588bbfa4b80ed3ef19942bbe04baebd51e67fb 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -422,12 +422,12 @@ public final class NaturalSpawner { +@@ -405,12 +405,12 @@ public final class NaturalSpawner { private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Gale - Airplane - Use ThreadUnsafeRandom for mob spawning - accept ServerLevel ChunkPos chunkcoordintpair = chunk.getPos(); @@ -55,24 +55,16 @@ index 31003588de8bef9952a688c486049077328e89a3..9c4a8b6a4371bf8b1af05fb180b8fee0 } diff --git a/src/main/java/net/minecraft/world/level/levelgen/RandomSupport.java b/src/main/java/net/minecraft/world/level/levelgen/RandomSupport.java -index 4327bee689e986561d126d6018d3fee7d2623176..e2958cbcac0433ae5be186699ce5f9b57cf7e95c 100644 +index 4327bee689e986561d126d6018d3fee7d2623176..267a28724ea0aea926c51c37e1172a2c34b47375 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/RandomSupport.java +++ b/src/main/java/net/minecraft/world/level/levelgen/RandomSupport.java -@@ -5,6 +5,7 @@ import com.google.common.base.Charsets; - import com.google.common.hash.HashFunction; - import com.google.common.hash.Hashing; - import com.google.common.primitives.Longs; -+import java.util.concurrent.ThreadLocalRandom; - import java.util.concurrent.atomic.AtomicLong; - - public final class RandomSupport { -@@ -41,6 +42,12 @@ public final class RandomSupport { +@@ -41,6 +41,12 @@ public final class RandomSupport { return SEED_UNIQUIFIER.updateAndGet(seedUniquifier -> seedUniquifier * 1181783497276652981L) ^ System.nanoTime(); } + // Leaf start - Generate random seed faster + public static long generateFasterSeed() { -+ return SEED_UNIQUIFIER.updateAndGet((seedUniquifier) -> seedUniquifier * 1181783497276652981L)^ ThreadLocalRandom.current().nextLong(); ++ return SEED_UNIQUIFIER.updateAndGet((seedUniquifier) -> seedUniquifier * 1181783497276652981L)^ java.util.concurrent.ThreadLocalRandom.current().nextLong(); + } + // Leaf end + diff --git a/patches/server/0038-Sync-with-Gale-s-Optimize-sun-burn-tick.patch.patch b/patches/server/0038-Sync-with-Gale-s-Optimize-sun-burn-tick.patch.patch deleted file mode 100644 index f6166548..00000000 --- a/patches/server/0038-Sync-with-Gale-s-Optimize-sun-burn-tick.patch.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Sat, 3 Feb 2024 04:25:45 -0500 -Subject: [PATCH] Sync with Gale's Optimize-sun-burn-tick.patch - - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 21bb8ecc55c49a3962ad44c71145feadb49fe9ea..bf3ef85baf05eb4bfb4521c59e789a7f1de113b9 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -568,13 +568,29 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - } - - // Purpur start - copied from Mob -+ // Gale start - JettPack - optimize sun burn tick - cache eye blockpos -+ private BlockPos cached_eye_blockpos; -+ private int cached_position_hashcode; -+ // Gale end - JettPack - optimize sun burn tick - cache eye blockpos -+ - public boolean isSunBurnTick() { - if (this.level().isDay() && !this.level().isClientSide) { -- float f = this.getLightLevelDependentMagicValue(); -- BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); -+ // Gale start - JettPack - optimize sun burn tick - optimizations and cache eye blockpos -+ int positionHashCode = this.position.hashCode(); -+ if (this.cached_position_hashcode != positionHashCode) { -+ this.cached_eye_blockpos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); -+ this.cached_position_hashcode = positionHashCode; -+ } -+ -+ float f = this.getLightLevelDependentMagicValue(cached_eye_blockpos); // Pass BlockPos to getBrightness -+ -+ // Check brightness first -+ if (f <= 0.5F) return false; -+ if (this.random.nextFloat() * 30.0F >= (f - 0.4F) * 2.0F) return false; -+ // Gale end - JettPack - optimize sun burn tick - optimizations and cache eye blockpos - boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; - -- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { -+ if (!flag && this.level().canSeeSky(this.cached_eye_blockpos)) { // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos - return true; - } - } -diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 61f7a9f761a04011b2fa4caa7fef424ccb88793d..4145a992d34e655c98d8c5a30153f507360b798c 100644 ---- a/src/main/java/net/minecraft/world/entity/Mob.java -+++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1742,11 +1742,6 @@ public abstract class Mob extends LivingEntity implements Targeting { - - } - -- // Gale start - JettPack - optimize sun burn tick - cache eye blockpos -- private BlockPos cached_eye_blockpos; -- private int cached_position_hashcode; -- // Gale end - JettPack - optimize sun burn tick - cache eye blockpos -- - public boolean isSunBurnTick() { - return super.isSunBurnTick(); - } diff --git a/patches/server/0048-Fix-sprint-glitch.patch b/patches/server/0039-Fix-sprint-glitch.patch similarity index 84% rename from patches/server/0048-Fix-sprint-glitch.patch rename to patches/server/0039-Fix-sprint-glitch.patch index 1d399895..d3ce5b29 100644 --- a/patches/server/0048-Fix-sprint-glitch.patch +++ b/patches/server/0039-Fix-sprint-glitch.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix sprint glitch diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index dccb8934428b0c29e35f2bf9968fd32443dc11eb..becdbc814361a7823657759087b2ffcbd778b0e4 100644 +index c0eab84d85bdcd01058d3fa4871eb09e10b6171a..20954a7ae2ea649fe176787ec82320f3e946d752 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1439,7 +1439,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1451,7 +1451,8 @@ public abstract class LivingEntity extends Entity implements Attackable { player.setRealHealth(health); } diff --git a/patches/server/0049-Fix-keepalive-kicked-name.patch b/patches/server/0040-Fix-keepalive-kicked-name.patch similarity index 89% rename from patches/server/0049-Fix-keepalive-kicked-name.patch rename to patches/server/0040-Fix-keepalive-kicked-name.patch index 5aabff8c..fcd61479 100644 --- a/patches/server/0049-Fix-keepalive-kicked-name.patch +++ b/patches/server/0040-Fix-keepalive-kicked-name.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix keepalive kicked name diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 1610f21bbfbca0d12ca12373e56d90a54ac7c9f7..4a6bb425902b780ddfcc505e71d4ff70ff0babb9 100644 +index 5972362c1c968dbabb799824227c6ae3aef0b61e..f74f1411384945498823fbdcf9d2e0ce4fc3e8ae 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -241,7 +241,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -282,7 +282,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack if (GaleGlobalConfiguration.get().misc.keepalive.sendMultiple) { if (elapsedTime >= 1000L) { // 1 second if (!this.processedDisconnect && this.keepAlives.size() >= KEEPALIVE_LIMIT_IN_SECONDS) { diff --git a/patches/server/0050-Configurable-movement-speed-of-more-entities.patch b/patches/server/0041-Configurable-movement-speed-of-more-entities.patch similarity index 78% rename from patches/server/0050-Configurable-movement-speed-of-more-entities.patch rename to patches/server/0041-Configurable-movement-speed-of-more-entities.patch index 09cd0abf..f46d6be3 100644 --- a/patches/server/0050-Configurable-movement-speed-of-more-entities.patch +++ b/patches/server/0041-Configurable-movement-speed-of-more-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable movement speed of more entities 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 0939ca7c225790c7a294accd820be3ff8000ac75..cd0439a24644d0d5adf89911bad3e746b28191dc 100644 +index 05ed15bcd5974af13395316b50f4ae78385f2ee4..a7495d74d849d3723555da3ec0d65022399d63e4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java -@@ -89,6 +89,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -92,6 +92,7 @@ public class Drowned extends Zombie implements RangedAttackMob { @Override public void initAttributes() { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.drownedMaxHealth); @@ -17,30 +17,22 @@ index 0939ca7c225790c7a294accd820be3ff8000ac75..cd0439a24644d0d5adf89911bad3e746 @Override 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 06a5106a94a44c1d21537410d801cdd945503d69..be8e667841f7e4b9f9b261c90dc05c6a775ae226 100644 +index 95d3edc6c88d6ed0556c21c2623cdd5cfda35911..cc3bfada6ede81fa7f15d65a2982b926ef049c18 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Husk.java +++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java -@@ -12,6 +12,7 @@ import net.minecraft.world.entity.EntityDimensions; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.MobSpawnType; -+import net.minecraft.world.entity.ai.attributes.Attributes; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.level.Level; -@@ -45,6 +46,7 @@ public class Husk extends Zombie { +@@ -43,6 +43,7 @@ public class Husk extends Zombie { @Override public void initAttributes() { this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.huskMaxHealth); -+ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.huskMovementSpeed); // Leaf - Configurable husk movement speed ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.huskMovementSpeed); // Leaf - Configurable husk movement speed } @Override 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 6d69d936a2346f42abe8f867d51040121213b6ff..5ae6c0aa59f577ea4601fc8ba3768ed81bf0bcdb 100644 +index 70263881941efe3b406bbc571932fc8d2c1a78cb..888cf98d1ee16d00592520a8cd9e0241d540eb8e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -128,6 +128,7 @@ public class Zombie extends Monster { +@@ -125,6 +125,7 @@ public class Zombie extends Monster { @Override public void initAttributes() { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombieMaxHealth); @@ -48,7 +40,7 @@ index 6d69d936a2346f42abe8f867d51040121213b6ff..5ae6c0aa59f577ea4601fc8ba3768ed8 } public boolean jockeyOnlyBaby() { -@@ -185,9 +186,15 @@ public class Zombie extends Monster { +@@ -182,9 +183,15 @@ public class Zombie extends Monster { this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); } @@ -64,32 +56,24 @@ index 6d69d936a2346f42abe8f867d51040121213b6ff..5ae6c0aa59f577ea4601fc8ba3768ed8 + // Leaf end @Override - protected void defineSynchedData() { + protected void defineSynchedData(SynchedEntityData.Builder builder) { 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 d713afdc687b44595c40690f76e5d6c7ccb501c6..5435bbea79a4399b6e42ddd7c6dddf5e7e49d9bf 100644 +index 8ea44416ea728e740af82912017e888a10d78983..5d59af7a09f8d607ad797dd8315b56f74ce32db9 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -27,6 +27,7 @@ import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.EquipmentSlot; - import net.minecraft.world.entity.MobSpawnType; - import net.minecraft.world.entity.SpawnGroupData; -+import net.minecraft.world.entity.ai.attributes.Attributes; - import net.minecraft.world.entity.ai.village.ReputationEventType; - import net.minecraft.world.entity.npc.Villager; - import net.minecraft.world.entity.npc.VillagerData; -@@ -102,6 +103,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { +@@ -100,6 +100,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { @Override public void initAttributes() { this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombieVillagerMaxHealth); -+ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.zombieVillagerMovementSpeed); // Leaf - Configurable zombieVillager movement speed ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.zombieVillagerMovementSpeed); // Leaf - Configurable zombieVillager movement speed } @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -index feba8a264bae656244f60296d0511a8046297f73..2a24928fc4509ac3603f7e5ce574fed81274a5a1 100644 +index 5bae3215ee0bf222c3bd77b3131f3d01ac6c9c41..8a643108954698425413d14eb9a2c86c4b5c5074 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -@@ -84,6 +84,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -82,6 +82,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @Override public void initAttributes() { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombifiedPiglinMaxHealth); @@ -97,7 +81,7 @@ index feba8a264bae656244f60296d0511a8046297f73..2a24928fc4509ac3603f7e5ce574fed8 } @Override -@@ -125,9 +126,13 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -123,9 +124,13 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); } @@ -111,12 +95,12 @@ index feba8a264bae656244f60296d0511a8046297f73..2a24928fc4509ac3603f7e5ce574fed8 + // Leaf end @Override - protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { + public EntityDimensions getDefaultDimensions(Pose pose) { diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc2a06fb17 100644 +index dde2e82e8f3686f6b77fefdaad9beaeb90059c23..3416c6778faf56666a521a69382799bb1bee1497 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1530,6 +1530,7 @@ public class PurpurWorldConfig { +@@ -1525,6 +1525,7 @@ public class PurpurWorldConfig { public boolean drownedTakeDamageFromWater = false; public boolean drownedBreakDoors = false; public boolean drownedAlwaysDropExp = false; @@ -124,7 +108,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc private void drownedSettings() { drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); -@@ -1547,6 +1548,7 @@ public class PurpurWorldConfig { +@@ -1542,6 +1543,7 @@ public class PurpurWorldConfig { drownedTakeDamageFromWater = getBoolean("mobs.drowned.takes-damage-from-water", drownedTakeDamageFromWater); drownedBreakDoors = getBoolean("mobs.drowned.can-break-doors", drownedBreakDoors); drownedAlwaysDropExp = getBoolean("mobs.drowned.always-drop-exp", drownedAlwaysDropExp); @@ -132,7 +116,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc } public boolean elderGuardianRidable = false; -@@ -1893,6 +1895,7 @@ public class PurpurWorldConfig { +@@ -1888,6 +1890,7 @@ public class PurpurWorldConfig { public boolean huskJockeyTryExistingChickens = true; public boolean huskTakeDamageFromWater = false; public boolean huskAlwaysDropExp = false; @@ -140,7 +124,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc private void huskSettings() { huskRidable = getBoolean("mobs.husk.ridable", huskRidable); huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); -@@ -1909,6 +1912,7 @@ public class PurpurWorldConfig { +@@ -1904,6 +1907,7 @@ public class PurpurWorldConfig { huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens); huskTakeDamageFromWater = getBoolean("mobs.husk.takes-damage-from-water", huskTakeDamageFromWater); huskAlwaysDropExp = getBoolean("mobs.husk.always-drop-exp", huskAlwaysDropExp); @@ -148,7 +132,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc } public boolean illusionerRidable = false; -@@ -3123,6 +3127,7 @@ public class PurpurWorldConfig { +@@ -3118,6 +3122,7 @@ public class PurpurWorldConfig { public boolean zombieTakeDamageFromWater = false; public boolean zombieAlwaysDropExp = false; public double zombieHeadVisibilityPercent = 0.5D; @@ -156,7 +140,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc private void zombieSettings() { zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); -@@ -3142,6 +3147,7 @@ public class PurpurWorldConfig { +@@ -3137,6 +3142,7 @@ public class PurpurWorldConfig { zombieTakeDamageFromWater = getBoolean("mobs.zombie.takes-damage-from-water", zombieTakeDamageFromWater); zombieAlwaysDropExp = getBoolean("mobs.zombie.always-drop-exp", zombieAlwaysDropExp); zombieHeadVisibilityPercent = getDouble("mobs.zombie.head-visibility-percent", zombieHeadVisibilityPercent); @@ -164,7 +148,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc } public boolean zombieHorseRidable = false; -@@ -3190,6 +3196,7 @@ public class PurpurWorldConfig { +@@ -3185,6 +3191,7 @@ public class PurpurWorldConfig { public int zombieVillagerCuringTimeMax = 6000; public boolean zombieVillagerCureEnabled = true; public boolean zombieVillagerAlwaysDropExp = false; @@ -172,7 +156,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc private void zombieVillagerSettings() { zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); -@@ -3209,6 +3216,7 @@ public class PurpurWorldConfig { +@@ -3204,6 +3211,7 @@ public class PurpurWorldConfig { zombieVillagerCuringTimeMax = getInt("mobs.zombie_villager.curing_time.max", zombieVillagerCuringTimeMax); zombieVillagerCureEnabled = getBoolean("mobs.zombie_villager.cure.enabled", zombieVillagerCureEnabled); zombieVillagerAlwaysDropExp = getBoolean("mobs.zombie_villager.always-drop-exp", zombieVillagerAlwaysDropExp); @@ -180,7 +164,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc } public boolean zombifiedPiglinRidable = false; -@@ -3222,6 +3230,7 @@ public class PurpurWorldConfig { +@@ -3217,6 +3225,7 @@ public class PurpurWorldConfig { public boolean zombifiedPiglinCountAsPlayerKillWhenAngry = true; public boolean zombifiedPiglinTakeDamageFromWater = false; public boolean zombifiedPiglinAlwaysDropExp = false; @@ -188,7 +172,7 @@ index bf92f6c9d1ecff3e56e5bb904c7af9e793823e93..d37bc0dde078c2246474eadd19f6ebcc private void zombifiedPiglinSettings() { zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); -@@ -3239,6 +3248,7 @@ public class PurpurWorldConfig { +@@ -3234,6 +3243,7 @@ public class PurpurWorldConfig { zombifiedPiglinCountAsPlayerKillWhenAngry = getBoolean("mobs.zombified_piglin.count-as-player-kill-when-angry", zombifiedPiglinCountAsPlayerKillWhenAngry); zombifiedPiglinTakeDamageFromWater = getBoolean("mobs.zombified_piglin.takes-damage-from-water", zombifiedPiglinTakeDamageFromWater); zombifiedPiglinAlwaysDropExp = getBoolean("mobs.zombified_piglin.always-drop-exp", zombifiedPiglinAlwaysDropExp); diff --git a/patches/server/0051-Faster-sequencing-of-futures-for-chunk-structure-gen.patch b/patches/server/0042-Faster-sequencing-of-futures-for-chunk-structure-gen.patch similarity index 89% rename from patches/server/0051-Faster-sequencing-of-futures-for-chunk-structure-gen.patch rename to patches/server/0042-Faster-sequencing-of-futures-for-chunk-structure-gen.patch index 8380304d..d52b73a9 100644 --- a/patches/server/0051-Faster-sequencing-of-futures-for-chunk-structure-gen.patch +++ b/patches/server/0042-Faster-sequencing-of-futures-for-chunk-structure-gen.patch @@ -7,10 +7,10 @@ Replace `thenApply` with `thenCompose`. Once one task is completed then the next to prevent blocking threads while waiting to complete all tasks diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 01a12f4d6f3c2f09bffc78692443b9fd391db45a..da6a9d2e315bf769e762b70599eeff25f6540728 100644 +index 0bd367235f80c1f0d319a6aa5130d82ad82d895c..194a883e028d1dff82516da0a890497d6aa3aeef 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -410,7 +410,11 @@ public class Util { +@@ -459,7 +459,11 @@ public class Util { return futures.get(0).thenApply(List::of); } else { CompletableFuture completableFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); diff --git a/patches/server/0052-Reduce-items-finding-hopper-nearby-check.patch b/patches/server/0043-Reduce-items-finding-hopper-nearby-check.patch similarity index 88% rename from patches/server/0052-Reduce-items-finding-hopper-nearby-check.patch rename to patches/server/0043-Reduce-items-finding-hopper-nearby-check.patch index 8b4cd2b6..98a78732 100644 --- a/patches/server/0052-Reduce-items-finding-hopper-nearby-check.patch +++ b/patches/server/0043-Reduce-items-finding-hopper-nearby-check.patch @@ -9,10 +9,10 @@ But still recommend to turn-off `checkForMinecartNearItemWhileActive` Since `Reduce-hopper-item-checks.patch` will cause lag under massive dropped items 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 00eb84726a6563ef1d7b29977566086df1bab090..056f3c234fc853a46f804d9d21f51eed47321e3f 100644 +index 18d1be51ca12c3ccac5a5130667c47c1f1235935..eebc8d5bc5f2c9dcd2fc38ca056485bf78874284 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -238,7 +238,9 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -244,7 +244,9 @@ public class ItemEntity extends Entity implements TraceableEntity { this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause return; // Gale - EMC - reduce hopper item checks } @@ -24,10 +24,10 @@ index 00eb84726a6563ef1d7b29977566086df1bab090..056f3c234fc853a46f804d9d21f51eed } } diff --git a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -index 356ec77bf63da9a218036c92bde9bf5fa006c1ac..0ac00c3c6aa6c5418b21a68e91520224d13a7b00 100644 +index c3c9fc0d126e3f258fa8f06901fb3cac0d0ab289..6571926d9f63a16b5d00ee63874dd0496f0a0290 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java +++ b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -@@ -76,10 +76,11 @@ public class GaleWorldConfiguration extends ConfigurationPart { +@@ -75,10 +75,11 @@ public class GaleWorldConfiguration extends ConfigurationPart { public TemporaryImmunity temporaryImmunity; public class TemporaryImmunity extends ConfigurationPart { diff --git a/patches/server/0044-Plazma-Add-some-missing-Pufferfish-configurations.patch b/patches/server/0044-Plazma-Add-some-missing-Pufferfish-configurations.patch new file mode 100644 index 00000000..57687337 --- /dev/null +++ b/patches/server/0044-Plazma-Add-some-missing-Pufferfish-configurations.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Wed, 27 Sep 2023 18:29:51 +0900 +Subject: [PATCH] Plazma: Add some missing Pufferfish configurations + +Original license: MIT +Original project: https://github.com/PlazmaMC/PlazmaBukkit + +Add Pufferfish DAB support for Camel, Sniffer +https://github.com/pufferfish-gg/Pufferfish/issues/83 + +diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +index 063dde771ade593a29481f14b8f44a0f72f15953..e658456676aba19861d301d009f61a3b5cb078da 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java ++++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +@@ -128,8 +128,10 @@ public class Armadillo extends Animal { + return ArmadilloAi.makeBrain(this.brainProvider().makeBrain(dynamic)); + } + ++ private int behaviorTick; // Leaf - Plazma - Add missing Pufferfish configurations + @Override + protected void customServerAiStep() { ++ if (this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations + ((Brain) this.brain).tick((ServerLevel) this.level(), this); // CraftBukkit - decompile error + ArmadilloAi.updateActivity(this); + if (this.isAlive() && !this.isBaby() && --this.scuteTime <= 0) { +diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +index 041def64118a5b8ed96e9982b2ed645dd9a8822a..c6eee4df07f9c5122504e5c9d5ad0465728ad48c 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java ++++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +@@ -149,10 +149,12 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl + return pose == Pose.SITTING ? Camel.SITTING_DIMENSIONS.scale(this.getAgeScale()) : super.getDefaultDimensions(pose); + } + ++ private int behaviorTick = 0; // Leaf - Plazma - Add missing Pufferfish configurations + @Override + protected void customServerAiStep() { + Brain behaviorcontroller = (Brain) this.getBrain(); // CraftBukkit - decompile error + ++ if (this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations + behaviorcontroller.tick((ServerLevel) this.level(), this); + CamelAi.updateActivity(this); + super.customServerAiStep(); +diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +index 9325dcc7e5af135ad6e44983e0e1dda5504a26d0..8d01aeec5daa9da49338dd77173c7757d36a68a8 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java ++++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +@@ -502,8 +502,10 @@ public class Sniffer extends Animal { + return Brain.provider(SnifferAi.MEMORY_TYPES, SnifferAi.SENSOR_TYPES); + } + ++ private int behaviorTick; // Leaf - Plazma - Add missing Pufferfish configurations + @Override + protected void customServerAiStep() { ++ if (this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations + this.getBrain().tick((ServerLevel) this.level(), this); + SnifferAi.updateActivity(this); + super.customServerAiStep(); diff --git a/patches/server/0055-Plazma-Add-missing-purpur-configuration-options.patch b/patches/server/0045-Plazma-Add-missing-purpur-configuration-options.patch similarity index 60% rename from patches/server/0055-Plazma-Add-missing-purpur-configuration-options.patch rename to patches/server/0045-Plazma-Add-missing-purpur-configuration-options.patch index 9971cd54..b1b1a4ca 100644 --- a/patches/server/0055-Plazma-Add-missing-purpur-configuration-options.patch +++ b/patches/server/0045-Plazma-Add-missing-purpur-configuration-options.patch @@ -9,15 +9,14 @@ Original project: https://github.com/PlazmaMC/PlazmaBukkit Add more Purpur configurable options for entities diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -index eb60d2d99155aae4a761051175fbbddf9ed5dad9..5444213b336bc08eb371673890ded04c1178fd90 100644 +index 3755ed3c550f9553f147fd442a01958ec19c87b3..cc0385ec99dda911f2a6b96c491a63f381fc9a47 100644 --- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -@@ -150,6 +150,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS - protected void registerGoals() { - this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur +@@ -152,6 +152,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.allayTakeDamageFromWater; @@ -32,20 +31,20 @@ index eb60d2d99155aae4a761051175fbbddf9ed5dad9..5444213b336bc08eb371673890ded04c + public void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.allayMaxHealth); + } -+ // Plazma end - // Purpur end - ++ // Leaf end - Plazma ++ @Override + protected Brain.Provider brainProvider() { + return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index a215c5a42943fcb97448e3ed67467e61efb0d28d..7bb25b1a8919abe4b9b65b6b5d54642aa3d7bba3 100644 +index c6eee4df07f9c5122504e5c9d5ad0465728ad48c..2cea089cc394642f1467f0b3a4773e06c89d6a54 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -97,6 +97,18 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl - public int getPurpurBreedTime() { - return this.level().purpurConfig.camelBreedingTicks; +@@ -95,6 +95,18 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.camelTakeDamageFromWater; @@ -55,20 +54,29 @@ index a215c5a42943fcb97448e3ed67467e61efb0d28d..7bb25b1a8919abe4b9b65b6b5d54642a + public boolean isAlwaysExperienceDropper() { + return level().purpurConfig.camelAlwaysDropExp; + } -+ // Plazma end - // Purpur end - ++ // Leaf start - Plazma ++ @Override + public void addAdditionalSaveData(CompoundTag nbt) { + super.addAdditionalSaveData(nbt); +@@ -154,7 +166,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl + protected void customServerAiStep() { + Brain behaviorcontroller = (Brain) this.getBrain(); // CraftBukkit - decompile error + +- if (this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations // Leaf - Plazma - Add missing purpur configurations + behaviorcontroller.tick((ServerLevel) this.level(), this); + CamelAi.updateActivity(this); + super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index bde190fd608262fcf9eb272316c4984c918252ed..ecedc765b08aa6c2f11e48eac5c601baf6281ba9 100644 +index da026533b15a1981000e73bba6c5209c13de28dc..96d2077abd0112f2b2b8c4678447afbf899cd290 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -162,6 +162,23 @@ public class Frog extends Animal implements VariantHolder { - public float getJumpPower() { - return (getRider() != null && isControllable()) ? level().purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower(); +@@ -162,6 +162,23 @@ public class Frog extends Animal implements VariantHolder> { } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.frogTakeDamageFromWater; @@ -83,20 +91,20 @@ index bde190fd608262fcf9eb272316c4984c918252ed..ecedc765b08aa6c2f11e48eac5c601ba + public void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.frogMaxHealth); + } -+ // Plazma end - // Purpur end - ++ // Leaf end - Plazma ++ public int getPurpurBreedTime() { + return this.level().purpurConfig.frogBreedingTicks; + } 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 cd696f6bb7f77338dd289c7c2d6bdf23d79264aa..5b333513bd618c9b108bae13299431bc4b66ad35 100644 +index e6861fd5f9817ec54294976f0e93952baa387773..2fe21d0d8807365610ef4f7346874e08e7342886 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 -@@ -90,6 +90,23 @@ public class Tadpole extends AbstractFish { - protected void registerGoals() { - this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur +@@ -95,6 +95,23 @@ public class Tadpole extends AbstractFish { } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.tadpoleTakeDamageFromWater; @@ -111,20 +119,20 @@ index cd696f6bb7f77338dd289c7c2d6bdf23d79264aa..5b333513bd618c9b108bae13299431bc + public void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.tadpoleMaxHealth); + } -+ // Plazma end - // Purpur end - ++ // Leaf end - Plazma ++ @Override + protected PathNavigation createNavigation(Level world) { + return new WaterBoundPathNavigation(this, world); diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index 9962e83e9478db6de3869d53eaa4c4dc9dc847b4..4e7867e7239eb573b287a70eee8191bdf434f686 100644 +index 8d01aeec5daa9da49338dd77173c7757d36a68a8..07c932fb02190cf031b8e9dbca33ef9c49caa8e9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -106,6 +106,18 @@ public class Sniffer extends Animal { - public boolean isControllable() { - return level().purpurConfig.snifferControllable; +@@ -121,6 +121,18 @@ public class Sniffer extends Animal { } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.snifferTakeDamageFromWater; @@ -134,20 +142,29 @@ index 9962e83e9478db6de3869d53eaa4c4dc9dc847b4..4e7867e7239eb573b287a70eee8191bd + public boolean isAlwaysExperienceDropper() { + return level().purpurConfig.snifferAlwaysDropExp; + } -+ // Plazma end - // Purpur end - ++ // Leaf end - Plazma ++ @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); +@@ -505,7 +517,7 @@ public class Sniffer extends Animal { + private int behaviorTick; // Leaf - Plazma - Add missing Pufferfish configurations + @Override + protected void customServerAiStep() { +- if (this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Plazma - Add missing Pufferfish configurations // Leaf - Plazma - Add missing purpur configurations + this.getBrain().tick((ServerLevel) this.level(), this); + SnifferAi.updateActivity(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 df0d0868c11c26b2cadc1a07196a0191e16838a0..5ebef8ad47b8dc27de23b878eec86f5136e4c9ec 100644 +index 3102be6066b0a8065cc0c80b5c4a5d369dc35b72..7feb830447da1f487de66d1dba1c1d1f4d28c62f 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 -@@ -147,6 +147,23 @@ public class Warden extends Monster implements VibrationSystem { - this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur +@@ -149,6 +149,23 @@ public class Warden extends Monster implements VibrationSystem { } -+ -+ // Plazma start + // Purpur end + ++ // Leaf start - Plazma + @Override + public boolean isSensitiveToWater() { + return level().purpurConfig.wardenTakeDamageFromWater; @@ -162,147 +179,192 @@ index df0d0868c11c26b2cadc1a07196a0191e16838a0..5ebef8ad47b8dc27de23b878eec86f51 + public void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.wardenMaxHealth); + } -+ // Plazma end - // Purpur end - ++ // Leaf end - Plazma ++ @Override + public Packet getAddEntityPacket() { + return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); +@@ -300,7 +317,7 @@ public class Warden extends Monster implements VibrationSystem { + protected void customServerAiStep() { + ServerLevel worldserver = (ServerLevel) this.level(); + +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Leaf - Plazma - Add missing purpur configurations + this.getBrain().tick(worldserver, this); + super.customServerAiStep(); + if ((this.tickCount + this.getId()) % 120 == 0) { diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -index 58af87b8faf4f8d6bdb111c49a429466acface68..7ae4b748ee6c95feb64d514292e31bea8c52e29d 100644 +index b04f7ce0805453f6c737fa9dc11c4129ca64e934..7ee2e841b364928620f36bd65b39aab354f9051e 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -@@ -43,7 +43,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain +@@ -45,7 +45,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain public ChestBoat(EntityType type, Level world) { super(type, world); - this.itemStacks = NonNullList.withSize(27, ItemStack.EMPTY); -+ this.itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // Plazma ++ this.itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // Leaf - Plazma } public ChestBoat(Level world, double d0, double d1, double d2) { -@@ -170,7 +170,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain +@@ -172,7 +172,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain @Override public int getContainerSize() { - return 27; -+ return org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // Plazma ++ return org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // Leaf - Plazma } @Override diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index 63b5a0993207c55357ac507c974dea77206e80f4..e45c11bf2c42e6d57f803349d8ca6936ac98c995 100644 +index 8facd29bac314d4b8897113460f78ea7ed3e82b6..300d5144d828330e3de934b1026a0f1b96496d79 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -336,6 +336,7 @@ public class PurpurConfig { +@@ -323,6 +323,7 @@ public class PurpurConfig { } public static int barrelRows = 3; -+ public static int chestBoatRows = 3; // Plazma ++ public static int chestBoatRows = 3; // Leaf - Plazma public static boolean enderChestSixRows = false; public static boolean enderChestPermissionRows = false; public static boolean cryingObsidianValidForPortalFrame = false; -@@ -376,6 +377,7 @@ public class PurpurConfig { +@@ -363,6 +364,7 @@ public class PurpurConfig { case 1 -> 9; default -> 27; }); -+ chestBoatRows = getInt("settings.blocks.chest_boat.rows", chestBoatRows); // Plazma ++ chestBoatRows = getInt("settings.blocks.chest_boat.rows", chestBoatRows); // Leaf - Plazma enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows); org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 99fed6e959d62082e7922aa95da614f8ce776838..4a863e33be9673a57b1edbdd51220fabbd9812ed 100644 +index 3416c6778faf56666a521a69382799bb1bee1497..92e41dab573e8c979564c83377e460cd93ec2865 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1195,7 +1195,15 @@ public class PurpurWorldConfig { +@@ -1165,10 +1165,20 @@ public class PurpurWorldConfig { + public boolean allayRidable = false; public boolean allayRidableInWater = true; public boolean allayControllable = true; - public List allayRespectNBT = new ArrayList<>(); -+ // Plazma start - Add missing purpur config options ++ // Leaf start - Plazma - Add missing purpur config options + public double allayMaxHealth = 20.0D; + public boolean allayTakeDamageFromWater = false; + public boolean allayAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void allaySettings() { -+ allayMaxHealth = getDouble("mobs.allay.max-health", allayMaxHealth); -+ allayTakeDamageFromWater = getBoolean("mobs.allay.take-damage-from-water", allayTakeDamageFromWater); -+ allayAlwaysDropExp = getBoolean("mobs.allay.always-drop-exp", allayAlwaysDropExp); -+ // Plazma end allayRidable = getBoolean("mobs.allay.ridable", allayRidable); allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); allayControllable = getBoolean("mobs.allay.controllable", allayControllable); -@@ -1314,7 +1322,15 @@ public class PurpurWorldConfig { ++ // Leaf start - Plazma - Add missing purpur config options ++ allayMaxHealth = getDouble("mobs.allay.max-health", allayMaxHealth); ++ allayTakeDamageFromWater = getBoolean("mobs.allay.take-damage-from-water", allayTakeDamageFromWater); ++ allayAlwaysDropExp = getBoolean("mobs.allay.always-drop-exp", allayAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean axolotlRidable = false; +@@ -1282,6 +1292,10 @@ public class PurpurWorldConfig { public double camelMovementSpeedMin = 0.09D; public double camelMovementSpeedMax = 0.09D; public int camelBreedingTicks = 6000; -+ // Plazma start - Add missing purpur config options -+ //public boolean camelRidableInWater = false; ++ // Leaf start - Plazma - Add missing purpur config options + public boolean camelTakeDamageFromWater = false; + public boolean camelAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void camelSettings() { -+ //camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); -+ camelTakeDamageFromWater = getBoolean("mobs.camel.takes-damage-from-water", camelTakeDamageFromWater); -+ camelAlwaysDropExp = getBoolean("mobs.camel.always-drop-exp", camelAlwaysDropExp); -+ // Plazma end camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin); - camelMaxHealthMax = getDouble("mobs.camel.attributes.max_health.max", camelMaxHealthMax); -@@ -1744,7 +1760,15 @@ public class PurpurWorldConfig { +@@ -1291,6 +1305,10 @@ public class PurpurWorldConfig { + camelMovementSpeedMin = getDouble("mobs.camel.attributes.movement_speed.min", camelMovementSpeedMin); + camelMovementSpeedMax = getDouble("mobs.camel.attributes.movement_speed.max", camelMovementSpeedMax); + camelBreedingTicks = getInt("mobs.camel.breeding-delay-ticks", camelBreedingTicks); ++ // Leaf start - Plazma - Add missing purpur config options ++ camelTakeDamageFromWater = getBoolean("mobs.camel.takes-damage-from-water", camelTakeDamageFromWater); ++ camelAlwaysDropExp = getBoolean("mobs.camel.always-drop-exp", camelAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean catRidable = false; +@@ -1712,12 +1730,22 @@ public class PurpurWorldConfig { public boolean frogControllable = true; public float frogRidableJumpHeight = 0.65F; public int frogBreedingTicks = 6000; -+ // Plazma start - Add missing purpur config options ++ // Leaf start - Plazma - Add missing purpur config options + public double frogMaxHealth = 10.0D; + public boolean frogTakeDamageFromWater = false; + public boolean frogAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void frogSettings() { -+ frogMaxHealth = getDouble("mobs.frog.attributes.max_health", frogMaxHealth); -+ frogTakeDamageFromWater = getBoolean("mobs.frog.takes-damage-from-water", frogTakeDamageFromWater); -+ frogAlwaysDropExp = getBoolean("mobs.frog.always-drop-exp", frogAlwaysDropExp); -+ // Plazma end frogRidable = getBoolean("mobs.frog.ridable", frogRidable); frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); frogControllable = getBoolean("mobs.frog.controllable", frogControllable); -@@ -2690,7 +2714,13 @@ public class PurpurWorldConfig { + frogRidableJumpHeight = (float) getDouble("mobs.frog.ridable-jump-height", frogRidableJumpHeight); + frogBreedingTicks = getInt("mobs.frog.breeding-delay-ticks", frogBreedingTicks); ++ // Leaf start - Plazma - Add missing purpur config options ++ frogMaxHealth = getDouble("mobs.frog.attributes.max_health", frogMaxHealth); ++ frogTakeDamageFromWater = getBoolean("mobs.frog.takes-damage-from-water", frogTakeDamageFromWater); ++ frogAlwaysDropExp = getBoolean("mobs.frog.always-drop-exp", frogAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean ghastRidable = false; +@@ -2658,12 +2686,20 @@ public class PurpurWorldConfig { public boolean snifferControllable = true; public double snifferMaxHealth = 14.0D; public int snifferBreedingTicks = 6000; -+ // Plazma start - Add missing purpur config options ++ // Leaf start - Plazma - Add missing purpur config options + public boolean snifferTakeDamageFromWater = false; + public boolean snifferAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void snifferSettings() { -+ snifferTakeDamageFromWater = getBoolean("mobs.sniffer.takes-damage-from-water", snifferTakeDamageFromWater); -+ snifferAlwaysDropExp = getBoolean("mobs.sniffer.always-drop-exp", snifferAlwaysDropExp); -+ // Plazma end snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); -@@ -2789,7 +2819,15 @@ public class PurpurWorldConfig { + snifferMaxHealth = getDouble("mobs.sniffer.attributes.max_health", snifferMaxHealth); + snifferBreedingTicks = getInt("mobs.sniffer.breeding-delay-ticks", chickenBreedingTicks); ++ // Leaf start - Plazma - Add missing purpur config options ++ snifferTakeDamageFromWater = getBoolean("mobs.sniffer.takes-damage-from-water", snifferTakeDamageFromWater); ++ snifferAlwaysDropExp = getBoolean("mobs.sniffer.always-drop-exp", snifferAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean squidRidable = false; +@@ -2757,10 +2793,20 @@ public class PurpurWorldConfig { public boolean tadpoleRidable = false; public boolean tadpoleRidableInWater = true; public boolean tadpoleControllable = true; -+ // Plazma start - Add missing purpur config options ++ // Leaf start - Plazma - Add missing purpur config options + public double tadpoleMaxHealth = 6.0D; // Leaf - Tadpole health should be 6 + public boolean tadpoleTakeDamageFromWater = false; + public boolean tadpoleAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void tadpoleSettings() { -+ tadpoleMaxHealth = getDouble("mobs.tadpole.attributes.max_health", tadpoleMaxHealth); -+ tadpoleTakeDamageFromWater = getBoolean("mobs.tadpole.takes-damage-from-water", tadpoleTakeDamageFromWater); -+ tadpoleAlwaysDropExp = getBoolean("mobs.tadpole.always-drop-exp", tadpoleAlwaysDropExp); -+ // Plazma end tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); -@@ -3005,7 +3043,15 @@ public class PurpurWorldConfig { ++ // Leaf start - Plazma - Add missing purpur config options ++ tadpoleMaxHealth = getDouble("mobs.tadpole.attributes.max_health", tadpoleMaxHealth); ++ tadpoleTakeDamageFromWater = getBoolean("mobs.tadpole.takes-damage-from-water", tadpoleTakeDamageFromWater); ++ tadpoleAlwaysDropExp = getBoolean("mobs.tadpole.always-drop-exp", tadpoleAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean traderLlamaRidable = false; +@@ -2973,10 +3019,20 @@ public class PurpurWorldConfig { public boolean wardenRidable = false; public boolean wardenRidableInWater = true; public boolean wardenControllable = true; -+ // Plazma start - Add missing purpur config options ++ // Leaf start - Plazma - Add missing purpur config options + public double wardenMaxHealth = 500.0D; + public boolean wardenTakeDamageFromWater = false; + public boolean wardenAlwaysDropExp = false; ++ // Leaf end - Plazma - Add missing purpur config options private void wardenSettings() { -+ wardenMaxHealth = getDouble("mobs.warden.attributes.max_health", wardenMaxHealth); -+ wardenTakeDamageFromWater = getBoolean("mobs.warden.takes-damage-from-water", wardenTakeDamageFromWater); -+ wardenAlwaysDropExp = getBoolean("mobs.warden.always-drop-exp", wardenAlwaysDropExp); -+ // Plazma end wardenRidable = getBoolean("mobs.warden.ridable", wardenRidable); wardenRidableInWater = getBoolean("mobs.warden.ridable-in-water", wardenRidableInWater); wardenControllable = getBoolean("mobs.warden.controllable", wardenControllable); ++ // Leaf start - Plazma - Add missing purpur config options ++ wardenMaxHealth = getDouble("mobs.warden.attributes.max_health", wardenMaxHealth); ++ wardenTakeDamageFromWater = getBoolean("mobs.warden.takes-damage-from-water", wardenTakeDamageFromWater); ++ wardenAlwaysDropExp = getBoolean("mobs.warden.always-drop-exp", wardenAlwaysDropExp); ++ // Leaf end - Plazma - Add missing purpur config options + } + + public boolean witchRidable = false; diff --git a/patches/server/0057-Skip-event-if-no-listeners.patch b/patches/server/0046-Skip-event-if-no-listeners.patch similarity index 85% rename from patches/server/0057-Skip-event-if-no-listeners.patch rename to patches/server/0046-Skip-event-if-no-listeners.patch index b743f9fe..80a25f36 100644 --- a/patches/server/0057-Skip-event-if-no-listeners.patch +++ b/patches/server/0046-Skip-event-if-no-listeners.patch @@ -5,21 +5,21 @@ Subject: [PATCH] Skip event if no listeners diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index cc38235d2b5f3fc5113a4d495f14f81cd24d7cb9..930711fd827d009a57171afa24d55fa8e53a08ca 100644 +index 9be6ddce778f47ce2c8371757ab8d30978b96888..dadc5ee6a79a47cbebcc8e8c943c2147cc16d732 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -36,6 +36,10 @@ class PaperEventManager { +@@ -35,6 +35,10 @@ class PaperEventManager { // SimplePluginManager public void callEvent(@NotNull Event event) { + // Leaf start - Skip event if no listeners + RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); + if (listeners.length == 0) return; -+ // Leaf end ++ // Leaf end - Skip event if no listeners // KTP start - Optimise spigot event bus if (event.asynchronous() != net.kyori.adventure.util.TriState.NOT_SET) { final boolean onPrimaryThread = this.server.isPrimaryThread(); -@@ -55,9 +59,6 @@ class PaperEventManager { +@@ -53,9 +57,6 @@ class PaperEventManager { // KTP stop - Optimise spigot event bus } diff --git a/patches/server/0047-Fix-casting-in-Purpur-world-config.patch b/patches/server/0047-Fix-casting-in-Purpur-world-config.patch deleted file mode 100644 index bf1eed7e..00000000 --- a/patches/server/0047-Fix-casting-in-Purpur-world-config.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Tue, 24 Oct 2023 20:02:48 -0400 -Subject: [PATCH] Fix casting in Purpur world config - - -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 7459ca7b724634a191498bf05e345c7e97fbe901..cd73f0e40e5010e3069330ae66120dace63cde56 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -678,7 +678,7 @@ public class PurpurWorldConfig { - dropsMap.forEach((itemId, chance) -> { - Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); - if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.strippables." + blockId + ".drops`: " + itemId); return; } -- drops.put(item, (double) chance); -+ drops.put(item, (Double) chance); // Leaf - Fix casting - }); - axeStrippables.put(block, new Strippable(into, drops)); - }); -@@ -732,7 +732,7 @@ public class PurpurWorldConfig { - dropsMap.forEach((itemId, chance) -> { - Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); - if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.waxables." + blockId + ".drops`: " + itemId); return; } -- drops.put(item, (double) chance); -+ drops.put(item, (Double) chance); // Leaf - Fix casting - }); - axeWaxables.put(block, new Waxable(into, drops)); - }); -@@ -777,7 +777,7 @@ public class PurpurWorldConfig { - dropsMap.forEach((itemId, chance) -> { - Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); - if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.weatherables." + blockId + ".drops`: " + itemId); return; } -- drops.put(item, (double) chance); -+ drops.put(item, (Double) chance); // Leaf - Fix casting - }); - axeWeatherables.put(block, new Weatherable(into, drops)); - }); -@@ -803,7 +803,7 @@ public class PurpurWorldConfig { - dropsMap.forEach((itemId, chance) -> { - Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); - if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.hoe.tillables." + blockId + ".drops`: " + itemId); return; } -- drops.put(item, (double) chance); -+ drops.put(item, (Double) chance); // Leaf - Fix casting - }); - hoeTillables.put(block, new Tillable(condition, into, drops)); - }); -@@ -827,7 +827,7 @@ public class PurpurWorldConfig { - dropsMap.forEach((itemId, chance) -> { - Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); - if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.shovel.flattenables." + blockId + ".drops`: " + itemId); return; } -- drops.put(item, (double) chance); -+ drops.put(item, (Double) chance); // Leaf - Fix casting - }); - shovelFlattenables.put(block, new Flattenable(into, drops)); - }); diff --git a/patches/server/0058-PaperPR-Rewrite-framed-map-tracker-ticking.patch b/patches/server/0047-PaperPR-Rewrite-framed-map-tracker-ticking.patch similarity index 82% rename from patches/server/0058-PaperPR-Rewrite-framed-map-tracker-ticking.patch rename to patches/server/0047-PaperPR-Rewrite-framed-map-tracker-ticking.patch index a2425181..e39c6a58 100644 --- a/patches/server/0058-PaperPR-Rewrite-framed-map-tracker-ticking.patch +++ b/patches/server/0047-PaperPR-Rewrite-framed-map-tracker-ticking.patch @@ -16,31 +16,29 @@ now is just updating dirty map/decoration data. When no bukkit renderers are added to the map, we also re-use the same packet for all players who are tracking it which avoids a lot of work. diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 60e8bfc89cfb92e2f7d4860b11c16b3bc5e2f095..b7c7e2727382d06c1ed83bac6e721e48f3d855d5 100644 +index 504711d92cd50f9aa2026cb2311540a5a7825790..db3936d43b39056dd4138278a23c6992b950bbae 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -111,29 +111,42 @@ public class ServerEntity { +@@ -113,27 +113,40 @@ public class ServerEntity { Entity entity = this.entity; -- if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame) { // Paper - Perf: Only tick item frames if players can see it -+ if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame frame && frame.cachedMapId != null) { // Paper - Perf: Only tick item frames if players can see it // Paper - ItemFrame entityitemframe = (ItemFrame) entity; - +- if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame entityitemframe) { // Paper - Perf: Only tick item frames if players can see it ++ if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame entityitemframe && entityitemframe.cachedMapId != null) { // Paper - Perf: Only tick item frames if players can see it // Paper if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block - ItemStack itemstack = entityitemframe.getItem(); + //ItemStack itemstack = entityitemframe.getItem(); // Paper - skip redundant getItem - if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable + if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 /*&& itemstack.getItem() instanceof MapItem*/) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable // Paper - skip redundant getItem - Integer integer = entityitemframe.cachedMapId; // Paper - Perf: Cache map ids on item frames - MapItemSavedData worldmap = MapItem.getSavedData(integer, this.level); + MapId mapid = entityitemframe.cachedMapId; // Paper - Perf: Cache map ids on item frames + MapItemSavedData worldmap = MapItem.getSavedData(mapid, this.level); if (worldmap != null) { + // Paper start - re-use the same update packet when possible + if (!worldmap.hasContextualRenderer) { + // Pass in a "random" player when a non-contextual plugin renderer is added to make sure its called -+ final Packet updatePacket = worldmap.framedUpdatePacket(integer, worldmap.hasPluginRenderer ? com.google.common.collect.Iterables.getFirst(this.trackedPlayers, null).getPlayer() : null); ++ final Packet updatePacket = worldmap.framedUpdatePacket(mapid, worldmap.hasPluginRenderer ? com.google.common.collect.Iterables.getFirst(this.trackedPlayers, null).getPlayer() : null); + + if (updatePacket != null) { + for (ServerPlayerConnection connection : this.trackedPlayers) { @@ -55,9 +53,9 @@ index 60e8bfc89cfb92e2f7d4860b11c16b3bc5e2f095..b7c7e2727382d06c1ed83bac6e721e48 ServerPlayer entityplayer = iterator.next().getPlayer(); // CraftBukkit - worldmap.tickCarriedBy(entityplayer, itemstack); -- Packet packet = worldmap.getUpdatePacket(integer, entityplayer); +- Packet packet = worldmap.getUpdatePacket(mapid, entityplayer); + //worldmap.tickCarriedBy(entityplayer, itemstack); // Paper -+ Packet packet = worldmap.framedUpdatePacket(integer, entityplayer); // Paper ++ Packet packet = worldmap.framedUpdatePacket(mapid, entityplayer); // Paper if (packet != null) { entityplayer.connection.send(packet); @@ -67,7 +65,7 @@ index 60e8bfc89cfb92e2f7d4860b11c16b3bc5e2f095..b7c7e2727382d06c1ed83bac6e721e48 } } -@@ -378,6 +391,19 @@ public class ServerEntity { +@@ -380,6 +393,19 @@ public class ServerEntity { } } @@ -88,10 +86,10 @@ index 60e8bfc89cfb92e2f7d4860b11c16b3bc5e2f095..b7c7e2727382d06c1ed83bac6e721e48 private void sendDirtyEntityData() { 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 2363d9eaad655389c7b7d67d545ef8025f550431..b779297432d78a2acd499dd00d9c1601c21a4e08 100644 +index 9af8fcf6abb9b768829592bc1b091ebe4599ed2e..68646c1b29f325cacf58fe372cecb8f4b4407adb 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -489,6 +489,16 @@ public class ItemFrame extends HangingEntity { +@@ -467,6 +467,16 @@ public class ItemFrame extends HangingEntity { } this.setItem(ItemStack.fromBukkitCopy(event.getItemStack())); // Paper end - Add PlayerItemFrameChangeEvent @@ -106,13 +104,13 @@ index 2363d9eaad655389c7b7d67d545ef8025f550431..b779297432d78a2acd499dd00d9c1601 + } + // Paper end this.gameEvent(GameEvent.BLOCK_CHANGE, player); - if (!player.getAbilities().instabuild) { - itemstack.shrink(1); + itemstack.consume(1, player); + } diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4fa14df79 100644 +index ac3341ea02985fdbafa405a4a3bc232439ff2e62..bdcf01af3792e8bca1af7aea887d3d7bb3250162 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -67,6 +67,16 @@ public class MapItemSavedData extends SavedData { +@@ -79,6 +79,16 @@ public class MapItemSavedData extends SavedData { private final Map frameMarkers = Maps.newHashMap(); private int trackedDecorationCount; private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper @@ -129,23 +127,23 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 public boolean isExplorerMap; // Purpur // CraftBukkit start -@@ -333,6 +343,7 @@ public class MapItemSavedData extends SavedData { +@@ -352,6 +362,7 @@ public class MapItemSavedData extends SavedData { } this.setDecorationsDirty(); + if (mapicon != null && mapicon.renderOnFrame()) this.dirtyFrameDecorations = true; // Paper } - public static void addTargetDecoration(ItemStack stack, BlockPos pos, String id, MapDecoration.Type type) { -@@ -428,6 +439,7 @@ public class MapItemSavedData extends SavedData { + public static void addTargetDecoration(ItemStack stack, BlockPos pos, String id, Holder decorationType) { +@@ -433,6 +444,7 @@ public class MapItemSavedData extends SavedData { } this.setDecorationsDirty(); -+ if (type.isRenderedOnFrame() || (mapicon1 != null && mapicon.type().isRenderedOnFrame())) this.dirtyFrameDecorations = true; // Paper ++ if (type.value().showOnItemFrame() || (mapicon1 != null && mapicon.type().value().showOnItemFrame())) this.dirtyFrameDecorations = true; // Paper } } -@@ -441,6 +453,20 @@ public class MapItemSavedData extends SavedData { +@@ -446,6 +458,20 @@ public class MapItemSavedData extends SavedData { public void setColorsDirty(int x, int z) { this.setDirty(); @@ -166,7 +164,7 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 Iterator iterator = this.carriedBy.iterator(); while (iterator.hasNext()) { -@@ -523,6 +549,7 @@ public class MapItemSavedData extends SavedData { +@@ -528,6 +554,7 @@ public class MapItemSavedData extends SavedData { public void removedFromFrame(BlockPos pos, int id) { this.removeDecoration("frame-" + id); this.frameMarkers.remove(MapFrame.frameId(pos)); @@ -174,20 +172,20 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 } public boolean updateColor(int x, int z, byte color) { -@@ -580,6 +607,93 @@ public class MapItemSavedData extends SavedData { - return this.trackedDecorationCount >= iconCount; +@@ -585,6 +612,93 @@ public class MapItemSavedData extends SavedData { + return this.trackedDecorationCount >= decorationCount; } + // Paper start -+ public final @Nullable Packet framedUpdatePacket(int id, @Nullable Player player) { -+ return createUpdatePacket(id, player, false); ++ public final @Nullable Packet framedUpdatePacket(MapId mapid, @Nullable Player player) { ++ return createUpdatePacket(mapid, player, false); + } + -+ public final @Nullable Packet fullUpdatePacket(int id, @Nullable Player player) { -+ return createUpdatePacket(id, player, true); ++ public final @Nullable Packet fullUpdatePacket(MapId mapid, @Nullable Player player) { ++ return createUpdatePacket(mapid, player, true); + } + -+ public final @Nullable Packet createUpdatePacket(int id, @Nullable Player player, boolean full) { ++ public final @Nullable Packet createUpdatePacket(MapId mapid, @Nullable Player player, boolean full) { + if (!dirtyColorData && !dirtyFrameDecorations && (player == null || server.getCurrentTick() % 5 != 0) && !full) // Periodically send update packets if a renderer is added + return null; + @@ -222,7 +220,7 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 + + for (final org.bukkit.map.MapCursor cursor : render.cursors) { + if (cursor.isVisible()) { -+ decorations.add(new MapDecoration(MapDecoration.Type.byIcon(cursor.getRawType()), cursor.getX(), cursor.getY(), cursor.getDirection(), PaperAdventure.asVanilla(cursor.caption()))); // Paper - Adventure ++ decorations.add(new MapDecoration(CraftMapCursor.CraftType.bukkitToMinecraftHolder(cursor.getType()), cursor.getX(), cursor.getY(), cursor.getDirection(), CraftChatMessage.fromStringOrOptional(cursor.getCaption()))); // Paper - Adventure + } + } + } @@ -251,7 +249,7 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 + return; + + MapFrame mapFrame = new MapFrame(frame.getPos(), frame.getDirection().get2DDataValue() * 90, frame.getId()); -+ this.addDecoration(MapDecoration.Type.FRAME, frame.level(), "frame-" + frame.getId(), frame.getPos().getX(), frame.getPos().getZ(), mapFrame.getRotation(), (Component) null); ++ this.addDecoration(MapDecorationTypes.FRAME, frame.level(), "frame-" + frame.getId(), frame.getPos().getX(), frame.getPos().getZ(), mapFrame.getRotation(), (Component) null); + this.frameMarkers.put(mapFrame.getId(), mapFrame); + } + @@ -269,10 +267,10 @@ index e1498d496aa01c433b6fa198608e33916eadecf3..80a3a17b86277df3edac32b7b81abee4 // Paper start diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java -index c3266c43a073cb7d7eff10d1a1b15f0a2265b859..4d69e345117556bac2126edc5169ab01eed97377 100644 +index a15cdf64575841edfe30f2b2c522f8fdfe2caae3..ce20060e48226cc1cbe476a404ef6e1f6bdb9137 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java -@@ -108,6 +108,10 @@ public final class CraftMapView implements MapView { +@@ -101,6 +101,10 @@ public final class CraftMapView implements MapView { this.renderers.add(renderer); this.canvases.put(renderer, new HashMap()); renderer.initialize(this); @@ -283,7 +281,7 @@ index c3266c43a073cb7d7eff10d1a1b15f0a2265b859..4d69e345117556bac2126edc5169ab01 } } -@@ -123,6 +127,17 @@ public final class CraftMapView implements MapView { +@@ -116,6 +120,17 @@ public final class CraftMapView implements MapView { } } this.canvases.remove(renderer); diff --git a/patches/server/0059-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch b/patches/server/0048-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch similarity index 67% rename from patches/server/0059-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch rename to patches/server/0048-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch index ac80c2db..714faa86 100644 --- a/patches/server/0059-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch +++ b/patches/server/0048-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch @@ -11,18 +11,18 @@ Optimizes "image in map" maps, without requiring the map to be locked, which som This has the disadvantage that the vanilla map data will never be updated while the CraftMapRenderer is not present, but that's not a huuuge problem for u diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index 8d3c1897044f9a2bbe1911e1a72dc9a00fb246df..c97bfd7396ec419fe3a8f6c88ccf864d52ad7e68 100644 +index 608390ed36710a419de1542b80340dd3fcc7299c..98449cfbad78833808a6ad069baaa723e701231f 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -325,7 +325,7 @@ public class MapItem extends ComplexItem { - worldmap.tickCarriedBy(entityhuman, stack); +@@ -277,7 +277,7 @@ public class MapItem extends ComplexItem { + mapItemSavedData.tickCarriedBy(player, stack); } -- if (!worldmap.locked && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { -+ if (!worldmap.locked && (!org.dreeam.leaf.config.modules.opt.SkipMapItemDataUpdates.enabled || worldmap.mapView.getRenderers().stream().anyMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list - this.update(world, entity, worldmap); +- if (!mapItemSavedData.locked && (selected || entity instanceof Player && ((Player)entity).getOffhandItem() == stack)) { ++ if (!mapItemSavedData.locked && (!org.dreeam.leaf.config.modules.opt.SkipMapItemDataUpdates.enabled || mapItemSavedData.mapView.getRenderers().stream().anyMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (selected || entity instanceof Player && ((Player)entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list + this.update(world, entity, mapItemSavedData); } - + } diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/SkipMapItemDataUpdates.java b/src/main/java/org/dreeam/leaf/config/modules/opt/SkipMapItemDataUpdates.java new file mode 100644 index 0000000000000000000000000000000000000000..014de86c0fe97d7b7ad789191dfc121419fda8a0 diff --git a/patches/server/0060-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch b/patches/server/0049-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch similarity index 91% rename from patches/server/0060-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch rename to patches/server/0049-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch index 845a5f29..c236bdf3 100644 --- a/patches/server/0060-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch +++ b/patches/server/0049-SparklyPaper-Cache-coordinate-key-used-for-nearby-pl.patch @@ -32,10 +32,10 @@ index f164256d59b761264876ca0c85f812d101bfd5de..10465a33d90a1e43b9dbd7764c895dd3 final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 70b35ce82701454017b44e8a2fb3b45fefc6420e..caef142261734aab264d1da420ff5e6d7117ea1c 100644 +index 6e19dc2d167e47ead14aba57bb2ae2fa5eb2282a..e6f6304724ae6acaf94ed9553c90c9650be5c0c6 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -594,7 +594,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -591,7 +591,7 @@ public class ServerChunkCache extends ChunkSource { // Paper start - optimise chunk tick iteration com.destroystokyo.paper.util.maplist.ReferenceList playersNearby @@ -45,10 +45,10 @@ index 70b35ce82701454017b44e8a2fb3b45fefc6420e..caef142261734aab264d1da420ff5e6d continue; } diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index f7e5e016a7028a9196e689e950805b0d5b31fe38..d0285843920f78e05ce07b1b0b2d8ce97ec8041e 100644 +index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..1ac1af72a71bbf402f0d1633a4b8c9a408917d73 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -62,7 +62,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -65,7 +65,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom protected final ShortList[] postProcessing; protected volatile boolean unsaved; private volatile boolean isLightCorrect; @@ -57,7 +57,7 @@ index f7e5e016a7028a9196e689e950805b0d5b31fe38..d0285843920f78e05ce07b1b0b2d8ce9 private long inhabitedTime; /** @deprecated */ @Nullable -@@ -136,7 +136,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -139,7 +139,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom } // Paper end - rewrite light engine this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups diff --git a/patches/server/0061-SparklyPaper-Optimize-canSee-checks.patch b/patches/server/0050-SparklyPaper-Optimize-canSee-checks.patch similarity index 91% rename from patches/server/0061-SparklyPaper-Optimize-canSee-checks.patch rename to patches/server/0050-SparklyPaper-Optimize-canSee-checks.patch index 6ed2261b..90da3b54 100644 --- a/patches/server/0061-SparklyPaper-Optimize-canSee-checks.patch +++ b/patches/server/0050-SparklyPaper-Optimize-canSee-checks.patch @@ -16,10 +16,10 @@ This seems stupid, but it does seem that it improves the performance a bit, and We also create a "canSee" method tailored for "ChunkMap#updatePlayer()", a method without the equals check (the "updatePlayer()" already checks if the entity is the same entity) because the CraftPlayer's `equals()` check is a *bit* expensive compared to only checking the object's identity, and because the identity has already been check, we don't need to check it twice. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index fdd72e567a1a59153da2adb35a9605b828698535..d6c44f1179688cfee19f9772baaacd22902a91f7 100644 +index 3852985ebf9643f6b1b17a3d090175800bcdd079..4f2f652cf7403221226e524586aa73feecd0d103 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1420,7 +1420,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1434,7 +1434,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - Configurable entity tracking range by Y // CraftBukkit start - respect vanish API @@ -29,10 +29,10 @@ index fdd72e567a1a59153da2adb35a9605b828698535..d6c44f1179688cfee19f9772baaacd22 } // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 857f682840f04734447856ab8386a53562031ae3..e3c2c3ba19eb04d93d3f5a9a73555bdc64c93b77 100644 +index 753e5a1c99e427729c4bcb5378005fc8012996ab..ea784b6c5aeb156147900ad6161c52cc185825dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -193,7 +193,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -198,7 +198,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private boolean hasPlayedBefore = false; private final ConversationTracker conversationTracker = new ConversationTracker(); private final Set channels = new HashSet(); @@ -41,7 +41,7 @@ index 857f682840f04734447856ab8386a53562031ae3..e3c2c3ba19eb04d93d3f5a9a73555bdc private final Set unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; -@@ -2168,9 +2168,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2238,9 +2238,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public boolean canSee(org.bukkit.entity.Entity entity) { diff --git a/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch b/patches/server/0051-Polpot-Make-egg-and-snowball-can-knockback-player.patch similarity index 79% rename from patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch rename to patches/server/0051-Polpot-Make-egg-and-snowball-can-knockback-player.patch index c85ebff4..ee6d13cf 100644 --- a/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch +++ b/patches/server/0051-Polpot-Make-egg-and-snowball-can-knockback-player.patch @@ -6,32 +6,24 @@ Subject: [PATCH] Polpot: Make egg and snowball can knockback player Original project: https://github.com/HaHaWTH/Polpot diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -index bb61e1132c28274175215a679befdcfa2496b099..8cc2c353334f6cfcadb8c12e96ad09f746b41bf8 100644 +index 1b9d0e28e518c501b4b93ae385ddd64aeade97d5..650e0e88e2a608fe6326806a830e437cf75a9e4f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -@@ -3,6 +3,7 @@ package net.minecraft.world.entity.projectile; - import net.minecraft.core.particles.ItemParticleOption; - import net.minecraft.core.particles.ParticleOptions; - import net.minecraft.core.particles.ParticleTypes; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.LivingEntity; -@@ -61,6 +62,12 @@ public class Snowball extends ThrowableItemProjectile { +@@ -61,6 +61,12 @@ public class Snowball extends ThrowableItemProjectile { int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float) i); + // Leaf start - Polpot - Make snowball can knockback player -+ if (org.dreeam.leaf.config.modules.gameplay.Knockback.snowballCanKnockback && entity instanceof ServerPlayer) { ++ if (org.dreeam.leaf.config.modules.gameplay.Knockback.snowballCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer) { + entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); -+ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ()); ++ ((net.minecraft.server.level.ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ()); + } -+ // Leaf end - Polpot ++ // Leaf end - Polpot - Make snowball can knockback player } // Purpur start - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -index 82bb8004635865f5202578d5a6f520048e7269d5..f1e2643926a020fd66967e64001f2987cfe334bf 100644 +index 82bb8004635865f5202578d5a6f520048e7269d5..bbfaf70522bddba18c16b5007b03c73b8073245f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java @@ -46,7 +46,14 @@ public class ThrownEgg extends ThrowableItemProjectile { @@ -45,7 +37,7 @@ index 82bb8004635865f5202578d5a6f520048e7269d5..f1e2643926a020fd66967e64001f2987 + entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); + ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ()); + } -+ // Leaf end - Polpot ++ // Leaf end - Polpot - Make egg can knockback player } @Override diff --git a/patches/server/0064-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch b/patches/server/0052-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch similarity index 86% rename from patches/server/0064-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch rename to patches/server/0052-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch index b5c517a8..98b96257 100644 --- a/patches/server/0064-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch +++ b/patches/server/0052-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Redirect vanilla getProfiler in PathNavigationRegion diff --git a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java b/src/main/java/net/minecraft/world/level/PathNavigationRegion.java -index a1a4b99167919bedb8a45c3b81889f58f2abfbcc..b0f619c0c145d32e6e5db066428b1c0f0a3774e4 100644 +index a1a4b99167919bedb8a45c3b81889f58f2abfbcc..30d19ae31fe29436482b3fbe146dc6238b1fd04b 100644 --- a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java +++ b/src/main/java/net/minecraft/world/level/PathNavigationRegion.java @@ -150,4 +150,10 @@ public class PathNavigationRegion implements BlockGetter, CollisionGetter { @@ -17,5 +17,5 @@ index a1a4b99167919bedb8a45c3b81889f58f2abfbcc..b0f619c0c145d32e6e5db066428b1c0f + public net.minecraft.util.profiling.ProfilerFiller getProfiler() { + return net.minecraft.util.profiling.InactiveProfiler.INSTANCE; // Gale - Purpur - remove vanilla profiler + } -+ // Leaf end ++ // Leaf end - Redirect to fix plugin incompatibility } diff --git a/patches/server/0066-Fix-MC-2025.patch b/patches/server/0053-Fix-MC-2025.patch similarity index 82% rename from patches/server/0066-Fix-MC-2025.patch rename to patches/server/0053-Fix-MC-2025.patch index 453bdbe6..26b035f1 100644 --- a/patches/server/0066-Fix-MC-2025.patch +++ b/patches/server/0053-Fix-MC-2025.patch @@ -6,12 +6,12 @@ Subject: [PATCH] Fix MC-2025 Mojang issues: https://bugs.mojang.com/browse/MC-2025 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index bf3ef85baf05eb4bfb4521c59e789a7f1de113b9..c873f1a36954f9ebf007153e37dc0b3953cebd1e 100644 +index 8b314a1ad2bf833cee950471d63e5538192bb1ab..c0089483f2085b60fa34884885fa83915d5fc143 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2566,6 +2566,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -2629,6 +2629,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } - // Paper end + // Purpur end nbttagcompound.put("Leaves.Data", leavesData); // Leaves - leaves ex data + + // Leaf start - Fix MC-2025 @@ -21,12 +21,12 @@ index bf3ef85baf05eb4bfb4521c59e789a7f1de113b9..c873f1a36954f9ebf007153e37dc0b39 + boundingBoxList.add(DoubleTag.valueOf(coord)); + } + nbttagcompound.put("Leaf.BoundingBox", boundingBoxList); -+ // Leaf end ++ // Leaf end - Fix MC-2025 + return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2643,6 +2653,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S +@@ -2706,6 +2716,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.reapplyPosition(); } @@ -35,7 +35,7 @@ index bf3ef85baf05eb4bfb4521c59e789a7f1de113b9..c873f1a36954f9ebf007153e37dc0b39 + ListTag boundingBoxList = nbt.getList("Leaf.BoundingBox", net.minecraft.nbt.Tag.TAG_DOUBLE); + setBoundingBox(new AABB(boundingBoxList.getDouble(0), boundingBoxList.getDouble(1), boundingBoxList.getDouble(2), boundingBoxList.getDouble(3), boundingBoxList.getDouble(4), boundingBoxList.getDouble(5))); + } -+ // Leaf end ++ // Leaf end - Fix MC-2025 + } else { throw new IllegalStateException("Entity has invalid rotation"); diff --git a/patches/server/0067-Fix-MC-65198.patch b/patches/server/0054-Fix-MC-65198.patch similarity index 94% rename from patches/server/0067-Fix-MC-65198.patch rename to patches/server/0054-Fix-MC-65198.patch index ad26e0fd..70f60bed 100644 --- a/patches/server/0067-Fix-MC-65198.patch +++ b/patches/server/0054-Fix-MC-65198.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix MC-65198 Mojang issues: https://bugs.mojang.com/browse/MC-65198 diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index 3756de835ea87e3a4fb87cbf77365ffd87957ea9..66e149fe132191293b6075f3368192f7007b143d 100644 +index 7215af6cc91f48b040c23c54536d4aac8d293497..53002139c8ba4e4886cf73404c3bbd152421053a 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -141,6 +141,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -27,7 +27,7 @@ index 3756de835ea87e3a4fb87cbf77365ffd87957ea9..66e149fe132191293b6075f3368192f7 } diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java -index accf752e7615f775483830f81bd0df30e40d3c7f..d3d7f9b81e0244b7d3a487ab16e78fd8be736765 100644 +index f17ff5988d826c8fad68f6bf7bac1d06edae01ae..02337174c26d7532c3ab99e269ec7ce8793b7f13 100644 --- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java +++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java @@ -45,7 +45,7 @@ public class ResultSlot extends Slot { diff --git a/patches/server/0069-Including-5s-in-getTPS.patch b/patches/server/0055-Including-5s-in-getTPS.patch similarity index 92% rename from patches/server/0069-Including-5s-in-getTPS.patch rename to patches/server/0055-Including-5s-in-getTPS.patch index ac8bc55d..43924db9 100644 --- a/patches/server/0069-Including-5s-in-getTPS.patch +++ b/patches/server/0055-Including-5s-in-getTPS.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Including 5s in getTPS() diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index db96be7e6f30ecab1349c1fe68fcdd2f4e27167d..c7faba7ff1101f68fef4a67c502e45a66ec77b93 100644 +index f17eb11741d09f9b04eac98918261680b600749a..25cbef3e87fd9924a86b019355df922eaf3773e1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -3152,6 +3152,8 @@ public final class CraftServer implements Server { +@@ -3170,6 +3170,8 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { diff --git a/patches/server/0056-Plazma-Add-some-missing-Pufferfish-configurations.patch b/patches/server/0056-Plazma-Add-some-missing-Pufferfish-configurations.patch deleted file mode 100644 index 41d0078d..00000000 --- a/patches/server/0056-Plazma-Add-some-missing-Pufferfish-configurations.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Wed, 27 Sep 2023 18:29:51 +0900 -Subject: [PATCH] Plazma: Add some missing Pufferfish configurations - -Original license: MIT -Original project: https://github.com/PlazmaMC/PlazmaBukkit - -Add Pufferfish DAB support for Camel, Sniffer, Warden -https://github.com/pufferfish-gg/Pufferfish/issues/83 - -diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index 7bb25b1a8919abe4b9b65b6b5d54642aa3d7bba3..60dcd2f996dbb4fc4d24489a225f52645c526adb 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -+++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -170,10 +170,12 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl - return dimensions.height - 0.1F * this.getScale(); - } - -+ private int behaviorTick = 0; // Plazma - Add missing pufferfish configurations - @Override - protected void customServerAiStep() { - Brain behaviorcontroller = (Brain) this.getBrain(); // CraftBukkit - decompile error - -+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Plazma - Add missing pufferfish configurations - behaviorcontroller.tick((ServerLevel) this.level(), this); - CamelAi.updateActivity(this); - super.customServerAiStep(); -diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index 4e7867e7239eb573b287a70eee8191bdf434f686..2c6c153187f97cd07157d72cbe4c9829161f74b7 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -527,8 +527,10 @@ public class Sniffer extends Animal { - return Brain.provider(SnifferAi.MEMORY_TYPES, SnifferAi.SENSOR_TYPES); - } - -+ private int behaviorTick; // Plazma - Add missing pufferfish configurations - @Override - protected void customServerAiStep() { -+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Plazma - Add missing pufferfish configurations - this.getBrain().tick((ServerLevel) this.level(), this); - SnifferAi.updateActivity(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 5ebef8ad47b8dc27de23b878eec86f5136e4c9ec..8acd9a0037e12670472734cd86c95336a04f9f13 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 -@@ -319,7 +319,7 @@ public class Warden extends Monster implements VibrationSystem { - protected void customServerAiStep() { - ServerLevel worldserver = (ServerLevel) this.level(); - -- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Plazma - this.getBrain().tick(worldserver, this); - super.customServerAiStep(); - if ((this.tickCount + this.getId()) % 120 == 0) { diff --git a/patches/server/0070-Remove-useless-creating-stats-json-bases-on-player-n.patch b/patches/server/0056-Remove-useless-creating-stats-json-bases-on-player-n.patch similarity index 75% rename from patches/server/0070-Remove-useless-creating-stats-json-bases-on-player-n.patch rename to patches/server/0056-Remove-useless-creating-stats-json-bases-on-player-n.patch index 8bc53867..d690df70 100644 --- a/patches/server/0070-Remove-useless-creating-stats-json-bases-on-player-n.patch +++ b/patches/server/0056-Remove-useless-creating-stats-json-bases-on-player-n.patch @@ -5,24 +5,24 @@ Subject: [PATCH] Remove useless creating stats json bases on player name logic diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index e960528f7e261552b3936e596d0ff9c285a151ca..25c7f47382f8a9949e2785c36f67dcf455d33f5a 100644 +index 07b9f53d49d9ba8bbd3fa3da99bb7cd05510a00c..c0d8094d26e1edf3ccee789158cba2e3a2fb8fca 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1580,6 +1580,8 @@ public abstract class PlayerList { +@@ -1576,6 +1576,8 @@ public abstract class PlayerList { File file = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile(); - File file1 = new File(file, uuid + ".json"); + File file1 = new File(file, String.valueOf(uuid) + ".json"); + // Leaf start - Remove useless creating stats json bases on player name logic + /* if (!file1.exists()) { File file2 = new File(file, displayName + ".json"); // CraftBukkit Path path = file2.toPath(); -@@ -1588,6 +1590,8 @@ public abstract class PlayerList { +@@ -1584,6 +1586,8 @@ public abstract class PlayerList { file2.renameTo(file1); } } + */ -+ // Leaf end ++ // Leaf end - Remove useless creating stats json bases on player name logic serverstatisticmanager = new ServerStatsCounter(this.server, file1); // this.stats.put(uuid, serverstatisticmanager); // CraftBukkit diff --git a/patches/server/0071-Fix-NPE-during-creating-GUI-graph.patch b/patches/server/0057-Fix-NPE-during-creating-GUI-graph.patch similarity index 87% rename from patches/server/0071-Fix-NPE-during-creating-GUI-graph.patch rename to patches/server/0057-Fix-NPE-during-creating-GUI-graph.patch index 1a9bf5b7..797a0d4a 100644 --- a/patches/server/0071-Fix-NPE-during-creating-GUI-graph.patch +++ b/patches/server/0057-Fix-NPE-during-creating-GUI-graph.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix NPE during creating GUI graph diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java -index 7c32c60100cf2bd109eb8762efa856c10b704fdd..7b0bff870d65383844c091806b19fdfa5e3a5db7 100644 +index 7c32c60100cf2bd109eb8762efa856c10b704fdd..81d40895cfa84676f5b200f53b128d9d6c5bc0bd 100644 --- a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java +++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java @@ -59,7 +59,14 @@ public class RAMDetails extends JList { @@ -20,7 +20,7 @@ index 7c32c60100cf2bd109eb8762efa856c10b704fdd..7b0bff870d65383844c091806b19fdfa + server.tps5.getAverage(), + server.tps15.getAverage() + }; // Gale - Purpur - 5 second TPS average -+ // Leaf end ++ // Leaf end - Revert to fix potential NPE during creating GUI graph String[] tpsAvg = new String[tps.length]; for ( int g = 0; g < tps.length; g++) { diff --git a/patches/server/0072-Don-t-throw-exception-on-missing-ResourceKey-value.patch b/patches/server/0058-Don-t-throw-exception-on-missing-ResourceKey-value.patch similarity index 73% rename from patches/server/0072-Don-t-throw-exception-on-missing-ResourceKey-value.patch rename to patches/server/0058-Don-t-throw-exception-on-missing-ResourceKey-value.patch index 641d300e..1eb548cf 100644 --- a/patches/server/0072-Don-t-throw-exception-on-missing-ResourceKey-value.patch +++ b/patches/server/0058-Don-t-throw-exception-on-missing-ResourceKey-value.patch @@ -5,18 +5,10 @@ Subject: [PATCH] Don't throw exception on missing ResourceKey value diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java -index 718377ce91a010a48b2b4a5e59e02ee8a42107a7..1160202375d1fd50c5722524a1e0584188cb2080 100644 +index 718377ce91a010a48b2b4a5e59e02ee8a42107a7..2d085f819902d09d26c98e8606ca7ba69ffdcf3c 100644 --- a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java -@@ -4,7 +4,6 @@ import io.leangen.geantyref.TypeToken; - import net.minecraft.core.Registry; - import net.minecraft.core.RegistryAccess; - import net.minecraft.resources.ResourceKey; --import org.spongepowered.configurate.serialize.SerializationException; - - /** - * Use {@link RegistryHolderSerializer} for datapack-configurable things. -@@ -20,10 +19,14 @@ public final class RegistryValueSerializer extends RegistryEntrySerializer extends RegistryEntrySerializer 0 ? split[0] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix, ""); String suffix = (split.length > 1 ? split[1] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, ""); if (afk) { @@ -44,10 +44,10 @@ index 6568b4541a81d52cc81729eb8590cf3723289bac..54e872d7279a56ce1c1ff0310ed302f0 } else { getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 70bf701ae9aea5b6f322db5aa2ae17009d68a807..85eba54ecdcb678eedcfdcc0a484ae2155f2bb15 100644 +index b877dc3f82bdd9640f522e7bd2dc1dbf23610eb1..492de69a877318bad5e49fb57ee461974ad562b6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2264,8 +2264,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2230,8 +2230,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -64,7 +64,8 @@ index 70bf701ae9aea5b6f322db5aa2ae17009d68a807..85eba54ecdcb678eedcfdcc0a484ae21 + long currentTime = System.nanoTime(); + if (cooldown.containsKey(uuid) && (currentTime - cooldown.get(uuid)) / 1000000000 <= org.purpurmc.purpur.PurpurConfig.afkCommandCooldown) { + String msg = org.purpurmc.purpur.PurpurConfig.afkCooldown; -+ if (msg != null && !msg.isEmpty()) player.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(msg.replace("%time%", String.valueOf(org.purpurmc.purpur.PurpurConfig.afkCommandCooldown - (currentTime - cooldown.get(uuid)) / 1000000000)))); ++ if (msg != null && !msg.isEmpty()) ++ player.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(msg.replace("%time%", String.valueOf(org.purpurmc.purpur.PurpurConfig.afkCommandCooldown - (currentTime - cooldown.get(uuid)) / 1000000000)))); + return; + } else { + cooldown.put(uuid, currentTime); @@ -78,11 +79,11 @@ index 70bf701ae9aea5b6f322db5aa2ae17009d68a807..85eba54ecdcb678eedcfdcc0a484ae21 + } + } + // Purpur end - if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) { - this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - } else { + this.tryHandleChat(packet.command(), () -> { + // CraftBukkit start - SPIGOT-7346: Prevent disconnected players from executing commands + if (this.player.hasDisconnected()) { diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index e45c11bf2c42e6d57f803349d8ca6936ac98c995..e6d44744b2a560789cde22a3b4b87eef7874c701 100644 +index 300d5144d828330e3de934b1026a0f1b96496d79..e49f813b4ccb698d9d50c8c827d789d2a5274acf 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -176,9 +176,13 @@ public class PurpurConfig { diff --git a/patches/server/0074-Virtual-Thread-for-async-scheduler.patch b/patches/server/0060-Virtual-Thread-for-async-scheduler.patch similarity index 62% rename from patches/server/0074-Virtual-Thread-for-async-scheduler.patch rename to patches/server/0060-Virtual-Thread-for-async-scheduler.patch index 7bc2d6ed..6adb5c96 100644 --- a/patches/server/0074-Virtual-Thread-for-async-scheduler.patch +++ b/patches/server/0060-Virtual-Thread-for-async-scheduler.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Virtual Thread for async scheduler diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index dcb6ccda0b46dc271be305c93df5c7db574bc07b..a3ef402251b526384b897df82965e769a93ff00b 100644 +index f236e7c56c6c72f3fcdba8314f258026e6561ecb..05b4d0ae35f203a62079cf19285d09d9d355a033 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -385,7 +385,6 @@ public class Main { +@@ -386,7 +386,6 @@ public class Main { tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$1"); tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$2"); tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$3"); @@ -17,38 +17,20 @@ index dcb6ccda0b46dc271be305c93df5c7db574bc07b..a3ef402251b526384b897df82965e769 tryPreloadClass("org.slf4j.helpers.FormattingTuple"); tryPreloadClass("org.slf4j.helpers.BasicMarker"); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..ba7784780a578350992be3e2cfcb9791aa805838 100644 +index 3c1992e212a6d6f1db4d5b807b38d71913619fc0..fe4f1868a5baebceb9ad0520f059ac8c4a68d397 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -@@ -25,30 +25,55 @@ package org.bukkit.craftbukkit.scheduler; - - import com.destroystokyo.paper.ServerSchedulerReportingWrapper; - import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+import org.galemc.gale.virtualthread.VirtualThreadService; - import org.bukkit.plugin.Plugin; - -+import java.lang.reflect.Method; - import java.util.ArrayList; - import java.util.Iterator; - import java.util.List; - import java.util.concurrent.Executor; - import java.util.concurrent.Executors; - import java.util.concurrent.SynchronousQueue; -+import java.util.concurrent.ThreadFactory; - import java.util.concurrent.ThreadPoolExecutor; - import java.util.concurrent.TimeUnit; +@@ -38,17 +38,30 @@ import java.util.concurrent.TimeUnit; public class CraftAsyncScheduler extends CraftScheduler { - private final ThreadPoolExecutor executor = new ThreadPoolExecutor( - 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(), -- new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); // Paper -+ private final Logger LOGGER = LogManager.getLogger(getClass().getName()); // Leaf - Class logger -+ private Executor executor; // Leaf - use super class +- new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); ++ private final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger(getClass().getName()); // Leaf - Class logger ++ private final Executor executor; // Leaf - use super class private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() - .setNameFormat("Craft Async Scheduler Management Thread").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); // Paper + .setNameFormat("Craft Async Scheduler Management Thread").build()); private final List temp = new ArrayList<>(); CraftAsyncScheduler() { @@ -57,16 +39,9 @@ index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..ba7784780a578350992be3e2cfcb9791 - executor.prestartAllCoreThreads(); + + // Leaf start - Ability to use Virtual Thread for async scheduler -+ if (VirtualThreadService.getJavaMajorVersion() >= VirtualThreadService.minimumJavaMajorVersionWithoutFeaturePreview && org.dreeam.leaf.config.modules.opt.VT4BukkitScheduler.enabled) { -+ try { -+ Method newThreadPerTaskExecutor = Executors.class.getMethod("newThreadPerTaskExecutor", ThreadFactory.class); -+ -+ executor = (Executor) newThreadPerTaskExecutor.invoke(null, VirtualThreadService.get().createFactory()); -+ //executor = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("Craft Scheduler Thread - ", 0).factory()); // Leaf - When Minecraft using Java21 -+ return; -+ } catch (Exception ignored) { -+ LOGGER.error("Failed to create Virtual Thread executor! Fallback to default executor."); -+ } ++ if (org.dreeam.leaf.config.modules.opt.VT4BukkitScheduler.enabled) { ++ executor = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("Craft Scheduler Thread - ", 0).factory()); ++ return; + } + + executor = new ThreadPoolExecutor( @@ -77,7 +52,7 @@ index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..ba7784780a578350992be3e2cfcb9791 + + threadPoolExecutor.allowCoreThreadTimeOut(true); + threadPoolExecutor.prestartAllCoreThreads(); -+ // Leaf end ++ // Leaf end - Ability to use Virtual Thread for async scheduler } @Override diff --git a/patches/server/0078-Mirai-Configurable-chat-message-signatures.patch b/patches/server/0061-Mirai-Configurable-chat-message-signatures.patch similarity index 60% rename from patches/server/0078-Mirai-Configurable-chat-message-signatures.patch rename to patches/server/0061-Mirai-Configurable-chat-message-signatures.patch index f5485351..92aa5a9d 100644 --- a/patches/server/0078-Mirai-Configurable-chat-message-signatures.patch +++ b/patches/server/0061-Mirai-Configurable-chat-message-signatures.patch @@ -11,7 +11,7 @@ Original license: GPLv3 Original project: https://github.com/etil2jz/Mirai diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index c5ad3034e8298e345733340d2b6284ef05bb4713..ecee309ae3351b90c4446717f2ae210ef5936b15 100644 +index 8b95af95976309f31eb2493049a6a7440c505608..0d2089fbbb79af51a143621d9ce330b71298f048 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -319,7 +319,7 @@ public final class ChatProcessor { @@ -23,24 +23,11 @@ index c5ad3034e8298e345733340d2b6284ef05bb4713..ecee309ae3351b90c4446717f2ae210e } } -diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatCommandPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatCommandPacket.java -index e62ae57532ddcf12b7ebca77220cb1f3bd603717..b702f707f03cba4f67657a0e7b65b28366b24b50 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatCommandPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatCommandPacket.java -@@ -18,7 +18,7 @@ public record ServerboundChatCommandPacket( - buf.writeUtf(this.command, 256); - buf.writeInstant(this.timeStamp); - buf.writeLong(this.salt); -- this.argumentSignatures.write(buf); -+ if (org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled) this.argumentSignatures.write(buf); // Leaf - Mirai - Configurable chat message signatures - this.lastSeenMessages.write(buf); - } - diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java -index 831178218ddfaa1828c00d0662b251d11bb29ff5..a3718138b956f635faba10e3e38c5285318dd36a 100644 +index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..62d5fb8b89cbcd4e7c1d1d920e12ff36ee5435f3 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java -@@ -18,7 +18,7 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt +@@ -23,7 +23,7 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt buf.writeUtf(this.message, 256); buf.writeInstant(this.timeStamp); buf.writeLong(this.salt); @@ -50,49 +37,44 @@ index 831178218ddfaa1828c00d0662b251d11bb29ff5..a3718138b956f635faba10e3e38c5285 } diff --git a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java -index 5ed4a3a30657ab9e748245ad34333b915e870ae2..866226b083217fef72dfa9b0271ab25ef25e21d8 100644 +index 50dc68a005490415b88780397ef6c26859596dd5..162115048cffc824376e54b7f60ae071719afb57 100644 --- a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java +++ b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java -@@ -22,16 +22,26 @@ public record ServerStatus( +@@ -22,8 +22,11 @@ public record ServerStatus( Optional favicon, boolean enforcesSecureChat ) { + // Leaf start - Mirai - Configurable chat message signatures public static final Codec CODEC = RecordCodecBuilder.create( - instance -> instance.group( -- ComponentSerialization.CODEC.optionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), -- ServerStatus.Players.CODEC.optionalFieldOf("players").forGetter(ServerStatus::players), -- ServerStatus.Version.CODEC.optionalFieldOf("version").forGetter(ServerStatus::version), -- ServerStatus.Favicon.CODEC.optionalFieldOf("favicon").forGetter(ServerStatus::favicon), -- Codec.BOOL.optionalFieldOf("enforcesSecureChat", Boolean.valueOf(false)).forGetter(ServerStatus::enforcesSecureChat) -- ) -- .apply(instance, ServerStatus::new) -+ instance -> -+ !org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled -+ ? instance.group( -+ ComponentSerialization.CODEC.optionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), -+ ServerStatus.Players.CODEC.optionalFieldOf("players").forGetter(ServerStatus::players), -+ ServerStatus.Version.CODEC.optionalFieldOf("version").forGetter(ServerStatus::version), -+ ServerStatus.Favicon.CODEC.optionalFieldOf("favicon").forGetter(ServerStatus::favicon), -+ Codec.BOOL.optionalFieldOf("enforcesSecureChat", Boolean.FALSE).forGetter(x -> true) -+ ).apply(instance, ServerStatus::new) -+ : instance.group( -+ ComponentSerialization.CODEC.optionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), -+ ServerStatus.Players.CODEC.optionalFieldOf("players").forGetter(ServerStatus::players), -+ ServerStatus.Version.CODEC.optionalFieldOf("version").forGetter(ServerStatus::version), -+ ServerStatus.Favicon.CODEC.optionalFieldOf("favicon").forGetter(ServerStatus::favicon), -+ Codec.BOOL.optionalFieldOf("enforcesSecureChat", Boolean.FALSE).forGetter(ServerStatus::enforcesSecureChat) -+ ).apply(instance, ServerStatus::new) ++ instance -> ++ org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled ++ ? instance.group( + ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), + ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(ServerStatus::players), + ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(ServerStatus::version), +@@ -31,7 +34,16 @@ public record ServerStatus( + Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", Boolean.valueOf(false)).forGetter(ServerStatus::enforcesSecureChat) + ) + .apply(instance, ServerStatus::new) ++ : instance.group( ++ ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), ++ ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(ServerStatus::players), ++ ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(ServerStatus::version), ++ ServerStatus.Favicon.CODEC.lenientOptionalFieldOf("favicon").forGetter(ServerStatus::favicon), ++ Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", Boolean.FALSE).forGetter(x -> true) ++ ) ++ .apply(instance, ServerStatus::new) ); -+ // Leaf end- Mirai ++ // Leaf end- Mirai - Configurable chat message signatures public static record Favicon(byte[] iconBytes) { private static final String PREFIX = "data:image/png;base64,"; diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index a83fb872a1d186a3547c12f518e1bb0067fffaf7..fbe299dc0e2d0903075f64f199a498c3e57f07ab 100644 +index a216177a2d02d19e0277085c851d72c878910ca2..e21b5f7d1e6f951865094be7ed824b38d4d3c499 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -681,6 +681,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -702,6 +702,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @Override public boolean enforceSecureProfile() { @@ -100,24 +82,11 @@ index a83fb872a1d186a3547c12f518e1bb0067fffaf7..fbe299dc0e2d0903075f64f199a498c3 DedicatedServerProperties dedicatedserverproperties = this.getProperties(); // Paper start - Add setting for proxy online mode status -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 54e872d7279a56ce1c1ff0310ed302f0012e5d3e..8cea11444cfb711c60ee6af84996c29100541cfa 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2262,7 +2262,7 @@ public class ServerPlayer extends Player { - } - - public void sendServerStatus(ServerStatus metadata) { -- this.connection.send(new ClientboundServerDataPacket(metadata.description(), metadata.favicon().map(ServerStatus.Favicon::iconBytes), metadata.enforcesSecureChat())); -+ if (!org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled) this.connection.send(new ClientboundServerDataPacket(metadata.description(), metadata.favicon().map(ServerStatus.Favicon::iconBytes), true)); else this.connection.send(new ClientboundServerDataPacket(metadata.description(), metadata.favicon().map(ServerStatus.Favicon::iconBytes), metadata.enforcesSecureChat())); // Leaf - Mirai - Configurable chat message signatures - } - - @Override diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 4a6bb425902b780ddfcc505e71d4ff70ff0babb9..dd6fa971c0584fe3b0c7814cfc11850d22a71b18 100644 +index f74f1411384945498823fbdcf9d2e0ce4fc3e8ae..98b081392d6d6fdfced4e25fe68224065ad0910a 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -279,10 +279,29 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -329,10 +329,29 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet) { @@ -125,13 +94,13 @@ index 4a6bb425902b780ddfcc505e71d4ff70ff0babb9..dd6fa971c0584fe3b0c7814cfc11850d + if (!org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket( -+ chat.chatType().resolve(this.player.level().registryAccess()).get().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false); ++ chat.chatType().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false); + + this.send(packet); + return; + } + } -+ // Leaf end - Mirai ++ // Leaf end - Mirai - Configurable chat message signatures this.send(packet, (PacketSendListener) null); } @@ -143,15 +112,15 @@ index 4a6bb425902b780ddfcc505e71d4ff70ff0babb9..dd6fa971c0584fe3b0c7814cfc11850d + return; + } + } -+ // Leaf end - Mirai ++ // Leaf end - Mirai - Configurable chat message signatures // CraftBukkit start if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 25c7f47382f8a9949e2785c36f67dcf455d33f5a..b79c9c983dc960732927bbc13017e7eb028e485b 100644 +index c0d8094d26e1edf3ccee789158cba2e3a2fb8fca..16dba0fe00150ea919deff052b5dc7a2732741c1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1533,7 +1533,7 @@ public abstract class PlayerList { +@@ -1529,7 +1529,7 @@ public abstract class PlayerList { // Paper end boolean flag = this.verifyChatTrusted(message); @@ -160,7 +129,7 @@ index 25c7f47382f8a9949e2785c36f67dcf455d33f5a..b79c9c983dc960732927bbc13017e7eb OutgoingChatMessage outgoingchatmessage = OutgoingChatMessage.create(message); boolean flag1 = false; -@@ -1562,6 +1562,7 @@ public abstract class PlayerList { +@@ -1558,6 +1558,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public diff --git a/patches/server/0079-Block-log4j-rce-exploit-in-chat.patch b/patches/server/0062-Block-log4j-rce-exploit-in-chat.patch similarity index 68% rename from patches/server/0079-Block-log4j-rce-exploit-in-chat.patch rename to patches/server/0062-Block-log4j-rce-exploit-in-chat.patch index 3f76d3c3..5c591f42 100644 --- a/patches/server/0079-Block-log4j-rce-exploit-in-chat.patch +++ b/patches/server/0062-Block-log4j-rce-exploit-in-chat.patch @@ -5,20 +5,19 @@ Subject: [PATCH] Block log4j rce exploit in chat diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 85eba54ecdcb678eedcfdcc0a484ae2155f2bb15..0639def76c50fc9f68a058d781ef86383a01a128 100644 +index 492de69a877318bad5e49fb57ee461974ad562b6..7aa64742d7967a74e4078af168b6b2bac005ccd1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2234,6 +2234,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - return; - } - // CraftBukkit end +@@ -2418,6 +2418,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + } + + private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit ++ if (ServerGamePacketListenerImpl.isLog4jExploit(s)) return; // Leaf - Block log4j rce exploit in chat + -+ if (ServerGamePacketListenerImpl.isLog4jExploit(packet.message())) return; // Leaf - Block log4j rce exploit in chat -+ - if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.message())) { - this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause - } else { -@@ -2409,6 +2412,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { + this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper + } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales +@@ -2449,6 +2451,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -33,12 +32,12 @@ index 85eba54ecdcb678eedcfdcc0a484ae2155f2bb15..0639def76c50fc9f68a058d781ef8638 + public static boolean isChatMessageIllegal(String message) { for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isAllowedChatCharacter(message.charAt(i))) { + if (!StringUtil.isAllowedChatCharacter(message.charAt(i))) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e3c2c3ba19eb04d93d3f5a9a73555bdc64c93b77..dfe42db7ef049c306af5e52eea0ecbf9a23140ca 100644 +index ea784b6c5aeb156147900ad6161c52cc185825dd..f4e916c3f38900576df974269ec5c88648a29eac 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -672,6 +672,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -742,6 +742,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (this.getHandle().connection == null) return; diff --git a/patches/server/0080-Cache-player-profileResult.patch b/patches/server/0063-Cache-player-profileResult.patch similarity index 89% rename from patches/server/0080-Cache-player-profileResult.patch rename to patches/server/0063-Cache-player-profileResult.patch index 329e329e..8a315e88 100644 --- a/patches/server/0080-Cache-player-profileResult.patch +++ b/patches/server/0063-Cache-player-profileResult.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Cache player profileResult diff --git a/build.gradle.kts b/build.gradle.kts -index 78a543150da9e2db42ec8ce07f4fa7528467462d..50ab66f5bf161e23d15949f0aa2416477ad1a98a 100644 +index 7c663d28213322165245c6946c6a73cbc5cbf50b..506bdb19310291ec8770226cdcfbd0e104f5ba7e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -31,6 +31,10 @@ dependencies { +@@ -30,6 +30,10 @@ dependencies { } - // Leaf end + // Leaf end - Legacy config + // Leaf start - Libraries + implementation("com.github.ben-manes.caffeine:caffeine:3.1.8") + // Leaf end + // Paper start - implementation("com.github.luben:zstd-jni:1.5.6-2") // LinearPurpur - implementation("org.lz4:lz4-java:1.8.0") // LinearPurpur + implementation("org.jline:jline-terminal-jansi:3.26.0") // Leaf - Bump Dependencies + implementation("net.minecrell:terminalconsoleappender:1.3.0") diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 0f3ba1abb609562e92dd9eb0ab7a621b8ed2d09f..910c8d2f32370c82c829535d4773fc7283c2e138 100644 +index 1d496b2efc44065e91b4d612e17f38382489e876..d991c875c8f2965ca26e87dc11bba0d347de9c5c 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -1,5 +1,7 @@ @@ -39,7 +39,7 @@ index 0f3ba1abb609562e92dd9eb0ab7a621b8ed2d09f..910c8d2f32370c82c829535d4773fc72 import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nullable; import javax.crypto.SecretKey; -@@ -67,6 +70,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -87,6 +90,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, private ServerPlayer player; // CraftBukkit public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support @@ -49,9 +49,9 @@ index 0f3ba1abb609562e92dd9eb0ab7a621b8ed2d09f..910c8d2f32370c82c829535d4773fc72 + .build(); + // Leaf end - public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection) { + public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection, boolean transferred) { this.state = ServerLoginPacketListenerImpl.State.HELLO; -@@ -272,7 +280,19 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -314,7 +322,19 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, String s1 = (String) Objects.requireNonNull(ServerLoginPacketListenerImpl.this.requestedUsername, "Player name not initialized"); try { diff --git a/patches/server/0081-Prevent-change-non-editable-sign-warning-spam-in-con.patch b/patches/server/0064-Prevent-change-non-editable-sign-warning-spam-in-con.patch similarity index 94% rename from patches/server/0081-Prevent-change-non-editable-sign-warning-spam-in-con.patch rename to patches/server/0064-Prevent-change-non-editable-sign-warning-spam-in-con.patch index 583aa026..ba96428e 100644 --- a/patches/server/0081-Prevent-change-non-editable-sign-warning-spam-in-con.patch +++ b/patches/server/0064-Prevent-change-non-editable-sign-warning-spam-in-con.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent change non-editable sign warning spam in console 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 93764bf849ad8e427bf119f6ff3dbcbcc4c2415e..6116ccf6c5edef3edd19d3c777f18568c4d5ff3e 100644 +index a28be7a332659be655f419d969e0c64e659b6c21..3d3c4a302be6ab681729b44aaa5b68542cd0d117 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 -@@ -188,7 +188,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -189,7 +189,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C this.setAllowedPlayerEditor((UUID) null); this.level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3); } else { diff --git a/patches/server/0082-Matter-Secure-Seed.patch b/patches/server/0065-Matter-Secure-Seed.patch similarity index 85% rename from patches/server/0082-Matter-Secure-Seed.patch rename to patches/server/0065-Matter-Secure-Seed.patch index 92cc5c89..557c0f7b 100644 --- a/patches/server/0082-Matter-Secure-Seed.patch +++ b/patches/server/0065-Matter-Secure-Seed.patch @@ -9,10 +9,10 @@ Original license: GPLv3 Original project: https://github.com/plasmoapp/matter diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index ee22ca05dccba4914d32125586299c1b7433a532..ad3bf1726a9c3b5fb8233bce799b5d4855fe2552 100644 +index 307a7596024528ad194eb01d6468aff1f5fe02cf..c873c85643ce21d7362673af311e9609ad46441b 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -@@ -48,6 +48,10 @@ import org.slf4j.Logger; +@@ -47,6 +47,10 @@ import org.slf4j.Logger; import joptsimple.OptionSet; // CraftBukkit end @@ -23,7 +23,7 @@ index ee22ca05dccba4914d32125586299c1b7433a532..ad3bf1726a9c3b5fb8233bce799b5d48 public class DedicatedServerProperties extends Settings { static final Logger LOGGER = LogUtils.getLogger(); -@@ -164,7 +168,21 @@ public class DedicatedServerProperties extends Settings { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index caef142261734aab264d1da420ff5e6d7117ea1c..e721f40495824dff2ba62c81156b2a8984d2904a 100644 +index e6f6304724ae6acaf94ed9553c90c9650be5c0c6..e0f13719a239a2e06330b03a2e4b8d5715b0ea63 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -47,6 +47,10 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp +@@ -44,6 +44,10 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp import net.minecraft.world.level.storage.DimensionDataStorage; import net.minecraft.world.level.storage.LevelStorageSource; @@ -61,7 +61,7 @@ index caef142261734aab264d1da420ff5e6d7117ea1c..e721f40495824dff2ba62c81156b2a89 public class ServerChunkCache extends ChunkSource { public static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper -@@ -731,6 +735,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -728,6 +732,7 @@ public class ServerChunkCache extends ChunkSource { } public ChunkGenerator getGenerator() { @@ -70,10 +70,10 @@ index caef142261734aab264d1da420ff5e6d7117ea1c..e721f40495824dff2ba62c81156b2a89 } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a5e3b6bee4484f598d7c762dc54bb92c7d0cb2d7..8f8ca4f69c442e30f30838c49917b7b7c81a9c0c 100644 +index aa831bc5ffa44c55da9eea33c72df1d6d68c861a..3baae2d8f55101fe17f43caefe38583b2ebb582c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -177,6 +177,10 @@ import org.bukkit.event.world.GenericGameEvent; +@@ -180,6 +180,10 @@ import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end @@ -84,19 +84,19 @@ index a5e3b6bee4484f598d7c762dc54bb92c7d0cb2d7..8f8ca4f69c442e30f30838c49917b7b7 public class ServerLevel extends Level implements WorldGenLevel { public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0); -@@ -746,6 +750,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -752,6 +756,7 @@ public class ServerLevel extends Level implements WorldGenLevel { chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); } // CraftBukkit end + Globals.setupGlobals(this); // Leaf - Matter - Feature Secure Seed boolean flag2 = minecraftserver.forceSynchronousWrites(); DataFixer datafixer = minecraftserver.getFixerUpper(); - this.entityStorage = new EntityRegionFileStorage(this.getLevel().purpurConfig.regionFormatName, this.getLevel().purpurConfig.regionFormatLinearCompressionLevel, this.getLevel().purpurConfig.linearCrashOnBrokenSymlink, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); // LinearPurpur + this.entityStorage = new EntityRegionFileStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index 0f77f00e9a02d1f982f285617604e7291b70a2a4..101f4845842d5da56551de417858d5313f0e25d8 100644 +index ccf7fea215d3096e76db294daa5874fec00147ca..33092f687246afa733d07b89a12007e33b4c6b3f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -435,7 +435,10 @@ public class Slime extends Mob implements Enemy { +@@ -431,7 +431,10 @@ public class Slime extends Mob implements Enemy { } ChunkPos chunkcoordintpair = new ChunkPos(pos); @@ -109,10 +109,10 @@ index 0f77f00e9a02d1f982f285617604e7291b70a2a4..101f4845842d5da56551de417858d531 // Paper start - Replace rules for Height in Slime Chunks final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum; diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index d0285843920f78e05ce07b1b0b2d8ce97ec8041e..30bf9668b3abb4389a25e0c065ec35e07edca77f 100644 +index 1ac1af72a71bbf402f0d1633a4b8c9a408917d73..ad7c58c9289f4cefce9c3b628970e2bfc08c2bfa 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -54,6 +54,10 @@ import net.minecraft.world.ticks.SerializableTickContainer; +@@ -57,6 +57,10 @@ import net.minecraft.world.ticks.SerializableTickContainer; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -123,7 +123,7 @@ index d0285843920f78e05ce07b1b0b2d8ce97ec8041e..30bf9668b3abb4389a25e0c065ec35e0 public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess { public static final int NO_FILLED_SECTION = -1; -@@ -82,6 +86,11 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -85,6 +89,11 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom protected final LevelHeightAccessor levelHeightAccessor; protected final LevelChunkSection[] sections; @@ -135,7 +135,7 @@ index d0285843920f78e05ce07b1b0b2d8ce97ec8041e..30bf9668b3abb4389a25e0c065ec35e0 // CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading. private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY); -@@ -172,6 +181,17 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -175,6 +184,17 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom return GameEventListenerRegistry.NOOP; } @@ -154,10 +154,10 @@ index d0285843920f78e05ce07b1b0b2d8ce97ec8041e..30bf9668b3abb4389a25e0c065ec35e0 @Nullable public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved); diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 0e54af504001fb94e65bff1c81a8e2e2e6b039c3..d00499d207259af148140a43b245764628e8a5f5 100644 +index 927bdebdb8ae01613f0cea074b3367bd7ffe9ab1..652e471c85cc12e934958103f7ce203aa88d2e4f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -@@ -77,6 +77,11 @@ import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement +@@ -79,6 +79,11 @@ import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import org.apache.commons.lang3.mutable.MutableBoolean; @@ -169,7 +169,7 @@ index 0e54af504001fb94e65bff1c81a8e2e2e6b039c3..d00499d207259af148140a43b2457646 public abstract class ChunkGenerator { public static final Codec CODEC = BuiltInRegistries.CHUNK_GENERATOR.byNameCodec().dispatchStable(ChunkGenerator::codec, Function.identity()); -@@ -339,7 +344,11 @@ public abstract class ChunkGenerator { +@@ -345,7 +350,11 @@ public abstract class ChunkGenerator { return structure.step().ordinal(); })); List list = (List) this.featuresPerStep.get(); @@ -182,7 +182,7 @@ index 0e54af504001fb94e65bff1c81a8e2e2e6b039c3..d00499d207259af148140a43b2457646 long i = seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), blockposition.getX(), blockposition.getZ()); Set> set = new ObjectArraySet(); -@@ -578,9 +587,18 @@ public abstract class ChunkGenerator { +@@ -584,9 +593,18 @@ public abstract class ChunkGenerator { ArrayList arraylist = new ArrayList(list.size()); arraylist.addAll(list); @@ -205,7 +205,7 @@ index 0e54af504001fb94e65bff1c81a8e2e2e6b039c3..d00499d207259af148140a43b2457646 StructureSet.StructureSelectionEntry structureset_a1; diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java -index 798e22fb4d685b5845ebf687e8004e94f13a9751..9462e69f89ac5ef6359111cf6bf6e5e3e6c2390e 100644 +index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..6acf180e65e8a30e71e2c472ce34b63998e5a458 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java @@ -39,6 +39,11 @@ import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStruct @@ -220,63 +220,43 @@ index 798e22fb4d685b5845ebf687e8004e94f13a9751..9462e69f89ac5ef6359111cf6bf6e5e3 public class ChunkGeneratorStructureState { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -224,15 +229,19 @@ public class ChunkGeneratorStructureState { +@@ -224,8 +229,10 @@ public class ChunkGeneratorStructureState { List> list = new ArrayList(j); int k = placement.spread(); HolderSet holderset = placement.preferredBiomes(); - RandomSource randomsource = RandomSource.create(); -- -- // Paper start - Add missing structure set seed configs -- if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { -- randomsource.setSeed(this.conf.strongholdSeed); -- } else { -- // Paper end - Add missing structure set seed configs -- randomsource.setSeed(this.concentricRingsSeed); -- } // Paper - Add missing structure set seed configs + // Leaf start - Matter - Feature Secure Seed + RandomSource randomsource = org.dreeam.leaf.config.modules.misc.SecureSeed.enabled ? new WorldgenCryptoRandom(0, 0, Globals.Salt.STRONGHOLDS, 0) : RandomSource.create(); -+ + + if (!org.dreeam.leaf.config.modules.misc.SecureSeed.enabled) { -+ // Paper start - Add missing structure set seed configs -+ if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { -+ randomsource.setSeed(this.conf.strongholdSeed); -+ } else { -+ // Paper end - Add missing structure set seed configs -+ randomsource.setSeed(this.concentricRingsSeed); -+ } // Paper - Add missing structure set seed configs -+ } -+ // Leaf end - Matter - double d0 = randomsource.nextDouble() * 3.141592653589793D * 2.0D; + // Paper start - Add missing structure set seed configs + if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { + randomsource.setSeed(this.conf.strongholdSeed); +@@ -233,6 +240,7 @@ public class ChunkGeneratorStructureState { + // Paper end - Add missing structure set seed configs + randomsource.setSeed(this.concentricRingsSeed); + } // Paper - Add missing structure set seed configs ++ }// Leaf end - Matter + double d0 = randomsource.nextDouble() * Math.PI * 2.0D; int l = 0; int i1 = 0; -diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -index a907b79fd8291a0e92db138f37239d17424188a1..2f9546e69abedf06f3efbb96cd639bc101254ab9 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -@@ -28,6 +28,10 @@ import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.levelgen.blending.Blender; - import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; - -+// Leaf start - Matter - Feature Secure Seed -+import su.plo.matter.Globals; -+// Leaf end - Matter -+ - public class ChunkStatus { - - // Paper start - rewrite chunk system -@@ -253,6 +257,7 @@ public class ChunkStatus { +diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java +index b81c548c0e1ac53784e9c94b34b65db5f123309c..4d540de21cb35343ef816a6e31cc821d7b121833 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java ++++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java +@@ -231,6 +231,7 @@ public class ChunkStatus { } - public CompletableFuture> generate(Executor executor, ServerLevel world, ChunkGenerator generator, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function>> fullChunkConverter, List chunks) { -+ Globals.setupGlobals(world); // Leaf - Matter - Feature Secure Seed - ChunkAccess ichunkaccess = (ChunkAccess) chunks.get(chunks.size() / 2); - ProfiledDuration profiledduration = JvmProfiler.INSTANCE.onChunkGenerate(ichunkaccess.getPos(), world.dimension(), this.toString()); - + public CompletableFuture generate(WorldGenContext context, Executor executor, ToFullChunk fullChunkConverter, List chunks) { ++ su.plo.matter.Globals.setupGlobals(context.level()); // Leaf - Matter - Feature Secure Seed + ChunkAccess chunkAccess = chunks.get(chunks.size() / 2); + ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onChunkGenerate(chunkAccess.getPos(), context.level().dimension(), this.toString()); + return this.generationTask.doWork(context, this, executor, fullChunkConverter, chunks, chunkAccess).thenApply(chunk -> { diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java -index 147e41c5869ac9070e1cb40f1411490a756dedef..b5212c859a43d0fd0fe0bc1296bccd3520ecede3 100644 +index 5ae04ec610a885e2ed73e942879a27fe8640471c..655627e2a305435cafb3dbcafd237a6bf4199ece 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java +++ b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java -@@ -3,33 +3,60 @@ package net.minecraft.world.level.levelgen; +@@ -3,14 +3,33 @@ package net.minecraft.world.level.levelgen; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -298,28 +278,24 @@ index 147e41c5869ac9070e1cb40f1411490a756dedef..b5212c859a43d0fd0fe0bc1296bccd35 + private static final boolean isSecureSeedEnabled = org.dreeam.leaf.config.modules.misc.SecureSeed.enabled; public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( - instance -> instance.group( -- Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed), -- Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures), -- Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest), -- Codec.STRING.optionalFieldOf("legacy_custom_options").stable().forGetter(generatorOptions -> generatorOptions.legacyCustomOptions) -- ) -- .apply(instance, instance.stable(WorldOptions::new)) -- ); ++ instance -> isSecureSeedEnabled ++ ? instance.group( ++ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed), ++ Codec.LONG_STREAM.fieldOf("feature_seed").stable().forGetter(WorldOptions::featureSeedStream), ++ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures), ++ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest), ++ Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(generatorOptions -> generatorOptions.legacyCustomOptions) ++ ) ++ .apply(instance, instance.stable(WorldOptions::new)) ++ : instance.group( + Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed), + Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures), + Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest), +@@ -18,18 +37,29 @@ public class WorldOptions { + ) + .apply(instance, instance.stable(WorldOptions::new)) + ); - public static final WorldOptions DEMO_OPTIONS = new WorldOptions((long)"North Carolina".hashCode(), true, true); -+ instance -> isSecureSeedEnabled -+ ? instance.group( -+ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed), -+ Codec.LONG_STREAM.fieldOf("feature_seed").stable().forGetter(WorldOptions::featureSeedStream), -+ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures), -+ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest), -+ Codec.STRING.optionalFieldOf("legacy_custom_options").stable().forGetter((generatorOptions) -> generatorOptions.legacyCustomOptions) -+ ).apply(instance, instance.stable(WorldOptions::new)) -+ : instance.group( -+ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed), -+ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures), -+ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest), -+ Codec.STRING.optionalFieldOf("legacy_custom_options").stable().forGetter((generatorOptions) -> generatorOptions.legacyCustomOptions) -+ ).apply(instance, instance.stable(WorldOptions::new))); + // Leaf end - Matter + public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled ? new WorldOptions((long) "North Carolina".hashCode(), Globals.createRandomWorldSeed(), true, true) : new WorldOptions("North Carolina".hashCode(), true, true); // Leaf - Matter - Feature Secure Seed private final long seed; @@ -347,7 +323,7 @@ index 147e41c5869ac9070e1cb40f1411490a756dedef..b5212c859a43d0fd0fe0bc1296bccd35 } private WorldOptions(long seed, boolean generateStructures, boolean bonusChest, Optional legacyCustomOptions) { -@@ -39,10 +66,26 @@ public class WorldOptions { +@@ -39,10 +69,26 @@ public class WorldOptions { this.legacyCustomOptions = legacyCustomOptions; } @@ -374,7 +350,7 @@ index 147e41c5869ac9070e1cb40f1411490a756dedef..b5212c859a43d0fd0fe0bc1296bccd35 public boolean generateStructures() { return this.generateStructures; } -@@ -55,17 +98,19 @@ public class WorldOptions { +@@ -55,17 +101,19 @@ public class WorldOptions { return this.legacyCustomOptions.isPresent(); } @@ -397,7 +373,7 @@ index 147e41c5869ac9070e1cb40f1411490a756dedef..b5212c859a43d0fd0fe0bc1296bccd35 public static OptionalLong parseSeed(String seed) { seed = seed.trim(); -@@ -75,7 +120,7 @@ public class WorldOptions { +@@ -75,7 +123,7 @@ public class WorldOptions { try { return OptionalLong.of(Long.parseLong(seed)); } catch (NumberFormatException var2) { @@ -432,7 +408,7 @@ index 17d2bb3f7d158ec1230a1ad7c52b9feeda586630..2a30f2d4beaa6077a283565211f5c632 List list2 = Lists.newLinkedList(); double d = (double)k / (double)geodeConfiguration.outerWallDistance.getMaxValue(); diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java -index e1fcc71b81c9da7180384ea1dfc656fdecf900c7..5fe14ff7c05f91b8f00fbdfd02909f4404860369 100644 +index 4d7398cbe2c400791e6598c9924202a454cb56ce..171118ccf3933aff7765687e5e6d5f6bac7f82e8 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java @@ -39,6 +39,11 @@ import net.minecraft.world.level.levelgen.structure.pieces.PiecesContainer; @@ -447,7 +423,7 @@ index e1fcc71b81c9da7180384ea1dfc656fdecf900c7..5fe14ff7c05f91b8f00fbdfd02909f44 public abstract class Structure { public static final Codec DIRECT_CODEC = BuiltInRegistries.STRUCTURE_TYPE.byNameCodec().dispatch(Structure::type, StructureType::codec); public static final Codec> CODEC = RegistryFileCodec.create(Registries.STRUCTURE, DIRECT_CODEC); -@@ -228,6 +233,14 @@ public abstract class Structure { +@@ -233,6 +238,14 @@ public abstract class Structure { } private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) { @@ -463,7 +439,7 @@ index e1fcc71b81c9da7180384ea1dfc656fdecf900c7..5fe14ff7c05f91b8f00fbdfd02909f44 worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z); return worldgenRandom; diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java -index e6136d68111f47e2495de81713043865fffc864a..e78f2dd555ac90464bd03a809afd285d1dc35eae 100644 +index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..3a24937a6e6f47e372a05ebb359312591e3d85aa 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java @@ -11,6 +11,11 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; @@ -476,9 +452,9 @@ index e6136d68111f47e2495de81713043865fffc864a..e78f2dd555ac90464bd03a809afd285d +// Leaf end - Matter + public class RandomSpreadStructurePlacement extends StructurePlacement { - public static final Codec CODEC = ExtraCodecs.validate( - RecordCodecBuilder.mapCodec( -@@ -74,8 +79,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + instance -> placementCodec(instance) +@@ -71,8 +76,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement { public ChunkPos getPotentialStructureChunk(long seed, int chunkX, int chunkZ) { int i = Math.floorDiv(chunkX, this.spacing); int j = Math.floorDiv(chunkZ, this.spacing); @@ -499,7 +475,7 @@ index e6136d68111f47e2495de81713043865fffc864a..e78f2dd555ac90464bd03a809afd285d int l = this.spreadType.evaluate(worldgenRandom, k); int m = this.spreadType.evaluate(worldgenRandom, k); diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java -index c154b3213864f697cc679e2ecdd3b31a97113542..b75a636d3d88e355877872ef697a7d6dbcbdaeec 100644 +index cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a..7bbb31678b889ee210a396635d644bbfb6a269dc 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java @@ -20,6 +20,11 @@ import net.minecraft.world.level.levelgen.LegacyRandomSource; @@ -565,7 +541,7 @@ index 70dbf7267b43357578c07fcd46618f656410a8e2..c7d9359af6be9efa19dd1e27e36f3074 Rotation rotation = Rotation.getRandom(worldgenRandom); StructureTemplatePool structureTemplatePool = structurePool.unwrapKey() diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/structures/EndCityStructure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/structures/EndCityStructure.java -index ffc8242c31bf18ef2f33f2b7ecb99f0a896ea730..5eb4cd3dfa593a9b8a368c820e395983b43df270 100644 +index 712c6431d63e0b1a1edd9d7de9b13c46a1acb469..35dc49d90aa6d660a60fb76efddb530f9ec59666 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/structures/EndCityStructure.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/structures/EndCityStructure.java @@ -10,6 +10,7 @@ import net.minecraft.world.level.levelgen.structure.Structure; @@ -575,21 +551,21 @@ index ffc8242c31bf18ef2f33f2b7ecb99f0a896ea730..5eb4cd3dfa593a9b8a368c820e395983 +//import su.plo.matter.WorldgenCryptoRandom; // Leaf - Matter - Feature Secure Seed public class EndCityStructure extends Structure { - public static final Codec CODEC = simpleCodec(EndCityStructure::new); + public static final MapCodec CODEC = simpleCodec(EndCityStructure::new); diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/structures/MineshaftStructure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/structures/MineshaftStructure.java -index 944b5ff23ccf8e9c93db142a7cbeb29dc0b021da..dbda2a51b88f1c7c58d662a28e55bdcb913cb2dc 100644 +index 7f4c5e9355a6f562f668e9b8134bfe65dde35f90..7a1c21696f6531c7dded774f45073df16732f252 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/structures/MineshaftStructure.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/structures/MineshaftStructure.java -@@ -19,6 +19,7 @@ import net.minecraft.world.level.levelgen.WorldgenRandom; +@@ -20,6 +20,7 @@ import net.minecraft.world.level.levelgen.WorldgenRandom; import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.StructureType; import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; +//import su.plo.matter.WorldgenCryptoRandom; // Leaf - Matter - Feature Secure Seed public class MineshaftStructure extends Structure { - public static final Codec CODEC = RecordCodecBuilder.create( + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index dca5f25cf331b5550e9be491b4e8a3466531e021..4882361460d934d0c1ff693325f59c10341c5f5d 100644 +index 82b4bd669c57b18fb0b443bcd94495023cd5a528..2d336a8bb12e9e41b717caf883d39de146ea32d3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -202,7 +202,10 @@ public class CraftChunk implements Chunk { @@ -605,10 +581,10 @@ index dca5f25cf331b5550e9be491b4e8a3466531e021..4882361460d934d0c1ff693325f59c10 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index c7faba7ff1101f68fef4a67c502e45a66ec77b93..15c3d62262a589844dbaa8ac357402aa592cd351 100644 +index 25cbef3e87fd9924a86b019355df922eaf3773e1..cbe7e050d0651d06fdc6a08331142914b8c49920 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -268,6 +268,10 @@ import net.md_5.bungee.api.chat.BaseComponent; // Spigot +@@ -270,6 +270,10 @@ import net.md_5.bungee.api.chat.BaseComponent; // Spigot import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper @@ -620,7 +596,7 @@ index c7faba7ff1101f68fef4a67c502e45a66ec77b93..15c3d62262a589844dbaa8ac357402aa private final String serverName = "Leaf"; // Paper // Gale - branding changes // Leaf private final String serverVersion; @@ -1374,7 +1378,7 @@ public final class CraftServer implements Server { - iregistry = leveldataanddimensions.dimensions().dimensions(); + iregistrycustom_dimension = leveldataanddimensions.dimensions().dimensionsRegistryAccess(); } else { LevelSettings worldsettings; - WorldOptions worldoptions = new WorldOptions(creator.seed(), creator.generateStructures(), false); diff --git a/patches/server/0083-Matter-Seed-Command.patch b/patches/server/0066-Matter-Seed-Command.patch similarity index 100% rename from patches/server/0083-Matter-Seed-Command.patch rename to patches/server/0066-Matter-Seed-Command.patch diff --git a/patches/server/0029-Leaves-Protocol-Core.patch b/patches/unapplied/server/0030-Leaves-Protocol-Core.patch similarity index 92% rename from patches/server/0029-Leaves-Protocol-Core.patch rename to patches/unapplied/server/0030-Leaves-Protocol-Core.patch index 77a48090..53cbf302 100644 --- a/patches/server/0029-Leaves-Protocol-Core.patch +++ b/patches/unapplied/server/0030-Leaves-Protocol-Core.patch @@ -8,29 +8,29 @@ TODO - Dreeam: Configurable leaves protocol listening Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves -diff --git a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java -index af86f752c33a2990405fea058b7c41c437ba9d46..bada9fae1e7178162429e1f5a1608b9c4a680a6c 100644 ---- a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java -@@ -20,7 +20,12 @@ public record ServerboundCustomPayloadPacket(CustomPacketPayload payload) implem +diff --git a/src/main/java/net/minecraft/network/protocol/login/ClientboundCustomQueryPacket.java b/src/main/java/net/minecraft/network/protocol/login/ClientboundCustomQueryPacket.java +index 1789c0c71d968b386060bd6dc2630e8a078c32e2..b83148a78306333949ac354311400bb971c212b5 100644 +--- a/src/main/java/net/minecraft/network/protocol/login/ClientboundCustomQueryPacket.java ++++ b/src/main/java/net/minecraft/network/protocol/login/ClientboundCustomQueryPacket.java +@@ -19,6 +19,13 @@ public record ClientboundCustomQueryPacket(int transactionId, CustomQueryPayload + } - private static CustomPacketPayload readPayload(ResourceLocation id, FriendlyByteBuf buf) { - FriendlyByteBuf.Reader packetdataserializer_a = (FriendlyByteBuf.Reader) ServerboundCustomPayloadPacket.KNOWN_TYPES.get(id); -- + private static CustomQueryPayload readPayload(ResourceLocation id, FriendlyByteBuf buf) { + // Leaves start - protocol -+ CustomPacketPayload leavesPayload = top.leavesmc.leaves.protocol.core.LeavesProtocolManager.getPayload(id, buf); ++ CustomQueryPayload leavesPayload = (CustomQueryPayload) top.leavesmc.leaves.protocol.core.LeavesProtocolManager.getPayload(id, buf); + if (leavesPayload != null) { + return leavesPayload; + } + // Leaves end - protocol - return (CustomPacketPayload) (packetdataserializer_a != null ? (CustomPacketPayload) packetdataserializer_a.apply(buf) : readUnknownPayload(id, buf)); ++ + return readUnknownPayload(id, buf); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 49105918ec09e9c9db49035fc03a6502bb4a951f..eb8e2c9401c79b106f206bd4ae76aca5ae9ae4bb 100644 +index 10e3eb23c00b2af646f198f789129814beb656b1..f5f69df14049716aab0856ed9b7041dc80d6ee31 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1721,6 +1721,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop detectedPlayers = new HashSet<>(); - protected final Set currentMobs = new HashSet<>(); +@@ -68,7 +68,7 @@ public class TrialSpawnerData { + }); + public final Set detectedPlayers; + public final Set currentMobs; - protected long cooldownEndsAt; + public long cooldownEndsAt; // Leaves - protected -> public protected long nextMobSpawnsAt; protected int totalMobsSpawned; - protected Optional nextSpawnData; + public Optional nextSpawnData; diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..b63d87d0593d116b0c5ee835dc4372f1b5542453 diff --git a/patches/server/0031-Leaves-Appleskin-Protocol.patch b/patches/unapplied/server/0032-Leaves-Appleskin-Protocol.patch similarity index 100% rename from patches/server/0031-Leaves-Appleskin-Protocol.patch rename to patches/unapplied/server/0032-Leaves-Appleskin-Protocol.patch diff --git a/patches/server/0032-Leaves-Xaero-Map-Protocol.patch b/patches/unapplied/server/0033-Leaves-Xaero-Map-Protocol.patch similarity index 96% rename from patches/server/0032-Leaves-Xaero-Map-Protocol.patch rename to patches/unapplied/server/0033-Leaves-Xaero-Map-Protocol.patch index 495345e7..cdff1700 100644 --- a/patches/server/0032-Leaves-Xaero-Map-Protocol.patch +++ b/patches/unapplied/server/0033-Leaves-Xaero-Map-Protocol.patch @@ -9,10 +9,10 @@ Original project: https://github.com/LeavesMC/Leaves This patch is Powered by Xaero Map diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 9a3dbd337728374e3adb1071769f7824c2698fe3..e960528f7e261552b3936e596d0ff9c285a151ca 100644 +index 1be9b74bc028ea835aaf4ceb70e8619a02aa9725..9e93de5fa378b1625679595771ce18c3ab9628a2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1376,6 +1376,7 @@ public abstract class PlayerList { +@@ -1375,6 +1375,7 @@ public abstract class PlayerList { player.connection.send(new ClientboundInitializeBorderPacket(worldborder)); player.connection.send(new ClientboundSetTimePacket(world.getGameTime(), world.getDayTime(), world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSharedSpawnPos(), world.getSharedSpawnAngle())); diff --git a/patches/server/0033-Leaves-Syncmatica-Protocol.patch b/patches/unapplied/server/0034-Leaves-Syncmatica-Protocol.patch similarity index 99% rename from patches/server/0033-Leaves-Syncmatica-Protocol.patch rename to patches/unapplied/server/0034-Leaves-Syncmatica-Protocol.patch index fb2b66f8..565e85c5 100644 --- a/patches/server/0033-Leaves-Syncmatica-Protocol.patch +++ b/patches/unapplied/server/0034-Leaves-Syncmatica-Protocol.patch @@ -9,18 +9,18 @@ Original project: https://github.com/LeavesMC/Leaves This patch is Powered by Syncmatica (https://github.com/End-Tech/syncmatica) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8895e7d35af8650503853b6fc7432f66e4f333db..451095afa88a2d89d33658042e9a62ef14547cc7 100644 +index f0886b4b63adb17ffe73b60f6ff6bdb734a4e8cf..b528172abb36edb31bc69043b03371651aa32eaa 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -310,6 +310,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -318,6 +318,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Objects.requireNonNull(server); this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(uuid, server::enforceSecureProfile); this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat + this.exchangeTarget = new top.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol } - // CraftBukkit start - add fields -@@ -349,6 +350,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + // CraftBukkit start - add fields and methods +@@ -350,6 +351,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ); // Purpur end diff --git a/patches/server/0046-Faster-Random-for-xaeroMapServerID-generation.patch b/patches/unapplied/server/0044-Faster-Random-for-xaeroMapServerID-generation.patch similarity index 100% rename from patches/server/0046-Faster-Random-for-xaeroMapServerID-generation.patch rename to patches/unapplied/server/0044-Faster-Random-for-xaeroMapServerID-generation.patch diff --git a/patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch b/patches/unapplied/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch similarity index 100% rename from patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch rename to patches/unapplied/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch diff --git a/patches/server/0076-Chat-Image-protocol.patch b/patches/unapplied/server/0067-Chat-Image-protocol.patch similarity index 100% rename from patches/server/0076-Chat-Image-protocol.patch rename to patches/unapplied/server/0067-Chat-Image-protocol.patch diff --git a/patches/server/0077-Asteor-Bar-protocol.patch b/patches/unapplied/server/0068-Asteor-Bar-protocol.patch similarity index 100% rename from patches/server/0077-Asteor-Bar-protocol.patch rename to patches/unapplied/server/0068-Asteor-Bar-protocol.patch