From 6a4b8c8003bbd6f8f1fb804230a9f164b6d006b5 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Fri, 25 Aug 2023 05:21:18 -0400 Subject: [PATCH] Updated Upstream (Purpur) --- patches/api/0002-Purpur-API-Changes.patch | 2 +- patches/server/0009-Purpur-Base.patch | 100 ---- ...patch => 0009-Purpur-Server-Changes.patch} | 528 ++++++++++++------ ...Purpur-Configurable-server-mod-name.patch} | 4 +- ...ies.patch => 0011-Bump-Dependencies.patch} | 0 ...> 0012-Remove-Mojang-username-check.patch} | 2 +- ...ck-for-Broken-BungeeCord-Configurat.patch} | 0 ...emove-UseItemOnPacket-Too-Far-Check.patch} | 0 ... 0015-KTP-Optimize-spigot-event-bus.patch} | 0 ...patch => 0016-KeYi-Player-Skull-API.patch} | 0 ...le-arrow-despawn-counter-by-default.patch} | 0 ...n-for-spigot-item-merging-mechanism.patch} | 0 ...pet-Fixes-Optimized-getBiome-method.patch} | 0 ...t-Fixes-Use-optimized-RecipeManager.patch} | 0 ...karin-Save-Json-list-asynchronously.patch} | 0 ...atch => 0022-Slice-Smooth-Teleports.patch} | 2 +- ...chment-Make-FixLight-use-action-bar.patch} | 0 ...s.patch => 0024-Leaves-Server-Utils.patch} | 0 ....patch => 0025-Leaves-Jade-Protocol.patch} | 0 ...h => 0026-Leaves-Appleskin-Protocol.patch} | 0 ...h => 0027-Leaves-Xaero-Map-Protocol.patch} | 0 ...og4j-compatible-with-future-release.patch} | 0 ...ror.patch => 0029-Fix-compile-error.patch} | 0 ...Optimize-villager-data-storage.patc.patch} | 0 ...031-Revert-Purpur-Fire-Immunity-API.patch} | 0 ...ch => 0032-Petal-Reduce-sensor-work.patch} | 0 ...tch => 0033-Petal-Async-Pathfinding.patch} | 0 ...=> 0034-Petal-Multithreaded-Tracker.patch} | 0 ...l-Sync-event-calls-on-async-threads.patch} | 0 ...r-NPE.patch => 0036-Fix-tracker-NPE.patch} | 0 ...he-minecart-vehicle-collide-results.patch} | 0 31 files changed, 376 insertions(+), 262 deletions(-) delete mode 100644 patches/server/0009-Purpur-Base.patch rename patches/server/{0010-Purpur-Server-Changes.patch => 0009-Purpur-Server-Changes.patch} (98%) rename patches/server/{0011-Purpur-Configurable-server-mod-name.patch => 0010-Purpur-Configurable-server-mod-name.patch} (94%) rename patches/server/{0012-Bump-Dependencies.patch => 0011-Bump-Dependencies.patch} (100%) rename patches/server/{0013-Remove-Mojang-username-check.patch => 0012-Remove-Mojang-username-check.patch} (96%) rename patches/server/{0014-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch => 0013-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch} (100%) rename patches/server/{0015-Remove-UseItemOnPacket-Too-Far-Check.patch => 0014-Remove-UseItemOnPacket-Too-Far-Check.patch} (100%) rename patches/server/{0016-KTP-Optimize-spigot-event-bus.patch => 0015-KTP-Optimize-spigot-event-bus.patch} (100%) rename patches/server/{0017-KeYi-Player-Skull-API.patch => 0016-KeYi-Player-Skull-API.patch} (100%) rename patches/server/{0018-KeYi-Disable-arrow-despawn-counter-by-default.patch => 0017-KeYi-Disable-arrow-despawn-counter-by-default.patch} (100%) rename patches/server/{0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch => 0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch} (100%) rename patches/server/{0020-Carpet-Fixes-Optimized-getBiome-method.patch => 0019-Carpet-Fixes-Optimized-getBiome-method.patch} (100%) rename patches/server/{0021-Carpet-Fixes-Use-optimized-RecipeManager.patch => 0020-Carpet-Fixes-Use-optimized-RecipeManager.patch} (100%) rename patches/server/{0022-Akarin-Save-Json-list-asynchronously.patch => 0021-Akarin-Save-Json-list-asynchronously.patch} (100%) rename patches/server/{0023-Slice-Smooth-Teleports.patch => 0022-Slice-Smooth-Teleports.patch} (97%) rename patches/server/{0024-Parchment-Make-FixLight-use-action-bar.patch => 0023-Parchment-Make-FixLight-use-action-bar.patch} (100%) rename patches/server/{0025-Leaves-Server-Utils.patch => 0024-Leaves-Server-Utils.patch} (100%) rename patches/server/{0026-Leaves-Jade-Protocol.patch => 0025-Leaves-Jade-Protocol.patch} (100%) rename patches/server/{0027-Leaves-Appleskin-Protocol.patch => 0026-Leaves-Appleskin-Protocol.patch} (100%) rename patches/server/{0028-Leaves-Xaero-Map-Protocol.patch => 0027-Leaves-Xaero-Map-Protocol.patch} (100%) rename patches/server/{0029-Fix-Make-log4j-compatible-with-future-release.patch => 0028-Fix-Make-log4j-compatible-with-future-release.patch} (100%) rename patches/server/{0030-Fix-compile-error.patch => 0029-Fix-compile-error.patch} (100%) rename patches/server/{0031-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch => 0030-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch} (100%) rename patches/server/{0032-Revert-Purpur-Fire-Immunity-API.patch => 0031-Revert-Purpur-Fire-Immunity-API.patch} (100%) rename patches/server/{0033-Petal-Reduce-sensor-work.patch => 0032-Petal-Reduce-sensor-work.patch} (100%) rename patches/server/{0034-Petal-Async-Pathfinding.patch => 0033-Petal-Async-Pathfinding.patch} (100%) rename patches/server/{0035-Petal-Multithreaded-Tracker.patch => 0034-Petal-Multithreaded-Tracker.patch} (100%) rename patches/server/{0036-Petal-Sync-event-calls-on-async-threads.patch => 0035-Petal-Sync-event-calls-on-async-threads.patch} (100%) rename patches/server/{0037-Fix-tracker-NPE.patch => 0036-Fix-tracker-NPE.patch} (100%) rename patches/server/{0038-Cache-minecart-vehicle-collide-results.patch => 0037-Cache-minecart-vehicle-collide-results.patch} (100%) diff --git a/patches/api/0002-Purpur-API-Changes.patch b/patches/api/0002-Purpur-API-Changes.patch index fe823be0..e25159ca 100644 --- a/patches/api/0002-Purpur-API-Changes.patch +++ b/patches/api/0002-Purpur-API-Changes.patch @@ -3,7 +3,7 @@ From: Github Actions Date: Fri, 16 Jun 2023 05:21:52 +0000 Subject: [PATCH] Purpur API Changes -Commit: a2e96448a0e4688585b5e7dee39caa90bfe48cdb +Commit: 8ef1580b1f5a1cd8dbd624b65fd4a8920ce52287 Patches below are removed in this patch: Build-System-Changes.patch diff --git a/patches/server/0009-Purpur-Base.patch b/patches/server/0009-Purpur-Base.patch deleted file mode 100644 index 509637d4..00000000 --- a/patches/server/0009-Purpur-Base.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Github Actions -Date: Wed, 24 May 2023 06:00:03 +0800 -Subject: [PATCH] Purpur Base - -Commit: a2e96448a0e4688585b5e7dee39caa90bfe48cdb - -Original license: MIT -Original project: https://github.com/PurpurMC/Purpur - -diff --git a/build.gradle.kts b/build.gradle.kts -index d297578fe5990eb7ff55d995ec30525bf8776a52..1d6f67588aaf8ec22190f344bb9c7dea84b7e9e7 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -54,6 +54,10 @@ dependencies { - } - // Paper end - -+ implementation("org.mozilla:rhino-runtime:1.7.14") // Purpur -+ implementation("org.mozilla:rhino-engine:1.7.14") // Purpur -+ implementation("dev.omega24:upnp4j:1.0") // Purpur -+ - runtimeOnly("org.apache.maven:maven-resolver-provider:3.8.5") - runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") - runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") -@@ -182,7 +186,7 @@ fun TaskContainer.registerRunTask( - } - } - // Gale end - use default Java installation for development runs -- group = "paper" -+ group = "paperweight" // Purpur - mainClass.set("org.bukkit.craftbukkit.Main") - standardInput = System.`in` - workingDir = rootProject.layout.projectDirectory -diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java -index 4e56018b64d11f76c8da43fd8f85c6de72204e36..aa8212432825db65cf485cd93f734ccd9eefcb5a 100644 ---- a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java -+++ b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java -@@ -21,7 +21,12 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co - - @Override - public void sendMessage(String message) { -- this.sendRawMessage(message); -+ // Purpur start -+ String[] parts = message.split("\n"); -+ for (String part : parts) { -+ this.sendRawMessage(part); -+ } -+ // Purpur end - } - - @Override -@@ -91,7 +96,7 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co - // Paper start - @Override - public void sendMessage(final net.kyori.adventure.identity.Identity identity, final net.kyori.adventure.text.Component message, final net.kyori.adventure.audience.MessageType type) { -- this.sendRawMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message)); -+ this.sendMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message)); // Purpur - } - - @Override -diff --git a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java -index d55adec004fd733859a75b34ce54e1f10b7336fc..5fdb227acfd1d8f55b770c8a66e97494c36db33c 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 ? Component.textOfChildren(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 -@@ -174,6 +174,6 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { - return null; - } - -- return Component.text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); -+ return org.bukkit.ChatColor.parseMM("Previous: %s", oldVersion); // Purpur - } - } diff --git a/patches/server/0010-Purpur-Server-Changes.patch b/patches/server/0009-Purpur-Server-Changes.patch similarity index 98% rename from patches/server/0010-Purpur-Server-Changes.patch rename to patches/server/0009-Purpur-Server-Changes.patch index 8f993602..cbb9e1c0 100644 --- a/patches/server/0010-Purpur-Server-Changes.patch +++ b/patches/server/0009-Purpur-Server-Changes.patch @@ -1,9 +1,9 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Github Actions -Date: Fri, 16 Jun 2023 05:22:02 +0000 +Date: Wed, 24 May 2023 06:00:03 +0800 Subject: [PATCH] Purpur Server Changes -Commit: a2e96448a0e4688585b5e7dee39caa90bfe48cdb +Commit: 8ef1580b1f5a1cd8dbd624b65fd4a8920ce52287 Patches below are removed in this patch: MC-238526-Fix-spawner-not-spawning-water-animals-cor.patch @@ -28,6 +28,30 @@ Halloween-options-and-optimizations.patch Original license: MIT Original project: https://github.com/PurpurMC/Purpur +diff --git a/build.gradle.kts b/build.gradle.kts +index 6cdadedb459eacf4a84c0b846399eb06a48a7b7f..15ac7e418105f9c6780b28055edfba888156ed42 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -54,6 +54,10 @@ dependencies { + } + // Paper end + ++ implementation("org.mozilla:rhino-runtime:1.7.14") // Purpur ++ implementation("org.mozilla:rhino-engine:1.7.14") // Purpur ++ implementation("dev.omega24:upnp4j:1.0") // Purpur ++ + runtimeOnly("org.apache.maven:maven-resolver-provider:3.8.5") + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") +@@ -182,7 +186,7 @@ fun TaskContainer.registerRunTask( + } + } + // Gale end - use default Java installation for development runs +- group = "paper" ++ group = "paperweight" // Purpur + mainClass.set("org.bukkit.craftbukkit.Main") + standardInput = System.`in` + workingDir = rootProject.layout.projectDirectory diff --git a/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java b/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..6b8b8af398577d4f79e1b1d8a9999a7586b166d5 @@ -1202,7 +1226,7 @@ index 5d6c0f5d2d993ae3a044a1a02716a2662e9080d0..b77a84a5ab85839e37aee24da0f4356b } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b750ea3db1b 100644 +index c97a719033ef075f2cc29f6e4e5327db12e24b8d..208165326d19d8a9e8c985ca7762f27f74bdc21e 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -279,6 +279,11 @@ public class ServerPlayer extends Player { @@ -1326,7 +1350,28 @@ index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b75 return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1531,6 +1571,7 @@ public class ServerPlayer extends Player { +@@ -1434,7 +1474,19 @@ public class ServerPlayer extends Player { + }); + + if (!this.serverLevel().canSleepThroughNights()) { +- this.displayClientMessage(Component.translatable("sleep.not_possible"), true); ++ // Purpur start ++ Component clientMessage; ++ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) { ++ clientMessage = null; ++ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) { ++ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible)); ++ } else { ++ clientMessage = Component.translatable("sleep.not_possible"); ++ } ++ if (clientMessage != null) { ++ this.displayClientMessage(clientMessage, true); ++ } ++ // Purpur end + } + + ((ServerLevel) this.level()).updateSleepingPlayerList(); +@@ -1531,6 +1583,7 @@ public class ServerPlayer extends Player { @Override public void openTextEdit(SignBlockEntity sign, boolean front) { @@ -1334,7 +1379,7 @@ index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b75 this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); } -@@ -1771,6 +1812,26 @@ public class ServerPlayer extends Player { +@@ -1771,6 +1824,26 @@ public class ServerPlayer extends Player { this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -1361,7 +1406,7 @@ index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b75 @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2076,6 +2137,7 @@ public class ServerPlayer extends Player { +@@ -2076,6 +2149,7 @@ public class ServerPlayer extends Player { } public void sendTexturePack(String url, String hash, boolean required, @Nullable Component resourcePackPrompt) { @@ -1369,7 +1414,7 @@ index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b75 this.connection.send(new ClientboundResourcePackPacket(url, hash, required, resourcePackPrompt)); } -@@ -2090,8 +2152,68 @@ public class ServerPlayer extends Player { +@@ -2090,8 +2164,68 @@ public class ServerPlayer extends Player { public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -1438,25 +1483,26 @@ index c97a719033ef075f2cc29f6e4e5327db12e24b8d..ac12549e49f824aded913eb131117b75 public ServerStatsCounter getStats() { return this.stats; } -@@ -2603,8 +2725,16 @@ public class ServerPlayer extends Player { +@@ -2603,9 +2737,17 @@ public class ServerPlayer extends Player { @Override public boolean isImmobile() { - return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper + return super.isImmobile() || frozen || (this.connection != null && this.connection.isDisconnected()); // Paper // Purpur -+ } -+ + } + + // Purpur start + private boolean frozen = false; + + public void setFrozen(boolean frozen) { + this.frozen = frozen; - } ++ } + // Purpur end - ++ @Override public Scoreboard getScoreboard() { -@@ -2653,4 +2783,50 @@ public class ServerPlayer extends Player { + return this.getBukkitEntity().getScoreboard().getHandle(); +@@ -2653,4 +2795,50 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -2021,9 +2067,18 @@ 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 c12d7bacf2c54f268b1bc5e46250a083ca041415..45e4717ba832edceeafdba575323c2527c350193 100644 +index c12d7bacf2c54f268b1bc5e46250a083ca041415..45a1cbe958c1a626df97022afe22484f2b387233 100644 --- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java +++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java +@@ -59,7 +59,7 @@ public class CombatTracker { + } + + ItemStack itemStack = var10000; +- return !itemStack.isEmpty() && itemStack.hasCustomHoverName() ? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName()) : Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName); ++ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.hasCustomHoverName()) ? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName()) : Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName); + } + + private Component getFallMessage(CombatEntry damageRecord, @Nullable Entity attacker) { @@ -99,6 +99,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); @@ -2039,7 +2094,7 @@ index c12d7bacf2c54f268b1bc5e46250a083ca041415..45e4717ba832edceeafdba575323c252 } } diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -index 25a5a3b949a0eb632611355e74ccd4865be108ca..d728712e8024480d336640a6801c1abb272adc13 100644 +index 25a5a3b949a0eb632611355e74ccd4865be108ca..88dc6e2cd7262f2f6d3308599fcada6be3d2d4f9 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java @@ -54,6 +54,9 @@ public class DamageSource { @@ -2052,7 +2107,12 @@ index 25a5a3b949a0eb632611355e74ccd4865be108ca..d728712e8024480d336640a6801c1abb public String toString() { return "DamageSource (" + this.type().msgId() + ")"; } -@@ -126,6 +129,15 @@ public class DamageSource { +@@ -122,10 +125,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); } } @@ -12241,6 +12301,46 @@ index f041a2b6b330692316e7c5385651d9370377d5e0..1bac25a9b4dd682d942ba5fce4cffb30 } 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 d98c526676202741e628d5e317b8cdd3f4d3be0a..edf9208ed49a179dc15308dd72ee47367c0a9ded 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java ++++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +@@ -597,20 +597,33 @@ public class PiglinAi { + 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 + + 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 + + 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); ++ ++ 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); ++ } ++ // Purpur end ++ + private static void stopWalking(Piglin piglin) { + 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 5aab051998b67b7ba95cbf568de60e325b905eab..1805d4e15328fa99595641ea64fc2e3e659c555e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java @@ -13458,7 +13558,7 @@ index 35b41bceeba72c3896c91c2605bac3b0bf9c54e9..5c028f957661089ff502109c99669285 } else if (this.isFuel(itemstack1)) { if (!this.moveItemStackTo(itemstack1, 1, 2, false)) { diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..cb4a1cd39f12d90d30dd95efa2de58f57d9c6ee0 100644 +index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..531b911c1bcdd3735529ee18f2bb0ccdf4ad6089 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; @@ -13524,12 +13624,16 @@ index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..cb4a1cd39f12d90d30dd95efa2de58f5 if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { flag3 = true; -@@ -222,16 +241,16 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -222,16 +241,20 @@ public class AnvilMenu extends ItemCombinerMenu { Enchantment enchantment1 = (Enchantment) 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 (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { ++ iterator1.remove(); ++ flag4 = true; ++ } ++i; } } @@ -13544,7 +13648,7 @@ index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..cb4a1cd39f12d90d30dd95efa2de58f5 i2 = enchantment.getMaxLevel(); } -@@ -276,6 +295,54 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -276,6 +299,54 @@ public class AnvilMenu extends ItemCombinerMenu { if (!this.itemName.equals(itemstack.getHoverName().getString())) { b1 = 1; i += b1; @@ -13599,7 +13703,7 @@ index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..cb4a1cd39f12d90d30dd95efa2de58f5 itemstack1.setHoverName(Component.literal(this.itemName)); } } else if (itemstack.hasCustomHoverName()) { -@@ -293,6 +360,13 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -293,6 +364,13 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } @@ -13613,7 +13717,7 @@ index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..cb4a1cd39f12d90d30dd95efa2de58f5 if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } -@@ -315,11 +389,17 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -315,11 +393,17 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); @@ -14166,6 +14270,19 @@ index 58cb992c5defec2f092755cbde661ff10f38bf9d..52f48681407d23f0925f4c9c072d5f0a // Paper start 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 0ebfa82de86cc08aa9f865e7807552bba4d3dd21..d23a75348204cb0e65656563ecd50d7853362a0e 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 { + BlockPos blockposition = context.getClickedPos(); + BlockState iblockdata = world.getBlockState(blockposition); + +- if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { ++ if (!world.purpurConfig.endCrystalPlaceAnywhere && !iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { + return InteractionResult.FAIL; + } else { + BlockPos blockposition1 = blockposition.above(); diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java index 749ab72edc0d2e9c6f1161415ab8d59d3d6ca976..6b27d98d06b163243bb0e1bb979aad03f48d7770 100644 --- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java @@ -14241,7 +14358,7 @@ index b2ad6d230de2c29f371178bccde1111c7532ee70..6667926519a0f1c151e53f59cce36e74 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 180aec596110309aade13d2080f8824d152b07cb..c4aec1e5135a79837918b692e75a7b55d5cffeb0 100644 +index 180aec596110309aade13d2080f8824d152b07cb..552c31c0f3746dd35388395036e70a925bf00bd4 100644 --- a/src/main/java/net/minecraft/world/item/HoeItem.java +++ b/src/main/java/net/minecraft/world/item/HoeItem.java @@ -34,15 +34,23 @@ public class HoeItem extends DiggerItem { @@ -14256,7 +14373,7 @@ index 180aec596110309aade13d2080f8824d152b07cb..c4aec1e5135a79837918b692e75a7b55 - Consumer consumer = pair.getSecond(); + // Purpur start + Block clickedBlock = level.getBlockState(blockPos).getBlock(); -+ var tillable = level.purpurConfig.hoeTillables.get(level.getBlockState(blockPos).getBlock()); ++ var tillable = level.purpurConfig.hoeTillables.get(clickedBlock); + if (tillable == null) { return InteractionResult.PASS; } else { + Predicate predicate = tillable.condition().predicate(); + Consumer consumer = (ctx) -> { @@ -14481,53 +14598,28 @@ index 2941c16ef486345b57ab2dfcd26f0272285d3b5a..7cc6812bf6f2ba015f65fd1fc1eaac02 ((Mob) newEntityLiving).setPersistenceRequired(); // Paper end diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index 21212462e6b415e96536a27b2c009d1562f18946..98f4870ab82b25ed8bb144835f74c581ad9b9134 100644 +index 21212462e6b415e96536a27b2c009d1562f18946..efaf83e7b90f38d3a46da89ada91e2bf41c954db 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java -@@ -34,13 +34,20 @@ public class ShovelItem extends DiggerItem { - return InteractionResult.PASS; - } else { - Player player = context.getPlayer(); -- BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); -+ // Purpur start -+ BlockState blockState2 = level.purpurConfig.shovelTurnsBlockToGrassPath.contains(blockState.getBlock()) ? Blocks.DIRT_PATH.defaultBlockState() : null; -+ boolean isUniqueFlattenable; -+ // Purpur end +@@ -37,9 +37,15 @@ public class ShovelItem extends DiggerItem { + BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); BlockState blockState3 = null; Runnable afterAction = null; // Paper - if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) { +- if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) { - afterAction = () -> level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper -+ // Purpur start -+ isUniqueFlattenable = FLATTENABLES.get(blockState.getBlock()) == null; -+ afterAction = () -> level.playSound(isUniqueFlattenable ? null : player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper +- blockState3 = blockState2; ++ // Purpur start ++ var flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); ++ if (flattenable != null && level.getBlockState(blockPos.above()).isAir()) { ++ afterAction = () -> { ++ if (!FLATTENABLES.containsKey(blockState.getBlock())) ++ level.playSound(null, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); ++ }; // Paper ++ blockState3 = flattenable.into().defaultBlockState(); + // Purpur end - blockState3 = blockState2; } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { -+ isUniqueFlattenable = false; // Purpur afterAction = () -> { // Paper if (!level.isClientSide()) { - level.levelEvent((Player)null, 1009, blockPos, 0); -@@ -50,6 +57,11 @@ public class ShovelItem extends DiggerItem { - }; // Paper - blockState3 = blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)); - } -+ // Purpur start -+ else { -+ isUniqueFlattenable = false; -+ } -+ // Purpur end - - if (blockState3 != null) { - if (!level.isClientSide) { -@@ -68,7 +80,7 @@ public class ShovelItem extends DiggerItem { - } - } - -- return InteractionResult.sidedSuccess(level.isClientSide); -+ return isUniqueFlattenable ? InteractionResult.SUCCESS : InteractionResult.sidedSuccess(level.isClientSide); // Purpur - } else { - 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 ef3f90a5bcdd7b9815a4053cff166f9d2552f55d..e7e5e1cc92f56e3daba8fa09c59188febec5e8f2 100644 --- a/src/main/java/net/minecraft/world/item/SnowballItem.java @@ -15522,7 +15614,7 @@ index 88faea00be60a519f56f975a5311df5e1eb3e6b8..cbb726ac367be81e27d3a86643baf7c4 int i = aenumdirection.length; diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java -index decb8caa67bc5f4525e4d92fedf465a17171fceb..7bebae9b1eb97fb595fb90e7d4b0aacc93413ac3 100644 +index decb8caa67bc5f4525e4d92fedf465a17171fceb..26b3f162f25bed3e9d8001e3d9c2f8d7d4b3e08a 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java @@ -168,7 +168,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @@ -15541,11 +15633,11 @@ index decb8caa67bc5f4525e4d92fedf465a17171fceb..7bebae9b1eb97fb595fb90e7d4b0aacc + + // Purpur start + @Override -+ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand) { ++ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { + if (world.purpurConfig.hoeReplantsCrops && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, getBaseSeedId()); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); + } + } + // Purpur end @@ -15830,44 +15922,6 @@ index cfbe1dae76db76cf54a4f5d72aca72d5e893859e..74cb10230d459ac9f300a9d59af504d2 + super.fallOn(world, state, pos, entity, fallDistance); // Purpur } } -diff --git a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -index 1dd44eb0ab977093660e8fe6f49338e7f5ef7b28..e7c3f8a9a849ad38ac02eb084436cf122f29d4cf 100644 ---- a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -@@ -22,7 +22,15 @@ public class HugeMushroomBlock extends Block { - - public HugeMushroomBlock(BlockBehaviour.Properties settings) { - super(settings); -- this.registerDefaultState(this.stateDefinition.any().setValue(NORTH, Boolean.valueOf(true)).setValue(EAST, Boolean.valueOf(true)).setValue(SOUTH, Boolean.valueOf(true)).setValue(WEST, Boolean.valueOf(true)).setValue(UP, Boolean.valueOf(true)).setValue(DOWN, Boolean.valueOf(true))); -+ // Purpur start -+ this.registerDefaultState(this.stateDefinition.any() -+ .setValue(NORTH, true) -+ .setValue(EAST, true) -+ .setValue(SOUTH, true) -+ .setValue(WEST, true) -+ .setValue(UP, true) -+ .setValue(DOWN, true)); -+ // Purpur end - } - - @Override -@@ -30,7 +38,15 @@ public class HugeMushroomBlock extends Block { - if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates - BlockGetter blockGetter = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); -- return this.defaultBlockState().setValue(DOWN, Boolean.valueOf(!blockGetter.getBlockState(blockPos.below()).is(this))).setValue(UP, Boolean.valueOf(!blockGetter.getBlockState(blockPos.above()).is(this))).setValue(NORTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.north()).is(this))).setValue(EAST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.east()).is(this))).setValue(SOUTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.south()).is(this))).setValue(WEST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.west()).is(this))); -+ // Purpur start -+ return this.defaultBlockState() -+ .setValue(DOWN, this != blockGetter.getBlockStateIfLoaded(blockPos.below()).getBlock()) -+ .setValue(UP, this != blockGetter.getBlockStateIfLoaded(blockPos.above()).getBlock()) -+ .setValue(NORTH, this != blockGetter.getBlockStateIfLoaded(blockPos.north()).getBlock()) -+ .setValue(EAST, this != blockGetter.getBlockStateIfLoaded(blockPos.east()).getBlock()) -+ .setValue(SOUTH, this != blockGetter.getBlockStateIfLoaded(blockPos.south()).getBlock()) -+ .setValue(WEST, this != blockGetter.getBlockStateIfLoaded(blockPos.west()).getBlock()); -+ // Purpur end - } - - @Override diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java index 04089e6f7d6e3d532b00585870283922b6be5246..61e6d14abd54ecd5e43a5459f8daa7d86adedf44 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java @@ -15979,7 +16033,7 @@ index a6ab0d0defc05e56a91084c49897059670a1324b..589b437e7c97c846410f293e2f014bdc EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); world.getCraftServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java -index e55720c4d2fbdf6aae526910e87a67c29cf906fd..bf4485b4cad324d5aace657ebf284c4d97197f53 100644 +index e55720c4d2fbdf6aae526910e87a67c29cf906fd..4310d62c45c776eea81987809309da08c242c7b0 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java @@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; @@ -15998,11 +16052,11 @@ index e55720c4d2fbdf6aae526910e87a67c29cf906fd..bf4485b4cad324d5aace657ebf284c4d + + // Purpur start + @Override -+ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand) { ++ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { + if (world.purpurConfig.hoeReplantsNetherWarts && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, Items.NETHER_WART); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); + } + } + @@ -16191,7 +16245,7 @@ index 14e00c7feb1c051d56a3d27cd00dcef072dd771a..4952fb1aaaafb55baa0fddb389f966a1 } diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java -index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe93c648f9b 100644 +index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad253814a0 100644 --- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java @@ -40,6 +40,58 @@ public class SpawnerBlock extends BaseEntityBlock { @@ -16200,7 +16254,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 + // Purpur start + @Override -+ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack) { ++ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack, boolean includeDrops) { + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) { + Optional> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn()); + @@ -16242,7 +16296,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 + + popResource(level, pos, item); + } -+ super.playerDestroy(level, player, pos, state, blockEntity, stack); ++ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops); + } + + private boolean isSilkTouch(Level level, ItemStack stack) { @@ -16262,7 +16316,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 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 4bce895268542531598a01a1bccd8ac1ed703b7d..8333a3565e43b6b2a99b4ba92bbf296e5c89e112 100644 +index 4bce895268542531598a01a1bccd8ac1ed703b7d..0deebc1413cf3f4959b76589c3357dcda7d42a4a 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java @@ -48,7 +48,7 @@ public class SpongeBlock extends Block { @@ -16274,12 +16328,23 @@ index 4bce895268542531598a01a1bccd8ac1ed703b7d..8333a3565e43b6b2a99b4ba92bbf296e Direction[] aenumdirection = SpongeBlock.ALL_DIRECTIONS; int i = aenumdirection.length; -@@ -116,7 +116,7 @@ public class SpongeBlock extends Block { +@@ -82,6 +82,10 @@ public class SpongeBlock extends Block { + + if (iblockdata.getBlock() instanceof LiquidBlock) { + blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit ++ // Purpur start ++ } else if (iblockdata.is(Blocks.MUD)) { ++ blockList.setBlock(blockposition1, Blocks.CLAY.defaultBlockState(), 3); ++ // Purpur end + } else { + if (!iblockdata.is(Blocks.KELP) && !iblockdata.is(Blocks.KELP_PLANT) && !iblockdata.is(Blocks.SEAGRASS) && !iblockdata.is(Blocks.TALL_SEAGRASS)) { + return false; +@@ -116,7 +120,7 @@ public class SpongeBlock extends Block { BlockState iblockdata = world.getBlockState(blockposition1); FluidState fluid = world.getFluidState(blockposition1); - if (fluid.is(FluidTags.WATER)) { -+ if (!fluid.is(FluidTags.WATER) && (world.purpurConfig.spongeAbsorbsLava && !fluid.is(FluidTags.LAVA))) { // Purpur ++ if (!fluid.is(FluidTags.WATER) && (!world.purpurConfig.spongeAbsorbsLava || !fluid.is(FluidTags.LAVA)) && (!world.purpurConfig.spongeAbsorbsWaterFromMud || !iblockdata.is(Blocks.MUD))) { // Purpur if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock(blockList, blockposition1, iblockdata).isEmpty()) { // NOP } else if (iblockdata.getBlock() instanceof LiquidBlock) { @@ -16905,32 +16970,44 @@ index 65e1381bb2d10bd212463feb602c60f8fdb9ade1..b7370e64fd0d50e8725d7d5afc30af2e + // Purpur } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 38cde466714e5663cd416b6afd5d2558e139ec09..931c23801be88d0437c757970c27fd479ecb4fc2 100644 +index 38cde466714e5663cd416b6afd5d2558e139ec09..ded868a0ca748505bcb81d99ba214c814d02083c 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 -@@ -208,11 +208,18 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -202,16 +202,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(); -- if (entityhuman.isTextFilteringEnabled()) { ++ 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 -+ // Purpur start TODO: This is probably wrong but we'll see what happens -+ org.bukkit.entity.Player player = (org.bukkit.craftbukkit.entity.CraftPlayer) entityhuman.getBukkitEntity(); -+ String line = net.minecraft.SharedConstants.filterText(entityhuman.isTextFilteringEnabled() ? filteredtext.filteredOrEmpty() : filteredtext.raw()); -+ 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"); -+ signtext = signtext.setMessage(i, io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line)).copy().setStyle(chatmodifier)); ++ 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, io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.Component.text(line)).copy().setStyle(chatmodifier)); ++ 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 } -+ // Purpur end } - // CraftBukkit start -@@ -351,6 +358,23 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -351,6 +366,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C return ClientboundBlockEntityDataPacket.create(this); } @@ -16939,12 +17016,17 @@ index 38cde466714e5663cd416b6afd5d2558e139ec09..931c23801be88d0437c757970c27fd47 + 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); -+ nbt.putString("Text" + (i + 1), json); ++ 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); @@ -17771,6 +17853,33 @@ index 380897c010521f368848a3e6986d307cf47ff319..3c5eae31dc229b8c5f15215be9462410 } // Paper end } +diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java +index 4e56018b64d11f76c8da43fd8f85c6de72204e36..aa8212432825db65cf485cd93f734ccd9eefcb5a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java +@@ -21,7 +21,12 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co + + @Override + public void sendMessage(String message) { +- this.sendRawMessage(message); ++ // Purpur start ++ String[] parts = message.split("\n"); ++ for (String part : parts) { ++ this.sendRawMessage(part); ++ } ++ // Purpur end + } + + @Override +@@ -91,7 +96,7 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co + // Paper start + @Override + public void sendMessage(final net.kyori.adventure.identity.Identity identity, final net.kyori.adventure.text.Component message, final net.kyori.adventure.audience.MessageType type) { +- this.sendRawMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message)); ++ this.sendMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message)); // Purpur + } + + @Override diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java index 3d0ce0803e1da8a2681a3cb41096ac942ece54a1..bcd075a771c7f43c6d1549aeec2ccb20ee168b57 100644 --- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -18532,12 +18641,51 @@ index 2959f713ce75a1df9c6c7cf5e021690cfcb6e1e7..3fa9539cfb2c35beeba6d44fa05cee97 DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "experience", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); // Paper - wrong permission; redirects are de-redirected and the root literal name is used, so xp -> experience DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands); 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/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java +index d55adec004fd733859a75b34ce54e1f10b7336fc..5fdb227acfd1d8f55b770c8a66e97494c36db33c 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 ? Component.textOfChildren(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 +@@ -174,6 +174,6 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { + return null; + } + +- return Component.text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); ++ return org.bukkit.ChatColor.parseMM("Previous: %s", oldVersion); // Purpur + } + } 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..fc2d05b44cfe1db4bddb6073caeb729a6aec7034 +index 0000000000000000000000000000000000000000..45cb38d9e8b20a8ee4421e0b4fd6313138b6b910 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -0,0 +1,653 @@ +@@ -0,0 +1,655 @@ +package org.purpurmc.purpur; + +import com.google.common.base.Throwables; @@ -18615,8 +18763,8 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + commands = new HashMap<>(); + commands.put("purpur", new PurpurCommand("purpur")); + -+ version = getInt("config-version", 32); -+ set("config-version", 32); ++ version = getInt("config-version", 33); ++ set("config-version", 33); + + readConfig(PurpurConfig.class, null); + @@ -18730,6 +18878,7 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + public static String unverifiedUsername = "default"; + public static String sleepSkippingNight = "default"; + public static String sleepingPlayersPercent = "default"; ++ public static String sleepNotPossible = "default"; + private static void messages() { + cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); + afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); @@ -18748,6 +18897,7 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + unverifiedUsername = getString("settings.messages.unverified-username", unverifiedUsername); + sleepSkippingNight = getString("settings.messages.sleep-skipping-night", sleepSkippingNight); + sleepingPlayersPercent = getString("settings.messages.sleeping-players-percent", sleepingPlayersPercent); ++ sleepNotPossible = getString("settings.messages.sleep-not-possible", sleepNotPossible); + } + + public static String deathMsgRunWithScissors = " slipped and fell on their shears"; @@ -18960,6 +19110,7 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + public static boolean allowIncompatibleEnchants = true; + public static boolean allowHigherEnchantsLevels = true; + public static boolean allowUnsafeEnchantCommand = false; ++ public static boolean replaceIncompatibleEnchants = false; + public static boolean clampEnchantLevels = true; + private static void enchantmentSettings() { + if (version < 5) { @@ -18983,6 +19134,7 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + allowIncompatibleEnchants = getBoolean("settings.enchantment.anvil.allow-incompatible-enchants", allowIncompatibleEnchants); + allowHigherEnchantsLevels = getBoolean("settings.enchantment.anvil.allow-higher-enchants-levels", allowHigherEnchantsLevels); + allowUnsafeEnchantCommand = getBoolean("settings.enchantment.allow-unsafe-enchant-command", allowUnsafeEnchants); // allowUnsafeEnchants as default for backwards compatability ++ replaceIncompatibleEnchants = getBoolean("settings.enchantment.anvil.replace-incompatible-enchants", replaceIncompatibleEnchants); + clampEnchantLevels = getBoolean("settings.enchantment.clamp-levels", clampEnchantLevels); + } + @@ -18997,13 +19149,6 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd); + } + -+ public static boolean disableMushroomBlockUpdates = false; -+ public static boolean disableChorusPlantUpdates = false; -+ private static void blockUpdatesSettings() { -+ disableMushroomBlockUpdates = getBoolean("settings.blocks.disable-mushroom-updates", disableMushroomBlockUpdates); -+ disableChorusPlantUpdates = getBoolean("settings.blocks.disable-chorus-plant-updates", disableChorusPlantUpdates); -+ } -+ + public static boolean loggerSuppressInitLegacyMaterialError = false; + public static boolean loggerSuppressIgnoredAdvancementWarnings = false; + public static boolean loggerSuppressUnrecognizedRecipeErrors = false; @@ -19190,13 +19335,18 @@ index 0000000000000000000000000000000000000000..fc2d05b44cfe1db4bddb6073caeb729a + block.fallDistanceMultiplier = fallDistanceMultiplier.floatValue(); + }); + } ++ ++ public static boolean playerDeathsAlwaysShowItem = false; ++ private static void playerDeathsAlwaysShowItem() { ++ playerDeathsAlwaysShowItem = getBoolean("settings.player-deaths-always-show-item", playerDeathsAlwaysShowItem); ++ } +} 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..f90c7ad885b3cf1246fb711dd670d143a0b324bc +index 0000000000000000000000000000000000000000..f9ec9c05a1c46d9e0035bb161ffd950badd6b4c6 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3210 @@ +@@ -0,0 +1,3255 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -19207,10 +19357,10 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; -+import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.properties.Tilt; ++import org.purpurmc.purpur.tool.Flattenable; +import org.purpurmc.purpur.tool.Strippable; +import org.purpurmc.purpur.tool.Tillable; +import org.purpurmc.purpur.tool.Waxable; @@ -19731,21 +19881,6 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage); + } + -+ public List shovelTurnsBlockToGrassPath = new ArrayList<>(); -+ private void shovelSettings() { -+ getList("gameplay-mechanics.shovel-turns-block-to-grass-path", new ArrayList(){{ -+ add("minecraft:coarse_dirt"); -+ add("minecraft:dirt"); -+ add("minecraft:grass_block"); -+ add("minecraft:mycelium"); -+ add("minecraft:podzol"); -+ add("minecraft:rooted_dirt"); -+ }}).forEach(key -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key.toString())); -+ if (block != Blocks.AIR) shovelTurnsBlockToGrassPath.add(block); -+ }); -+ } -+ + public boolean silkTouchEnabled = false; + public String silkTouchSpawnerName = "Monster Spawner"; + public List silkTouchSpawnerLore = new ArrayList<>(); @@ -19782,6 +19917,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + public Map axeWaxables = new HashMap<>(); + public Map axeWeatherables = new HashMap<>(); + public Map hoeTillables = new HashMap<>(); ++ public Map shovelFlattenables = new HashMap<>(); + public boolean hoeReplantsCrops = false; + public boolean hoeReplantsNetherWarts = false; + private void toolSettings() { @@ -19789,6 +19925,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + axeWaxables.clear(); + axeWeatherables.clear(); + hoeTillables.clear(); ++ shovelFlattenables.clear(); + if (PurpurConfig.version < 18) { + ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + ".tools.hoe.tilling"); + if (section != null) { @@ -19810,6 +19947,19 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:cherry_wood", Map.of("into", "minecraft:stripped_cherry_wood", "drops", new HashMap())); + PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:bamboo_block", Map.of("into", "minecraft:stripped_bamboo_block", "drops", new HashMap())); + } ++ if (PurpurConfig.version < 33) { ++ getList("gameplay-mechanics.shovel-turns-block-to-grass-path", new ArrayList() {{ ++ add("minecraft:coarse_dirt"); ++ add("minecraft:dirt"); ++ add("minecraft:grass_block"); ++ add("minecraft:mycelium"); ++ add("minecraft:podzol"); ++ add("minecraft:rooted_dirt"); ++ }}).forEach(key -> { ++ PurpurConfig.config.set("world-settings.default.tools.shovel.flattenables." + key.toString(), Map.of("into", "minecraft:dirt_path", "drops", new HashMap())); ++ }); ++ set("gameplay-mechanics.shovel-turns-block-to-grass-path", null); ++ } + getMap("tools.axe.strippables", Map.ofEntries( + Map.entry("minecraft:oak_wood", Map.of("into", "minecraft:stripped_oak_wood", "drops", new HashMap())), + Map.entry("minecraft:oak_log", Map.of("into", "minecraft:stripped_oak_log", "drops", new HashMap())), @@ -19937,7 +20087,46 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.hoe.tillables." + blockId + ".drops`: " + itemId); return; } + drops.put(item, (double) chance); + }); -+ hoeTillables.put(block, new Tillable(condition, into, drops)); ++ shovelFlattenables.put(block, new Flattenable(into, drops)); ++ }); ++ getMap("tools.shovel.flattenables", Map.ofEntries( ++ Map.entry("minecraft:grass_block", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:podzol", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:coarse_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:mycelium", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:rooted_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap()))) ++ ).forEach((blockId, obj) -> { ++ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ if (block == Blocks.AIR) { ++ PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables`: " + blockId); ++ return; ++ } ++ if (!(obj instanceof Map map)) { ++ PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + "`"); ++ return; ++ } ++ String intoId = (String) map.get("into"); ++ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ if (into == Blocks.AIR) { ++ PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables." + blockId + ".into`: " + intoId); ++ return; ++ } ++ Object dropsObj = map.get("drops"); ++ if (!(dropsObj instanceof Map dropsMap)) { ++ PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + ".drops`"); ++ return; ++ } ++ Map drops = new HashMap<>(); ++ 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); ++ }); ++ shovelFlattenables.put(block, new Flattenable(into, drops)); + }); + hoeReplantsCrops = getBoolean("tools.hoe.replant-crops", hoeReplantsCrops); + hoeReplantsNetherWarts = getBoolean("tools.hoe.replant-nether-warts", hoeReplantsNetherWarts); @@ -20079,6 +20268,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + public boolean basedEndCrystalExplosionFire = false; + public net.minecraft.world.level.Level.ExplosionInteraction basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK; + public int endCrystalCramming = 0; ++ public boolean endCrystalPlaceAnywhere = false; + private void endCrystalSettings() { + if (PurpurConfig.version < 31) { + if ("DESTROY".equals(getString("blocks.end-crystal.baseless.explosion-effect", baselessEndCrystalExplosionEffect.name()))) { @@ -20107,6 +20297,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK; + } + endCrystalCramming = getInt("blocks.end-crystal.cramming-amount", endCrystalCramming); ++ endCrystalPlaceAnywhere = getBoolean("gameplay-mechanics.item.end-crystal.place-anywhere", endCrystalPlaceAnywhere); + } + + public boolean farmlandBypassMobGriefing = false; @@ -20243,10 +20434,12 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + public int spongeAbsorptionArea = 65; + public int spongeAbsorptionRadius = 6; + public boolean spongeAbsorbsLava = false; ++ public boolean spongeAbsorbsWaterFromMud = false; + private void spongeSettings() { + spongeAbsorptionArea = getInt("blocks.sponge.absorption.area", spongeAbsorptionArea); + spongeAbsorptionRadius = getInt("blocks.sponge.absorption.radius", spongeAbsorptionRadius); + spongeAbsorbsLava = getBoolean("blocks.sponge.absorbs-lava", spongeAbsorbsLava); ++ spongeAbsorbsWaterFromMud = getBoolean("blocks.sponge.absorbs-water-from-mud", spongeAbsorbsWaterFromMud); + } + + public float stonecutterDamage = 0.0F; @@ -21383,6 +21576,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + public int piglinPortalSpawnModifier = 2000; + public boolean piglinAlwaysDropExp = false; + public double piglinHeadVisibilityPercent = 0.5D; ++ public boolean piglinIgnoresArmorWithGoldTrim = false; + private void piglinSettings() { + piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); + piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); @@ -21398,6 +21592,7 @@ index 0000000000000000000000000000000000000000..f90c7ad885b3cf1246fb711dd670d143 + piglinPortalSpawnModifier = getInt("mobs.piglin.portal-spawn-modifier", piglinPortalSpawnModifier); + piglinAlwaysDropExp = getBoolean("mobs.piglin.always-drop-exp", piglinAlwaysDropExp); + piglinHeadVisibilityPercent = getDouble("mobs.piglin.head-visibility-percent", piglinHeadVisibilityPercent); ++ piglinIgnoresArmorWithGoldTrim = getBoolean("mobs.piglin.ignores-armor-with-gold-trim", piglinIgnoresArmorWithGoldTrim); + } + + public boolean piglinBruteRidable = false; @@ -24532,6 +24727,25 @@ index 0000000000000000000000000000000000000000..e18c37f06730da9d3055d5215e813b14 + return drops; + } +} +diff --git a/src/main/java/org/purpurmc/purpur/tool/Flattenable.java b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b7e47f58af7cfb3367eeaad92f3a87d6ae9e708f +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java +@@ -0,0 +1,12 @@ ++package org.purpurmc.purpur.tool; ++ ++import net.minecraft.world.item.Item; ++import net.minecraft.world.level.block.Block; ++ ++import java.util.Map; ++ ++public class Flattenable extends Actionable { ++ public Flattenable(Block into, Map drops) { ++ super(into, drops); ++ } ++} +\ No newline at end of file diff --git a/src/main/java/org/purpurmc/purpur/tool/Strippable.java b/src/main/java/org/purpurmc/purpur/tool/Strippable.java new file mode 100644 index 0000000000000000000000000000000000000000..bf5402214f41af9c09bd6c5c4f45d330516d742e diff --git a/patches/server/0011-Purpur-Configurable-server-mod-name.patch b/patches/server/0010-Purpur-Configurable-server-mod-name.patch similarity index 94% rename from patches/server/0011-Purpur-Configurable-server-mod-name.patch rename to patches/server/0010-Purpur-Configurable-server-mod-name.patch index 45fbdf16..4a1a5689 100644 --- a/patches/server/0011-Purpur-Configurable-server-mod-name.patch +++ b/patches/server/0010-Purpur-Configurable-server-mod-name.patch @@ -34,10 +34,10 @@ index 9299d2fe1cda71b6881fd8bd65d3d74b1189a196..80a196442edbc6b4eb44bb6a40510087 } diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index fc2d05b44cfe1db4bddb6073caeb729a6aec7034..cca5d9efc37ff4881645aeeaa08ae02ea1fbb97d 100644 +index 45cb38d9e8b20a8ee4421e0b4fd6313138b6b910..c673e6cfe8f8afb9546a1bb234f5cef1f1312490 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -229,11 +229,6 @@ public class PurpurConfig { +@@ -231,11 +231,6 @@ public class PurpurConfig { deathMessageOnlyBroadcastToAffectedPlayer = getBoolean("settings.broadcasts.death.only-broadcast-to-affected-player", deathMessageOnlyBroadcastToAffectedPlayer); } diff --git a/patches/server/0012-Bump-Dependencies.patch b/patches/server/0011-Bump-Dependencies.patch similarity index 100% rename from patches/server/0012-Bump-Dependencies.patch rename to patches/server/0011-Bump-Dependencies.patch diff --git a/patches/server/0013-Remove-Mojang-username-check.patch b/patches/server/0012-Remove-Mojang-username-check.patch similarity index 96% rename from patches/server/0013-Remove-Mojang-username-check.patch rename to patches/server/0012-Remove-Mojang-username-check.patch index 789ba4c9..a46a9433 100644 --- a/patches/server/0013-Remove-Mojang-username-check.patch +++ b/patches/server/0012-Remove-Mojang-username-check.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove Mojang 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 badb262810effd22ca1ba021a1e746a777a19cbc..9baf55e9c3259aed431022a50c12d4f215c3ed80 100644 +index 2163d62be320031b6cd1bed06a2600801c634112..fe5ee9f6ee14e74679b9f26fae3412b04a431c75 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -253,10 +253,10 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/server/0014-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch b/patches/server/0013-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch similarity index 100% rename from patches/server/0014-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch rename to patches/server/0013-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch diff --git a/patches/server/0015-Remove-UseItemOnPacket-Too-Far-Check.patch b/patches/server/0014-Remove-UseItemOnPacket-Too-Far-Check.patch similarity index 100% rename from patches/server/0015-Remove-UseItemOnPacket-Too-Far-Check.patch rename to patches/server/0014-Remove-UseItemOnPacket-Too-Far-Check.patch diff --git a/patches/server/0016-KTP-Optimize-spigot-event-bus.patch b/patches/server/0015-KTP-Optimize-spigot-event-bus.patch similarity index 100% rename from patches/server/0016-KTP-Optimize-spigot-event-bus.patch rename to patches/server/0015-KTP-Optimize-spigot-event-bus.patch diff --git a/patches/server/0017-KeYi-Player-Skull-API.patch b/patches/server/0016-KeYi-Player-Skull-API.patch similarity index 100% rename from patches/server/0017-KeYi-Player-Skull-API.patch rename to patches/server/0016-KeYi-Player-Skull-API.patch diff --git a/patches/server/0018-KeYi-Disable-arrow-despawn-counter-by-default.patch b/patches/server/0017-KeYi-Disable-arrow-despawn-counter-by-default.patch similarity index 100% rename from patches/server/0018-KeYi-Disable-arrow-despawn-counter-by-default.patch rename to patches/server/0017-KeYi-Disable-arrow-despawn-counter-by-default.patch diff --git a/patches/server/0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch b/patches/server/0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch similarity index 100% rename from patches/server/0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch rename to patches/server/0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch diff --git a/patches/server/0020-Carpet-Fixes-Optimized-getBiome-method.patch b/patches/server/0019-Carpet-Fixes-Optimized-getBiome-method.patch similarity index 100% rename from patches/server/0020-Carpet-Fixes-Optimized-getBiome-method.patch rename to patches/server/0019-Carpet-Fixes-Optimized-getBiome-method.patch diff --git a/patches/server/0021-Carpet-Fixes-Use-optimized-RecipeManager.patch b/patches/server/0020-Carpet-Fixes-Use-optimized-RecipeManager.patch similarity index 100% rename from patches/server/0021-Carpet-Fixes-Use-optimized-RecipeManager.patch rename to patches/server/0020-Carpet-Fixes-Use-optimized-RecipeManager.patch diff --git a/patches/server/0022-Akarin-Save-Json-list-asynchronously.patch b/patches/server/0021-Akarin-Save-Json-list-asynchronously.patch similarity index 100% rename from patches/server/0022-Akarin-Save-Json-list-asynchronously.patch rename to patches/server/0021-Akarin-Save-Json-list-asynchronously.patch diff --git a/patches/server/0023-Slice-Smooth-Teleports.patch b/patches/server/0022-Slice-Smooth-Teleports.patch similarity index 97% rename from patches/server/0023-Slice-Smooth-Teleports.patch rename to patches/server/0022-Slice-Smooth-Teleports.patch index 1fa68f8a..a712d06a 100644 --- a/patches/server/0023-Slice-Smooth-Teleports.patch +++ b/patches/server/0022-Slice-Smooth-Teleports.patch @@ -7,7 +7,7 @@ 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 ac12549e49f824aded913eb131117b750ea3db1b..49310193515273c1388dea7b651314bf7791d36a 100644 +index 208165326d19d8a9e8c985ca7762f27f74bdc21e..05cb74d822dee7c5b4256ab6abec617018731fc9 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -284,6 +284,7 @@ public class ServerPlayer extends Player { diff --git a/patches/server/0024-Parchment-Make-FixLight-use-action-bar.patch b/patches/server/0023-Parchment-Make-FixLight-use-action-bar.patch similarity index 100% rename from patches/server/0024-Parchment-Make-FixLight-use-action-bar.patch rename to patches/server/0023-Parchment-Make-FixLight-use-action-bar.patch diff --git a/patches/server/0025-Leaves-Server-Utils.patch b/patches/server/0024-Leaves-Server-Utils.patch similarity index 100% rename from patches/server/0025-Leaves-Server-Utils.patch rename to patches/server/0024-Leaves-Server-Utils.patch diff --git a/patches/server/0026-Leaves-Jade-Protocol.patch b/patches/server/0025-Leaves-Jade-Protocol.patch similarity index 100% rename from patches/server/0026-Leaves-Jade-Protocol.patch rename to patches/server/0025-Leaves-Jade-Protocol.patch diff --git a/patches/server/0027-Leaves-Appleskin-Protocol.patch b/patches/server/0026-Leaves-Appleskin-Protocol.patch similarity index 100% rename from patches/server/0027-Leaves-Appleskin-Protocol.patch rename to patches/server/0026-Leaves-Appleskin-Protocol.patch diff --git a/patches/server/0028-Leaves-Xaero-Map-Protocol.patch b/patches/server/0027-Leaves-Xaero-Map-Protocol.patch similarity index 100% rename from patches/server/0028-Leaves-Xaero-Map-Protocol.patch rename to patches/server/0027-Leaves-Xaero-Map-Protocol.patch diff --git a/patches/server/0029-Fix-Make-log4j-compatible-with-future-release.patch b/patches/server/0028-Fix-Make-log4j-compatible-with-future-release.patch similarity index 100% rename from patches/server/0029-Fix-Make-log4j-compatible-with-future-release.patch rename to patches/server/0028-Fix-Make-log4j-compatible-with-future-release.patch diff --git a/patches/server/0030-Fix-compile-error.patch b/patches/server/0029-Fix-compile-error.patch similarity index 100% rename from patches/server/0030-Fix-compile-error.patch rename to patches/server/0029-Fix-compile-error.patch diff --git a/patches/server/0031-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch b/patches/server/0030-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch similarity index 100% rename from patches/server/0031-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch rename to patches/server/0030-sync-with-Gale-s-Optimize-villager-data-storage.patc.patch diff --git a/patches/server/0032-Revert-Purpur-Fire-Immunity-API.patch b/patches/server/0031-Revert-Purpur-Fire-Immunity-API.patch similarity index 100% rename from patches/server/0032-Revert-Purpur-Fire-Immunity-API.patch rename to patches/server/0031-Revert-Purpur-Fire-Immunity-API.patch diff --git a/patches/server/0033-Petal-Reduce-sensor-work.patch b/patches/server/0032-Petal-Reduce-sensor-work.patch similarity index 100% rename from patches/server/0033-Petal-Reduce-sensor-work.patch rename to patches/server/0032-Petal-Reduce-sensor-work.patch diff --git a/patches/server/0034-Petal-Async-Pathfinding.patch b/patches/server/0033-Petal-Async-Pathfinding.patch similarity index 100% rename from patches/server/0034-Petal-Async-Pathfinding.patch rename to patches/server/0033-Petal-Async-Pathfinding.patch diff --git a/patches/server/0035-Petal-Multithreaded-Tracker.patch b/patches/server/0034-Petal-Multithreaded-Tracker.patch similarity index 100% rename from patches/server/0035-Petal-Multithreaded-Tracker.patch rename to patches/server/0034-Petal-Multithreaded-Tracker.patch diff --git a/patches/server/0036-Petal-Sync-event-calls-on-async-threads.patch b/patches/server/0035-Petal-Sync-event-calls-on-async-threads.patch similarity index 100% rename from patches/server/0036-Petal-Sync-event-calls-on-async-threads.patch rename to patches/server/0035-Petal-Sync-event-calls-on-async-threads.patch diff --git a/patches/server/0037-Fix-tracker-NPE.patch b/patches/server/0036-Fix-tracker-NPE.patch similarity index 100% rename from patches/server/0037-Fix-tracker-NPE.patch rename to patches/server/0036-Fix-tracker-NPE.patch diff --git a/patches/server/0038-Cache-minecart-vehicle-collide-results.patch b/patches/server/0037-Cache-minecart-vehicle-collide-results.patch similarity index 100% rename from patches/server/0038-Cache-minecart-vehicle-collide-results.patch rename to patches/server/0037-Cache-minecart-vehicle-collide-results.patch