From 25cc3d8578dde4e27019c66f71eb308bb8b74c41 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 25 Dec 2024 11:08:07 +0100 Subject: [PATCH 01/40] Fix EnchantmentView#setOffers length precondition being flipped (#11818) --- .../bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java index abe709ab9..37a02aa25 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java @@ -47,7 +47,7 @@ public class CraftEnchantmentView extends CraftInventoryView> registry = CraftRegistry.getMinecraftRegistry().lookupOrThrow(Registries.ENCHANTMENT).asHolderIdMap(); for (int i = 0; i < offers.length; i++) { final EnchantmentOffer offer = offers[i]; From 763b32d825b22c75ebc2601424a4b1985fdd7a78 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 25 Dec 2024 12:31:03 +0100 Subject: [PATCH 02/40] Fix framed maps looping through all players in world (#11819) --- ...ntity-tracker-desync-when-new-players-are-added.patch | 8 ++++---- .../net/minecraft/server/level/ServerEntity.java.patch | 9 +++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/paper-server/patches/features/0018-Fix-entity-tracker-desync-when-new-players-are-added.patch b/paper-server/patches/features/0018-Fix-entity-tracker-desync-when-new-players-are-added.patch index 1059713e9..4bfb85602 100644 --- a/paper-server/patches/features/0018-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/paper-server/patches/features/0018-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -60,7 +60,7 @@ index 3dff97f13586be3b52bbe786852c185f6753a019..ff6503bf8eb88d1264c3d848a89d0255 } else if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f7117281649b7a 100644 +index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b75c7d7e59 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java @@ -90,6 +90,13 @@ public class ServerEntity { @@ -77,7 +77,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172 public void sendChanges() { // Paper start - optimise collisions if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) { -@@ -130,7 +137,7 @@ public class ServerEntity { +@@ -131,7 +138,7 @@ public class ServerEntity { this.sendDirtyEntityData(); } @@ -86,7 +86,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172 byte b = Mth.packDegrees(this.entity.getYRot()); byte b1 = Mth.packDegrees(this.entity.getXRot()); boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1; -@@ -165,7 +172,7 @@ public class ServerEntity { +@@ -166,7 +173,7 @@ public class ServerEntity { long l1 = this.positionCodec.encodeY(vec3); long l2 = this.positionCodec.encodeZ(vec3); boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L; @@ -95,7 +95,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172 this.wasOnGround = this.entity.onGround(); this.teleportDelay = 0; packet = ClientboundEntityPositionSyncPacket.of(this.entity); -@@ -230,6 +237,7 @@ public class ServerEntity { +@@ -231,6 +238,7 @@ public class ServerEntity { } this.entity.hasImpulse = false; diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch index 4413d91d0..7932d7570 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch @@ -29,7 +29,7 @@ removedPassengers(passengers, this.lastPassengers) .forEach( removedPassenger -> { -@@ -102,10 +_,10 @@ +@@ -102,13 +_,14 @@ this.lastPassengers = passengers; } @@ -42,7 +42,12 @@ + MapId mapId = itemFrame.cachedMapId; // Paper - Perf: Cache map ids on item frames MapItemSavedData savedData = MapItem.getSavedData(mapId, this.level); if (savedData != null) { - for (ServerPlayer serverPlayer : this.level.players()) { +- for (ServerPlayer serverPlayer : this.level.players()) { ++ for (final net.minecraft.server.network.ServerPlayerConnection connection : this.trackedPlayers) { // Paper ++ final ServerPlayer serverPlayer = connection.getPlayer(); // Paper + savedData.tickCarriedBy(serverPlayer, item); + Packet updatePacket = savedData.getUpdatePacket(mapId, serverPlayer); + if (updatePacket != null) { @@ -141,7 +_,13 @@ } else { this.teleportDelay++; From 946314fb5869b9c1f2e5c29ebc7ff0f8bb1ff4fe Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:20:21 +0100 Subject: [PATCH 03/40] Remove disableTeleportationSuffocationCheck config (#11822) --- .../io/papermc/paper/configuration/RemovedConfigurations.java | 3 ++- .../io/papermc/paper/configuration/WorldConfiguration.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java b/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java index f9a4bb664..fad321217 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java @@ -53,7 +53,8 @@ interface RemovedConfigurations { path("entities", "spawning", "despawn-ranges", "hard"), path("fixes", "fix-curing-zombie-villager-discount-exploit"), path("entities", "mob-effects", "undead-immune-to-certain-effects"), - path("entities", "entities-target-with-follow-range") + path("entities", "entities-target-with-follow-range"), + path("environment", "disable-teleportation-suffocation-check") }; // spawn.keep-spawn-loaded and spawn.keep-spawn-loaded-range are no longer used, but kept // in the world default config for compatibility with old worlds being migrated to use the gamerule diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java index b1c917d65..f5ac1b029 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java @@ -445,7 +445,6 @@ public class WorldConfiguration extends ConfigurationPart { public int portalSearchRadius = 128; public int portalCreateRadius = 16; public boolean portalSearchVanillaDimensionScaling = true; - public boolean disableTeleportationSuffocationCheck = false; public IntOr.Disabled netherCeilingVoidDamageHeight = IntOr.Disabled.DISABLED; public int maxFluidTicks = 65536; public int maxBlockTicks = 65536; From 140577b7621cbe069ab4e961d278438568c0090d Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:36:23 +0100 Subject: [PATCH 04/40] Fix broken field rename compat for instrument "feel_goat_horn" (#11824) --- .../src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java | 1 + 1 file changed, 1 insertion(+) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java index fe29c0827..23cbe3b6f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java @@ -282,6 +282,7 @@ public class FieldRename { .change("PONDER", "PONDER_GOAT_HORN") .change("SING", "SING_GOAT_HORN") .change("SEEK", "SEEK_GOAT_HORN") + .change("FEEL", "FEEL_GOAT_HORN") .change("ADMIRE", "ADMIRE_GOAT_HORN") .change("CALL", "CALL_GOAT_HORN") .change("YEARN", "YEARN_GOAT_HORN") From a07cec16f8d7098fabc4a3bccb7d6da263410d4a Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:56:24 +0200 Subject: [PATCH 05/40] Add effective name to ItemStack (#11770) --- .../main/java/org/bukkit/inventory/ItemStack.java | 12 ++++++++++++ .../bukkit/craftbukkit/inventory/CraftItemStack.java | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java index 8c9654cd1..ed95b77a0 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableMap; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -710,6 +711,17 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getServer().getItemFactory().displayName(this); } + /** + * Gets the effective name of this item stack shown to player in inventory. + * It takes into account the display name (with italics) from the item meta, + * the potion effect, translatable name, rarity etc. + * + * @return the effective name of this item stack + */ + public @NotNull Component effectiveName() { + return this.craftDelegate.effectiveName(); + } + /** * Minecraft updates are converting simple item stacks into more complex NBT oriented Item Stacks. * diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 78975412d..379997369 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -5,6 +5,8 @@ import com.google.common.collect.ImmutableMap; import java.util.Collections; import java.util.Map; import java.util.Optional; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; import net.minecraft.advancements.critereon.ItemPredicate; import net.minecraft.advancements.critereon.MinMaxBounds; import net.minecraft.core.Holder; @@ -25,6 +27,7 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; +import org.jetbrains.annotations.NotNull; @DelegateDeserialization(ItemStack.class) public final class CraftItemStack extends ItemStack { @@ -467,6 +470,11 @@ public final class CraftItemStack extends ItemStack { return true; } + @Override + public @NotNull Component effectiveName() { + return this.handle == null ? Component.empty() : PaperAdventure.asAdventure(this.handle.getStyledHoverName()); + } + @Override public boolean isSimilar(ItemStack stack) { if (stack == null) { From 3a479eadd70a91fc0fd14f2aa39be0643bdcf3d4 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Wed, 25 Dec 2024 19:39:27 -0800 Subject: [PATCH 06/40] Add Registry#getTags (#11795) --- .../src/main/java/org/bukkit/Registry.java | 377 +++++++++--------- .../paper/registry/PaperSimpleRegistry.java | 6 + .../registry/legacy/DelayedRegistry.java | 11 +- .../registry/set/NamedRegistryKeySetImpl.java | 4 + .../org/bukkit/craftbukkit/CraftRegistry.java | 53 +-- 5 files changed, 210 insertions(+), 241 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index d55c33ca1..50eea2967 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -3,13 +3,22 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; +import java.util.Collection; import java.util.Iterator; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import net.kyori.adventure.key.Key; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; @@ -35,8 +44,8 @@ import org.bukkit.map.MapCursor; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a registry of Bukkit objects that may be retrieved by @@ -44,39 +53,34 @@ import org.jetbrains.annotations.Nullable; * * @param type of item in the registry */ +@NullMarked public interface Registry extends Iterable { + private static Registry registryFor(final RegistryKey registryKey) { + return RegistryAccess.registryAccess().getRegistry(registryKey); + } + + @SuppressWarnings("removal") + @Deprecated(forRemoval = true, since = "1.21.4") + private static Registry legacyRegistryFor(final Class clazz) { + return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), "No registry present for " + clazz.getSimpleName() + ". This is a bug."); + } + /** * Server advancements. * - * @see Bukkit#getAdvancement(org.bukkit.NamespacedKey) + * @see Bukkit#getAdvancement(NamespacedKey) * @see Bukkit#advancementIterator() + * @deprecated use {@link Bukkit#getAdvancement(NamespacedKey)} and {@link Bukkit#advancementIterator()} */ - Registry ADVANCEMENT = new Registry() { + @Deprecated(since = "1.21.4", forRemoval = true) + Registry ADVANCEMENT = new NotARegistry<>() { - @Nullable @Override - public Advancement get(@NotNull NamespacedKey key) { + public @Nullable Advancement get(final NamespacedKey key) { return Bukkit.getAdvancement(key); } - @NotNull - @Override - public Advancement getOrThrow(@NotNull NamespacedKey key) { - Advancement advancement = get(key); - - Preconditions.checkArgument(advancement != null, "No Advancement registry entry found for key %s.", key); - - return advancement; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { return Bukkit.advancementIterator(); @@ -86,71 +90,54 @@ public interface Registry extends Iterable { * Server art. * * @see Art - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#PAINTING_VARIANT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#PAINTING_VARIANT} */ @Deprecated(since = "1.21.3") // Paper - Registry ART = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Art.class), "No registry present for Art. This is a bug."); + Registry ART = legacyRegistryFor(Art.class); /** * Attribute. * * @see Attribute */ - Registry ATTRIBUTE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ATTRIBUTE); // Paper + Registry ATTRIBUTE = registryFor(RegistryKey.ATTRIBUTE); /** * Server banner patterns. * * @see PatternType - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BANNER_PATTERN} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BANNER_PATTERN} */ @Deprecated(since = "1.21") // Paper - Registry BANNER_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(PatternType.class), "No registry present for PatternType. This is a bug."); // Paper + Registry BANNER_PATTERN = legacyRegistryFor(PatternType.class); /** * Server biomes. * * @see Biome - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BIOME} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BIOME} */ @Deprecated(since = "1.21.3") // Paper - Registry BIOME = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Biome.class), "No registry present for Biome. This is a bug."); + Registry BIOME = legacyRegistryFor(Biome.class); /** * Server block types. * * @see BlockType - * @apiNote BlockType is not ready for public usage yet */ - @ApiStatus.Internal - Registry BLOCK = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.BLOCK); // Paper + @ApiStatus.Experimental + Registry BLOCK = registryFor(RegistryKey.BLOCK); /** * Custom boss bars. * * @see Bukkit#getBossBar(org.bukkit.NamespacedKey) * @see Bukkit#getBossBars() + * @deprecated use {@link Bukkit#getBossBar(NamespacedKey)} and {@link Bukkit#getBossBars()} */ - Registry BOSS_BARS = new Registry() { + @Deprecated(since = "1.21.4", forRemoval = true) + Registry BOSS_BARS = new NotARegistry<>() { - @Nullable @Override - public KeyedBossBar get(@NotNull NamespacedKey key) { + public @Nullable KeyedBossBar get(final NamespacedKey key) { return Bukkit.getBossBar(key); } - @NotNull - @Override - public KeyedBossBar getOrThrow(@NotNull NamespacedKey key) { - KeyedBossBar keyedBossBar = get(key); - - Preconditions.checkArgument(keyedBossBar != null, "No KeyedBossBar registry entry found for key %s.", key); - - return keyedBossBar; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { return Bukkit.getBossBars(); @@ -161,37 +148,36 @@ public interface Registry extends Iterable { * * @see Cat.Type */ - Registry CAT_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.CAT_VARIANT); // Paper + Registry CAT_VARIANT = registryFor(RegistryKey.CAT_VARIANT); /** * Server enchantments. * * @see Enchantment - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#ENCHANTMENT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#ENCHANTMENT} */ @Deprecated(since = "1.21") - Registry ENCHANTMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug."); // Paper + Registry ENCHANTMENT = legacyRegistryFor(Enchantment.class); /** * Server entity types. * * @see EntityType */ - Registry ENTITY_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ENTITY_TYPE); // Paper + Registry ENTITY_TYPE = registryFor(RegistryKey.ENTITY_TYPE); /** * Server instruments. * * @see MusicInstrument - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#INSTRUMENT} */ @Deprecated(since = "1.21.2") - Registry INSTRUMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(MusicInstrument.class), "No registry present for Instruments. This is a bug."); // Paper + Registry INSTRUMENT = legacyRegistryFor(MusicInstrument.class); /** * Server item types. * * @see ItemType - * @apiNote ItemType is not ready for public usage yet */ - @ApiStatus.Internal - Registry ITEM = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ITEM); // Paper + @ApiStatus.Experimental + Registry ITEM = registryFor(RegistryKey.ITEM); /** * Default server loot tables. * @@ -210,25 +196,25 @@ public interface Registry extends Iterable { * @see MenuType */ @ApiStatus.Experimental - Registry MENU = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MENU); // Paper + Registry MENU = registryFor(RegistryKey.MENU); /** * Server mob effects. * * @see PotionEffectType */ - Registry EFFECT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MOB_EFFECT); // Paper + Registry MOB_EFFECT = registryFor(RegistryKey.MOB_EFFECT); /** * Server particles. * * @see Particle */ - Registry PARTICLE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.PARTICLE_TYPE); // Paper + Registry PARTICLE_TYPE = registryFor(RegistryKey.PARTICLE_TYPE); // Paper /** * Server potions. * * @see PotionType */ - Registry POTION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.POTION); // Paper + Registry POTION = registryFor(RegistryKey.POTION); // Paper /** * Server statistics. * @@ -239,160 +225,161 @@ public interface Registry extends Iterable { * Server structures. * * @see Structure - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#STRUCTURE} */ @Deprecated(since = "1.20.6") // Paper - Registry STRUCTURE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Structure.class), "No registry present for Structure. This is a bug."); // Paper + Registry STRUCTURE = legacyRegistryFor(Structure.class); /** * Server structure types. * * @see StructureType */ - Registry STRUCTURE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.STRUCTURE_TYPE), "No registry present for StructureType. This is a bug."); // Paper + Registry STRUCTURE_TYPE = registryFor(RegistryKey.STRUCTURE_TYPE); /** - * Sound keys. + * Sound events. * * @see Sound */ - Registry SOUNDS = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.SOUND_EVENT); // Paper + Registry SOUND_EVENT = registryFor(RegistryKey.SOUND_EVENT); /** * Trim materials. * * @see TrimMaterial - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_MATERIAL} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_MATERIAL} */ @Deprecated(since = "1.20.6") // Paper - Registry TRIM_MATERIAL = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimMaterial.class), "No registry present for TrimMaterial. This is a bug."); // Paper + Registry TRIM_MATERIAL = legacyRegistryFor(TrimMaterial.class); /** * Trim patterns. * * @see TrimPattern - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_PATTERN} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_PATTERN} */ @Deprecated(since = "1.20.6") - Registry TRIM_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimPattern.class), "No registry present for TrimPattern. This is a bug."); // Paper + Registry TRIM_PATTERN = legacyRegistryFor(TrimPattern.class); /** * Damage types. * * @see DamageType - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#DAMAGE_TYPE} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#DAMAGE_TYPE} */ @Deprecated(since = "1.20.6") - Registry DAMAGE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(DamageType.class), "No registry present for DamageType. This is a bug."); // Paper + Registry DAMAGE_TYPE = legacyRegistryFor(DamageType.class); /** * Jukebox songs. * * @see JukeboxSong - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#JUKEBOX_SONG} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#JUKEBOX_SONG} */ @ApiStatus.Experimental @Deprecated(since = "1.21") - Registry JUKEBOX_SONG = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(JukeboxSong.class), "No registry present for JukeboxSong. This is a bug."); // Paper + Registry JUKEBOX_SONG = legacyRegistryFor(JukeboxSong.class); /** * Villager profession. * * @see Villager.Profession */ - Registry VILLAGER_PROFESSION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_PROFESSION); // Paper + Registry VILLAGER_PROFESSION = registryFor(RegistryKey.VILLAGER_PROFESSION); /** * Villager type. * * @see Villager.Type */ - Registry VILLAGER_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_TYPE); // Paper + Registry VILLAGER_TYPE = registryFor(RegistryKey.VILLAGER_TYPE); /** * Memory Keys. * * @see MemoryKey */ - Registry MEMORY_MODULE_TYPE = new Registry() { + Registry MEMORY_MODULE_TYPE = new NotARegistry<>() { - @NotNull @Override public Iterator iterator() { return MemoryKey.values().iterator(); } - @Nullable @Override - public MemoryKey get(@NotNull NamespacedKey key) { + public @Nullable MemoryKey get(final NamespacedKey key) { return MemoryKey.getByKey(key); } - - @NotNull - @Override - public MemoryKey getOrThrow(@NotNull NamespacedKey key) { - MemoryKey memoryKey = get(key); - - Preconditions.checkArgument(memoryKey != null, "No MemoryKey registry entry found for key %s.", key); - - return memoryKey; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } }; /** * Server fluids. * * @see Fluid */ - Registry FLUID = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FLUID); // Paper + Registry FLUID = registryFor(RegistryKey.FLUID); /** * Frog variants. * * @see Frog.Variant */ - Registry FROG_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FROG_VARIANT); // Paper + Registry FROG_VARIANT = registryFor(RegistryKey.FROG_VARIANT); /** * Wolf variants. * * @see Wolf.Variant - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#WOLF_VARIANT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#WOLF_VARIANT} */ @Deprecated(since = "1.20.6") - Registry WOLF_VARIANT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Wolf.Variant.class), "No registry present for Wolf$Variant. This is a bug."); // Paper + Registry WOLF_VARIANT = legacyRegistryFor(Wolf.Variant.class); /** * Map cursor types. * * @see MapCursor.Type */ - Registry MAP_DECORATION_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MAP_DECORATION_TYPE); // Paper + Registry MAP_DECORATION_TYPE = registryFor(RegistryKey.MAP_DECORATION_TYPE); /** * Game events. * * @see GameEvent + * @see io.papermc.paper.registry.event.RegistryEvents#GAME_EVENT */ - Registry GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper + Registry GAME_EVENT = registryFor(RegistryKey.GAME_EVENT); + /** + * Data component types. + * + * @see DataComponentType + */ + Registry DATA_COMPONENT_TYPE = registryFor(RegistryKey.DATA_COMPONENT_TYPE); // Paper - // Paper start - potion effect type registry + // /** - * Potion effect types. - * - * @see org.bukkit.potion.PotionEffectType + * @apiNote use {@link #MOB_EFFECT} instead + * @hidden */ + @ApiStatus.Obsolete(since = "1.21.4") + Registry EFFECT = MOB_EFFECT; + /** + * @apiNote use {@link #MOB_EFFECT} instead + * @hidden + */ + @ApiStatus.Obsolete(since = "1.21.4") Registry POTION_EFFECT_TYPE = EFFECT; - // Paper end - potion effect type registry - Registry DATA_COMPONENT_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.DATA_COMPONENT_TYPE); // Paper /** - * Get the object by its key. - * - * @param key non-null key - * @return item or null if does not exist + * @apiNote use {@link #SOUND_EVENT} + * @hidden */ - @Nullable - T get(@NotNull NamespacedKey key); - // Paper start + @ApiStatus.Obsolete(since = "1.21.4") + Registry SOUNDS = registryFor(RegistryKey.SOUND_EVENT); + // + /** * Get the object by its key. * * @param key non-null key * @return item or null if it does not exist */ - default @Nullable T get(final net.kyori.adventure.key.@NotNull Key key) { + @Nullable T get(NamespacedKey key); + // Paper start + + /** + * Get the object by its key. + * + * @param key non-null key + * @return item or null if it does not exist + */ + default @Nullable T get(final Key key) { return key instanceof final NamespacedKey nsKey ? this.get(nsKey) : this.get(new NamespacedKey(key.namespace(), key.value())); } @@ -402,23 +389,26 @@ public interface Registry extends Iterable { * @param typedKey non-null typed key * @return item or null if it does not exist */ - default @Nullable T get(final io.papermc.paper.registry.@NotNull TypedKey typedKey) { + default @Nullable T get(final TypedKey typedKey) { + Preconditions.checkArgument(typedKey != null, "typedKey cannot be null"); return this.get(typedKey.key()); } // Paper end // Paper start - improve Registry + /** * Gets the object by its key or throws if it doesn't exist. * * @param key the key to get the object of in this registry * @return the object for the key - * @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry + * @throws NoSuchElementException if the key doesn't point to an object in the registry */ - default @NotNull T getOrThrow(final net.kyori.adventure.key.@NotNull Key key) { + default T getOrThrow(final net.kyori.adventure.key.Key key) { + Preconditions.checkArgument(key != null, "key cannot be null"); final T value = this.get(key); if (value == null) { - throw new java.util.NoSuchElementException("No value for " + key + " in " + this); + throw new NoSuchElementException("No value for " + key + " in " + this); } return value; } @@ -428,12 +418,12 @@ public interface Registry extends Iterable { * * @param key the key to get the object of in this registry * @return the object for the key - * @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry + * @throws NoSuchElementException if the key doesn't point to an object in the registry */ - default @NotNull T getOrThrow(final io.papermc.paper.registry.@NotNull TypedKey key) { + default T getOrThrow(final TypedKey key) { final T value = this.get(key); if (value == null) { - throw new java.util.NoSuchElementException("No value for " + key + " in " + this); + throw new NoSuchElementException("No value for " + key + " in " + this); } return value; } @@ -447,14 +437,13 @@ public interface Registry extends Iterable { * * @param value the value to get the key of in this registry * @return the key for the value - * @throws java.util.NoSuchElementException if the value doesn't exist in this registry + * @throws NoSuchElementException if the value doesn't exist in this registry * @see #getKey(Keyed) */ - default @NotNull NamespacedKey getKeyOrThrow(final @NotNull T value) { - Preconditions.checkArgument(value != null, "value cannot be null"); + default NamespacedKey getKeyOrThrow(final T value) { final NamespacedKey key = this.getKey(value); if (key == null) { - throw new java.util.NoSuchElementException(value + " has no key in " + this); + throw new NoSuchElementException(value + " has no key in " + this); } return key; } @@ -470,14 +459,7 @@ public interface Registry extends Iterable { * @return the key for the value or null if not in the registry * @see #getKeyOrThrow(Keyed) */ - default @Nullable NamespacedKey getKey(final @NotNull T value) { - Preconditions.checkArgument(value != null, "value cannot be null"); - //noinspection ConstantValue (it might not be in the future...) - if (value instanceof Keyed) { - return value.getKey(); - } - return null; - } + @Nullable NamespacedKey getKey(T value); // Paper end - improve Registry // Paper start - RegistrySet API @@ -486,46 +468,52 @@ public interface Registry extends Iterable { * * @param key the key to check for * @return true if this registry has a tag with the given key, false otherwise - * @see #getTag(io.papermc.paper.registry.tag.TagKey) + * @throws UnsupportedOperationException if this registry doesn't have or support tags + * @see #getTag(TagKey) */ @ApiStatus.Experimental - default boolean hasTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { - throw new UnsupportedOperationException(this + " doesn't have tags"); - } + boolean hasTag(TagKey key); /** * Gets the named registry set (tag) for the given key. * * @param key the key to get the tag for * @return the tag for the key - * @throws java.util.NoSuchElementException if no tag with the given key is found - * @throws UnsupportedOperationException if this registry doesn't have or support tags - * @see #hasTag(io.papermc.paper.registry.tag.TagKey) + * @throws NoSuchElementException if no tag with the given key is found + * @throws UnsupportedOperationException if this registry doesn't have or support tags + * @see #hasTag(TagKey) */ @ApiStatus.Experimental - default @NotNull io.papermc.paper.registry.tag.Tag getTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { - throw new UnsupportedOperationException(this + " doesn't have tags"); - } + Tag getTag(TagKey key); + + /** + * Gets all the tags in this registry. + * + * @return a stream of all tags in this registry + * @throws UnsupportedOperationException if this registry doesn't have or support tags + */ + @ApiStatus.Experimental + Collection> getTags(); // Paper end - RegistrySet API /** * Get the object by its key. - * + *

* If there is no object with the given key, an exception will be thrown. * * @param key to get the object from * @return object with the given key - * @throws IllegalArgumentException if there is no object with the given key + * @throws NoSuchElementException if there is no object with the given key */ - @NotNull - T getOrThrow(@NotNull NamespacedKey key); + default T getOrThrow(final NamespacedKey key) { + return this.getOrThrow((Key) key); + } /** * Returns a new stream, which contains all registry items, which are registered to the registry. * * @return a stream of all registry items */ - @NotNull Stream stream(); /** @@ -539,64 +527,47 @@ public interface Registry extends Iterable { * @deprecated this method's behavior is broken and not useful. If you want to get an object * based on its vanilla name, or a key, wrap it in a {@link NamespacedKey} object and use {@link #get(NamespacedKey)} */ - @Nullable - @Deprecated(forRemoval = true) // Paper - default T match(@NotNull String input) { + // Paper + @Deprecated(forRemoval = true) + default @Nullable T match(final String input) { Preconditions.checkArgument(input != null, "input must not be null"); - String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_"); - NamespacedKey namespacedKey = NamespacedKey.fromString(filtered); - return (namespacedKey != null) ? get(namespacedKey) : null; + final String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_"); + final NamespacedKey namespacedKey = NamespacedKey.fromString(filtered); + return (namespacedKey != null) ? this.get(namespacedKey) : null; } - class SimpleRegistry & Keyed> implements Registry { // Paper - remove final + @ApiStatus.Internal + class SimpleRegistry & Keyed> extends NotARegistry { // Paper - remove final private final Class type; private final Map map; - protected SimpleRegistry(@NotNull Class type) { - this(type, Predicates.alwaysTrue()); + protected SimpleRegistry(final Class type) { + this(type, Predicates.alwaysTrue()); } - protected SimpleRegistry(@NotNull Class type, @NotNull Predicate predicate) { - ImmutableMap.Builder builder = ImmutableMap.builder(); + protected SimpleRegistry(final Class type, final Predicate predicate) { + final ImmutableMap.Builder builder = ImmutableMap.builder(); - for (T entry : type.getEnumConstants()) { + for (final T entry : type.getEnumConstants()) { if (predicate.test(entry)) { builder.put(entry.getKey(), entry); } } - map = builder.build(); + this.map = builder.build(); this.type = type; } - @Nullable @Override - public T get(@NotNull NamespacedKey key) { - return map.get(key); + public @Nullable T get(final NamespacedKey key) { + return this.map.get(key); } - @NotNull - @Override - public T getOrThrow(@NotNull NamespacedKey key) { - T object = get(key); - - Preconditions.checkArgument(object != null, "No %s registry entry found for key %s.", type, key); - - return object; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { - return map.values().iterator(); + return this.map.values().iterator(); } @ApiStatus.Internal @@ -604,12 +575,34 @@ public interface Registry extends Iterable { public Class getType() { return this.type; } + } + + @ApiStatus.Internal + abstract class NotARegistry implements Registry { - // Paper start - improve Registry @Override - public @NotNull NamespacedKey getKey(final @NotNull T value) { + public Stream stream() { + return StreamSupport.stream(this.spliterator(), false); + } + + @Override + public NamespacedKey getKey(final A value) { return value.getKey(); } - // Paper end - improve Registry + + @Override + public boolean hasTag(final TagKey key) { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } + + @Override + public Tag getTag(final TagKey key) { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } + + @Override + public Collection> getTags() { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java index cc39bc68d..7c3fdfb46 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java @@ -3,6 +3,7 @@ package io.papermc.paper.registry; import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; +import java.util.Collection; import java.util.function.Predicate; import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; @@ -51,4 +52,9 @@ public class PaperSimpleRegistry & Keyed, M> extends Registry. final HolderSet.Named namedHolderSet = this.nmsRegistry.get(PaperRegistries.toNms(key)).orElseThrow(); return new NamedRegistryKeySetImpl<>(key, namedHolderSet); } + + @Override + public Collection> getTags() { + return this.nmsRegistry.getTags().>map(NamedRegistryKeySetImpl::new).toList(); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java index fdc475f2b..527fbbbbe 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java @@ -2,6 +2,7 @@ package io.papermc.paper.registry.legacy; import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; +import java.util.Collection; import java.util.Iterator; import java.util.function.Supplier; import java.util.stream.Stream; @@ -38,11 +39,6 @@ public final class DelayedRegistry> imple return this.delegate().get(key); } - @Override - public T getOrThrow(final NamespacedKey key) { - return this.delegate().getOrThrow(key); - } - @Override public Iterator iterator() { return this.delegate().iterator(); @@ -67,4 +63,9 @@ public final class DelayedRegistry> imple public @NonNull Tag getTag(final TagKey key) { return this.delegate().getTag(key); } + + @Override + public Collection> getTags() { + return this.delegate().getTags(); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java index 7b15640c2..79499fa90 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java @@ -26,6 +26,10 @@ public record NamedRegistryKeySetImpl( // TODO remove Keyed HolderSet.Named namedSet ) implements Tag, org.bukkit.Tag { + public NamedRegistryKeySetImpl(final HolderSet.Named namedSet) { + this(PaperRegistries.fromNms(namedSet.key()), namedSet); + } + @Override public @Unmodifiable Collection> values() { final ImmutableList.Builder> builder = ImmutableList.builder(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index 332215f8b..2762dd259 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -2,7 +2,10 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; import io.papermc.paper.registry.entry.RegistryEntryMeta; +import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; +import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.util.Holderable; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -10,59 +13,16 @@ import java.util.function.BiFunction; import java.util.stream.Stream; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; -import org.bukkit.Art; -import org.bukkit.Fluid; -import org.bukkit.GameEvent; -import org.bukkit.JukeboxSong; import org.bukkit.Keyed; -import org.bukkit.MusicInstrument; import org.bukkit.NamespacedKey; import org.bukkit.Particle; import org.bukkit.Registry; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.block.Biome; -import org.bukkit.block.BlockType; -import org.bukkit.block.banner.PatternType; -import org.bukkit.craftbukkit.attribute.CraftAttribute; -import org.bukkit.craftbukkit.block.CraftBiome; -import org.bukkit.craftbukkit.block.CraftBlockType; -import org.bukkit.craftbukkit.block.banner.CraftPatternType; -import org.bukkit.craftbukkit.damage.CraftDamageType; -import org.bukkit.craftbukkit.enchantments.CraftEnchantment; -import org.bukkit.craftbukkit.entity.CraftCat; -import org.bukkit.craftbukkit.entity.CraftFrog; -import org.bukkit.craftbukkit.entity.CraftVillager; -import org.bukkit.craftbukkit.entity.CraftWolf; -import org.bukkit.craftbukkit.generator.structure.CraftStructure; -import org.bukkit.craftbukkit.generator.structure.CraftStructureType; -import org.bukkit.craftbukkit.inventory.CraftItemType; -import org.bukkit.craftbukkit.inventory.CraftMenuType; -import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial; -import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern; import org.bukkit.craftbukkit.legacy.FieldRename; -import org.bukkit.craftbukkit.map.CraftMapCursor; -import org.bukkit.craftbukkit.potion.CraftPotionEffectType; import org.bukkit.craftbukkit.util.ApiVersion; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.craftbukkit.util.Handleable; -import org.bukkit.damage.DamageType; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Cat; import org.bukkit.entity.EntityType; -import org.bukkit.entity.Frog; -import org.bukkit.entity.Villager; -import org.bukkit.entity.Wolf; -import org.bukkit.generator.structure.Structure; -import org.bukkit.generator.structure.StructureType; -import org.bukkit.inventory.ItemType; -import org.bukkit.inventory.MenuType; -import org.bukkit.inventory.meta.trim.TrimMaterial; -import org.bukkit.inventory.meta.trim.TrimPattern; -import org.bukkit.map.MapCursor; -import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; public class CraftRegistry implements Registry { @@ -304,7 +264,7 @@ public class CraftRegistry implements Registry { if (value instanceof Holderable holderable) { return holderable.getKeyOrNull(); } - return Registry.super.getKey(value); + return value.getKey(); } // Paper end - improve Registry @@ -319,5 +279,10 @@ public class CraftRegistry implements Registry { final net.minecraft.core.HolderSet.Named namedHolderSet = this.minecraftRegistry.get(io.papermc.paper.registry.PaperRegistries.toNms(key)).orElseThrow(); return new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(key, namedHolderSet); } + + @Override + public Collection> getTags() { + return this.minecraftRegistry.getTags().>map(NamedRegistryKeySetImpl::new).toList(); + } // Paper end - RegistrySet API } From d85d318951a3758f8a532797da46eeb729a20732 Mon Sep 17 00:00:00 2001 From: Maddy Miller Date: Thu, 26 Dec 2024 18:41:37 +1000 Subject: [PATCH 07/40] Fix NullPointerException in PlayerInteractEvent#getClickedPosition (#11827) Fixes a NullPointerException in PlayerInteractEvent#getClickedPosition Re: https://github.com/EngineHub/CraftBook/issues/1340 --- .../main/java/org/bukkit/event/player/PlayerInteractEvent.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java index 5e52f4dc2..759aaa935 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java @@ -241,6 +241,9 @@ public class PlayerInteractEvent extends PlayerEvent implements Cancellable { @Nullable @Deprecated // Paper public Vector getClickedPosition() { + if (this.clickedPosistion == null) { + return null; + } return clickedPosistion.clone(); } From 3331805d0b4a780284bc7a0918d767063738a150 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:24:02 +0100 Subject: [PATCH 08/40] Deprecate #furnace_materials item tag (#11823) --- paper-api/src/main/java/org/bukkit/Tag.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Tag.java b/paper-api/src/main/java/org/bukkit/Tag.java index 961a36e03..193858a28 100644 --- a/paper-api/src/main/java/org/bukkit/Tag.java +++ b/paper-api/src/main/java/org/bukkit/Tag.java @@ -1050,9 +1050,16 @@ public interface Tag extends Keyed { */ Tag ITEMS_REPAIRS_WOLF_ARMOR = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("repairs_wolf_armor"), Material.class); /** - * Vanilla item tag representing all furnace materials. + * Vanilla item tag representing all stone based materials for crafting. */ - Tag ITEMS_FURNACE_MATERIALS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("furnace_materials"), Material.class); + Tag ITEMS_STONE_CRAFTING_MATERIALS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("stone_crafting_materials"), Material.class); + /** + * Vanilla item tag representing all furnace materials. + * + * @deprecated partially replaced by {@link #ITEMS_STONE_CRAFTING_MATERIALS} + */ + @Deprecated(since = "1.16.2", forRemoval = true) + Tag ITEMS_FURNACE_MATERIALS = ITEMS_STONE_CRAFTING_MATERIALS; /** * Vanilla item tag representing all compasses. */ From c9a904ed17eb8d86ef8425c04900b5cf01d5d80c Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Thu, 26 Dec 2024 15:19:56 +0000 Subject: [PATCH 09/40] Fix keepalive logic resetting counter This would of actually arised in the client being kicked due to sending bad keepalive packets due to the erronious extra sending of keepalives too --- .../network/ServerCommonPacketListenerImpl.java.patch | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index e21dc4c54..af6cdd217 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -95,7 +95,7 @@ } } -@@ -88,30 +_,117 @@ +@@ -88,30 +_,119 @@ public void handlePong(ServerboundPongPacket packet) { } @@ -208,15 +208,16 @@ Profiler.get().push("keepAlive"); long millis = Util.getMillis(); - if (!this.isSingleplayerOwner() && millis - this.keepAliveTime >= 15000L) { -- if (this.keepAlivePending) { -- this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE); + // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings + // This should effectively place the keepalive handling back to "as it was" before 1.12.2 + final long elapsedTime = millis - this.keepAliveTime; + if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets -+ if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + if (this.keepAlivePending) { +- this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE); ++ if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected ++ this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause ++ } + // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings -+ this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause } else if (this.checkIfClosed(millis)) { this.keepAlivePending = true; this.keepAliveTime = millis; From a8f850a128307bef089738b6b4f37f17f4b87960 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 26 Dec 2024 10:11:18 -0800 Subject: [PATCH 10/40] temporarily revert OldEnum toString changes (#11829) --- .../java/io/papermc/paper/util/OldEnumHolderable.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/util/OldEnumHolderable.java b/paper-server/src/main/java/io/papermc/paper/util/OldEnumHolderable.java index 1e7014684..0c4ddd9ea 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/OldEnumHolderable.java +++ b/paper-server/src/main/java/io/papermc/paper/util/OldEnumHolderable.java @@ -9,7 +9,7 @@ import org.bukkit.util.OldEnum; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; -@SuppressWarnings("removal") +@SuppressWarnings({"removal", "DeprecatedIsStillUsed"}) @Deprecated @NullMarked public abstract class OldEnumHolderable, M> implements Holderable, OldEnum, Keyed { @@ -43,7 +43,7 @@ public abstract class OldEnumHolderable, M> implements Hold @Override @Deprecated - public int compareTo(A other) { + public int compareTo(final A other) { this.checkIsReference(); return this.ordinal - other.ordinal(); } @@ -83,6 +83,10 @@ public abstract class OldEnumHolderable, M> implements Hold @Override public String toString() { + if (this.name != null) { + // TODO remove in next feature release or 1.22 + return this.name; + } return this.implToString(); } } From a14c06bbd8d8c5e2ec4b93f05eafe37a46791e8f Mon Sep 17 00:00:00 2001 From: Yannick Lamprecht <1420893+yannicklamprecht@users.noreply.github.com> Date: Thu, 26 Dec 2024 19:22:00 +0100 Subject: [PATCH 11/40] fix annotation test for null marked inner classes (#11826) --- paper-api/src/test/java/org/bukkit/AnnotationTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/paper-api/src/test/java/org/bukkit/AnnotationTest.java b/paper-api/src/test/java/org/bukkit/AnnotationTest.java index 5b0d26c68..37feafd62 100644 --- a/paper-api/src/test/java/org/bukkit/AnnotationTest.java +++ b/paper-api/src/test/java/org/bukkit/AnnotationTest.java @@ -205,14 +205,16 @@ public class AnnotationTest { // Paper start - skip class if it's @NullMarked private static boolean isClassNullMarked(@NotNull ClassNode clazz, @NotNull Map allClasses) { + if (isClassNullMarked0(clazz)) { + return true; + } if (clazz.nestHostClass != null) { final ClassNode nestHostNode = allClasses.get(clazz.nestHostClass); if (nestHostNode != null) { - return isClassNullMarked0(nestHostNode); + return isClassNullMarked(nestHostNode, allClasses); } } - - return isClassNullMarked0(clazz); + return false; } private static boolean isClassNullMarked0(@NotNull ClassNode clazz) { From f51aa3e3e1235d160f71fbfec8284c8327bf00ab Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Thu, 26 Dec 2024 19:42:03 +0100 Subject: [PATCH 12/40] Fix BlockRedstoneEvent for tripwire hooks (#11791) --- .../level/block/TripWireHookBlock.java.patch | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch index 661176a03..225f53b41 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch @@ -1,21 +1,65 @@ --- a/net/minecraft/world/level/block/TripWireHookBlock.java +++ b/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -173,9 +_,18 @@ +@@ -127,10 +_,10 @@ + if (optionalValue.isPresent()) { + Direction direction = optionalValue.get(); + boolean flag = hookState.getOptionalValue(ATTACHED).orElse(false); +- boolean flag1 = hookState.getOptionalValue(POWERED).orElse(false); ++ boolean flag1 = hookState.getOptionalValue(POWERED).orElse(false); // Paper - diff on change, for event below + Block block = hookState.getBlock(); + boolean flag2 = !attaching; +- boolean flag3 = false; ++ boolean flag3 = false; // Paper - diff on change, for event below + int i = 0; + BlockState[] blockStates = new BlockState[42]; + +@@ -166,21 +_,48 @@ + flag2 &= i > 1; + flag3 &= flag2; + BlockState blockState1 = block.defaultBlockState().trySetValue(ATTACHED, Boolean.valueOf(flag2)).trySetValue(POWERED, Boolean.valueOf(flag3)); ++ boolean cancelledEmitterHook = false, cancelledReceiverHook = false; // Paper - Call BlockRedstoneEvent ++ boolean wasPowered = flag1, willBePowered = flag3; // Paper - OBFHELPER + if (i > 0) { + BlockPos blockPosx = pos.relative(direction, i); ++ // Paper start - Call BlockRedstoneEvent ++ if (wasPowered != willBePowered) { ++ int newCurrent = willBePowered ? 15 : 0; ++ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent( ++ org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPosx), wasPowered ? 15 : 0, newCurrent ++ ); ++ event.callEvent(); ++ cancelledReceiverHook = event.getNewCurrent() != newCurrent; ++ } ++ if (!cancelledReceiverHook) { // always trigger two events even when the first hook current change is cancelled ++ // Paper end - Call BlockRedstoneEvent + Direction opposite = direction.getOpposite(); + level.setBlock(blockPosx, blockState1.setValue(FACING, opposite), 3); notifyNeighbors(block, level, blockPosx, opposite); emitState(level, blockPosx, flag2, flag3, flag, flag1); - } -+ // CraftBukkit start -+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), 15, 0); -+ level.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if (eventRedstone.getNewCurrent() > 0) { -+ return; +- } ++ } // Paper - Call BlockRedstoneEvent + } -+ // CraftBukkit end ++ // Paper start - Call BlockRedstoneEvent ++ if (wasPowered != willBePowered) { ++ int newCurrent = willBePowered ? 15 : 0; ++ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent( ++ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), wasPowered ? 15 : 0, newCurrent ++ ); ++ event.callEvent(); ++ cancelledEmitterHook = event.getNewCurrent() != newCurrent; ++ } ++ // Paper end - Call BlockRedstoneEvent ++ if (!cancelledEmitterHook) { // Paper - Call BlockRedstoneEvent emitState(level, pos, flag2, flag3, flag, flag1); if (!attaching) { + if (level.getBlockState(pos).is(Blocks.TRIPWIRE_HOOK)) // Paper - Validate tripwire hook placement before update level.setBlock(pos, blockState1.setValue(FACING, direction), 3); if (shouldNotifyNeighbours) { notifyNeighbors(block, level, pos, direction); + } + } ++ } // Paper - Call BlockRedstoneEvent + + if (flag != flag2) { + for (int i2 = 1; i2 < i; i2++) { From af2812fb0f14acea697f3ff6b7b56ffd14900041 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 26 Dec 2024 13:41:15 -0800 Subject: [PATCH 13/40] For new registry values, allow copying from existing (#11796) Co-authored-by: Bjarne Koll --- .../registry/RegistryBuilderFactory.java | 39 ++++++++++++++ .../papermc/paper/registry/RegistryKey.java | 24 +++++++++ .../io/papermc/paper/registry/TypedKey.java | 15 ++++++ .../registry/event/WritableRegistry.java | 16 +++++- .../0017-Moonrise-optimisation-patches.patch | 8 +-- .../minecraft/core/MappedRegistry.java.patch | 25 ++++++++- .../registry/PaperRegistryBuilderFactory.java | 51 +++++++++++++++++++ .../paper/registry/WritableCraftRegistry.java | 19 ++----- 8 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/RegistryBuilderFactory.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java diff --git a/paper-api/src/main/java/io/papermc/paper/registry/RegistryBuilderFactory.java b/paper-api/src/main/java/io/papermc/paper/registry/RegistryBuilderFactory.java new file mode 100644 index 000000000..ce2447d3d --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/RegistryBuilderFactory.java @@ -0,0 +1,39 @@ +package io.papermc.paper.registry; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * A factory to create a {@link RegistryBuilder} for a given {@link TypedKey}. For + * each instance of this class, once either {@link #empty()} or {@link #copyFrom(TypedKey)} + * is called once, any future calls to either method will throw an {@link IllegalStateException}. + * + * @param The type of the registry + * @param The type of the registry builder + */ +@NullMarked +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface RegistryBuilderFactory> { + + /** + * Creates a new empty {@link RegistryBuilder}. + * + * @return A new empty {@link RegistryBuilder} + * @throws IllegalStateException if this method or {@link #copyFrom(TypedKey)}) has already been called once + */ + @Contract("-> new") + B empty(); + + /** + * Creates a new {@link RegistryBuilder} with the same properties as the given {@link TypedKey}. + * + * @param key The key to copy properties from + * @return A new {@link RegistryBuilder} with the same properties as the given key + * @throws IllegalStateException if this method or {@link #empty()} has already been called once + * @throws IllegalArgumentException if key doesn't exist + */ + @Contract("_ -> new") + B copyFrom(TypedKey key); +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java index e5319bdb9..ea795de95 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -1,6 +1,8 @@ package io.papermc.paper.registry; import io.papermc.paper.datacomponent.DataComponentType; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import net.kyori.adventure.key.Keyed; import org.bukkit.Art; import org.bukkit.Fluid; @@ -200,4 +202,26 @@ public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { RegistryKey PARTICLE_TYPE = create("particle_type"); RegistryKey POTION = create("potion"); RegistryKey> MEMORY_MODULE_TYPE = create("memory_module_type"); + + /** + * Constructs a new {@link TypedKey} for this registry given the typed key's key. + * + * @param key the key of the typed key. + * @return the constructed typed key. + */ + @ApiStatus.Experimental + default TypedKey typedKey(final Key key) { + return TypedKey.create(this, key); + } + + /** + * Constructs a new {@link TypedKey} for this registry given the typed key's key. + * + * @param key the string representation of the key that will be passed to {@link Key#key(String)}. + * @return the constructed typed key. + */ + @ApiStatus.Experimental + default TypedKey typedKey(final @KeyPattern String key) { + return TypedKey.create(this, key); + } } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java b/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java index 81bee5224..c8f363a24 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java @@ -1,6 +1,7 @@ package io.papermc.paper.registry; import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import net.kyori.adventure.key.Keyed; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -42,4 +43,18 @@ public sealed interface TypedKey extends Key permits TypedKeyImpl { static TypedKey create(final RegistryKey registryKey, final Key key) { return new TypedKeyImpl<>(key, registryKey); } + + /** + * Create a typed key from a string and a registry key. + * + * @param registryKey the registry this key is for + * @param key the string version of a {@link Key} that will be passed to {@link Key#key(String)} for parsing. + * @param value type + * @return a new key for the value key and registry key + * @see Key#key(String) + */ + @ApiStatus.Experimental + static TypedKey create(final RegistryKey registryKey, final @KeyPattern String key) { + return create(registryKey, Key.key(key)); + } } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java index 744f455b1..fed7ad660 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java @@ -1,6 +1,7 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilderFactory; import io.papermc.paper.registry.TypedKey; import java.util.function.Consumer; import org.jetbrains.annotations.ApiStatus; @@ -24,5 +25,18 @@ public interface WritableRegistry> { * @param key the entry's key (must be unique from others) * @param value a consumer for the entry's builder */ - void register(TypedKey key, Consumer value); + default void register(final TypedKey key, final Consumer value) { + this.registerWith(key, factory -> value.accept(factory.empty())); + } + + /** + * Register a new value with the specified key. This will + * fire a {@link RegistryEntryAddEvent} for the new entry. The + * {@link RegistryBuilderFactory} lets you pre-fill a builder with + * an already-existing entry's properties. + * + * @param key the entry's key (must be unique from others) + * @param value a consumer of a builder factory + */ + void registerWith(TypedKey key, Consumer> value); } diff --git a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch index 337302aaa..45b4a15fe 100644 --- a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch @@ -23508,10 +23508,10 @@ index 3d3eec1db91cb47395f40c4f47aa77164ad42175..216f97207dac88cc1dc3df59c6ee8a62 + // Paper end - optimise collisions } diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java -index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff642b19ed 100644 +index 452c358c2cfa0c39e0b09853cd4a9a12c6ced65d..5f752603aa5611ce9d3dd44cc5b70c27ac46a86e 100644 --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { +@@ -51,6 +51,19 @@ public class MappedRegistry implements WritableRegistry { return this.getTags(); } @@ -23531,10 +23531,10 @@ index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff public MappedRegistry(ResourceKey> key, Lifecycle registryLifecycle) { this(key, registryLifecycle, false); } -@@ -114,6 +127,7 @@ public class MappedRegistry implements WritableRegistry { - this.toId.put(value, size); +@@ -116,6 +129,7 @@ public class MappedRegistry implements WritableRegistry { this.registrationInfos.put(key, registrationInfo); this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle()); + this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API + this.injectFluidRegister(key, value); // Paper - fluid method optimisations return reference; } diff --git a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch index 400d714ab..2a92380a2 100644 --- a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -33,11 +_,11 @@ +@@ -33,17 +_,18 @@ public class MappedRegistry implements WritableRegistry { private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); @@ -17,6 +17,29 @@ private Lifecycle registryLifecycle; private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); + private boolean frozen; + @Nullable + private Map> unregisteredIntrusiveHolders; ++ public final Map temporaryUnfrozenMap = new HashMap<>(); // Paper - support pre-filling in registry mod API + + @Override + public Stream> listTags() { +@@ -114,6 +_,7 @@ + this.toId.put(value, size); + this.registrationInfos.put(key, registrationInfo); + this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle()); ++ this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API + return reference; + } + } +@@ -275,6 +_,7 @@ + return this; + } else { + this.frozen = true; ++ this.temporaryUnfrozenMap.clear(); // Paper - support pre-filling in registry mod API + this.byValue.forEach((object, reference) -> reference.bindValue((T)object)); + List list = this.byKey + .entrySet() @@ -509,4 +_,13 @@ Stream> getTags(); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java new file mode 100644 index 000000000..e83a6336b --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java @@ -0,0 +1,51 @@ +package io.papermc.paper.registry; + +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.data.util.Conversions; +import java.util.function.Function; +import net.minecraft.resources.ResourceLocation; +import org.bukkit.Keyed; +import org.jspecify.annotations.Nullable; + +public class PaperRegistryBuilderFactory> implements RegistryBuilderFactory { // TODO remove Keyed + + private final Conversions conversions; + private final PaperRegistryBuilder.Filler builderFiller; + private final Function existingValueGetter; + private @Nullable B builder; + + public PaperRegistryBuilderFactory(final Conversions conversions, final PaperRegistryBuilder.Filler builderFiller, final Function existingValueGetter) { + this.conversions = conversions; + this.builderFiller = builderFiller; + this.existingValueGetter = existingValueGetter; + } + + private void validate() { + if (this.builder != null) { + throw new IllegalStateException("Already created a builder"); + } + } + + public B requireBuilder() { + if (this.builder == null) { + throw new IllegalStateException("Builder not created yet"); + } + return this.builder; + } + + @Override + public B empty() { + this.validate(); + return this.builder = this.builderFiller.create(this.conversions); + } + + @Override + public B copyFrom(final TypedKey key) { + this.validate(); + final M existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(key)); + if (existing == null) { + throw new IllegalArgumentException("Key " + key + " doesn't exist"); + } + return this.builder = this.builderFiller.fill(this.conversions, existing); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java index 6c17623e7..a294ec37b 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java @@ -2,20 +2,15 @@ package io.papermc.paper.registry; import com.mojang.serialization.Lifecycle; import io.papermc.paper.registry.data.util.Conversions; -import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntryMeta; -import io.papermc.paper.registry.entry.RegistryTypeMapper; import io.papermc.paper.registry.event.WritableRegistry; import java.util.Optional; -import java.util.function.BiFunction; import java.util.function.Consumer; import net.minecraft.core.MappedRegistry; import net.minecraft.core.RegistrationInfo; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.ApiVersion; public class WritableCraftRegistry> extends CraftRegistry { @@ -33,16 +28,16 @@ public class WritableCraftRegistry key, final Consumer value, final Conversions conversions) { + public void register(final TypedKey key, final Consumer> value, final Conversions conversions) { final ResourceKey resourceKey = PaperRegistries.toNms(key); this.registry.validateWrite(resourceKey); - final B builder = this.newBuilder(conversions); - value.accept(builder); + final PaperRegistryBuilderFactory builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta.builderFiller(), this.registry.temporaryUnfrozenMap::get); + value.accept(builderFactory); PaperRegistryListenerManager.INSTANCE.registerWithListeners( this.registry, this.meta, resourceKey, - builder, + builderFactory.requireBuilder(), FROM_PLUGIN, conversions ); @@ -52,10 +47,6 @@ public class WritableCraftRegistry { private final Conversions conversions; @@ -65,7 +56,7 @@ public class WritableCraftRegistry key, final Consumer value) { + public void registerWith(final TypedKey key, final Consumer> value) { WritableCraftRegistry.this.register(key, value, this.conversions); } } From 0efd3012c9647844117524dfa5ee66447469aab6 Mon Sep 17 00:00:00 2001 From: YoungSoulluoS <70120313+YoungSoulluoS@users.noreply.github.com> Date: Fri, 27 Dec 2024 04:07:02 +0500 Subject: [PATCH 14/40] Fix suggestions for ResourceLocation (#11830) --- .../io/papermc/paper/command/subcommands/EntityCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java b/paper-server/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java index f671b74e4..bbd29bcca 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java @@ -48,7 +48,7 @@ public final class EntityCommand implements PaperSubcommand { if (args.length == 1) { return CommandUtil.getListMatchingLast(sender, args, "help", "list"); } else if (args.length == 2) { - return CommandUtil.getListMatchingLast(sender, args, BuiltInRegistries.ENTITY_TYPE.keySet().stream().map(ResourceLocation::toString).sorted().toArray(String[]::new)); + return CommandUtil.getListMatchingLast(sender, args, BuiltInRegistries.ENTITY_TYPE.keySet()); } return Collections.emptyList(); } From aac246ae29349b04334529fe12f88aa3cd8e0c7c Mon Sep 17 00:00:00 2001 From: SoSeDiK Date: Fri, 27 Dec 2024 01:08:00 +0200 Subject: [PATCH 15/40] Expand on entity serialization API (#11807) --- .../paper/entity/EntitySerializationFlag.java | 38 ++++++ .../main/java/org/bukkit/UnsafeValues.java | 77 +++++++++++- .../main/java/org/bukkit/entity/Entity.java | 19 +-- .../0017-Moonrise-optimisation-patches.patch | 20 +-- .../minecraft/world/entity/Entity.java.patch | 63 +++++----- .../craftbukkit/entity/CraftEntity.java | 15 ++- .../entity/CraftEntitySnapshot.java | 2 +- .../craftbukkit/util/CraftMagicNumbers.java | 118 +++++++++++++++--- 8 files changed, 275 insertions(+), 77 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/entity/EntitySerializationFlag.java diff --git a/paper-api/src/main/java/io/papermc/paper/entity/EntitySerializationFlag.java b/paper-api/src/main/java/io/papermc/paper/entity/EntitySerializationFlag.java new file mode 100644 index 000000000..4a76c3491 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/entity/EntitySerializationFlag.java @@ -0,0 +1,38 @@ +package io.papermc.paper.entity; + +import org.bukkit.UnsafeValues; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Represents flags for entity serialization. + * + * @see UnsafeValues#serializeEntity(Entity, EntitySerializationFlag... serializationFlags) + * @since 1.21.4 + */ +public enum EntitySerializationFlag { + + /** + * Serialize entities that wouldn't be serialized normally + * (e.g. dead, despawned, non-persistent, etc.). + * + * @see Entity#isValid() + * @see Entity#isPersistent() + */ + FORCE, + /** + * Serialize misc non-saveable entities like lighting bolts, fishing bobbers, etc. + *
Note: players require a separate flag: {@link #PLAYER}. + */ + MISC, + /** + * Include passengers in the serialized data. + */ + PASSENGERS, + /** + * Allow serializing {@link Player}s. + *

Note: deserializing player data will always fail. + */ + PLAYER + +} diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java index d0de7ce3c..56fa266e4 100644 --- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java +++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java @@ -1,6 +1,7 @@ package org.bukkit; import com.google.common.collect.Multimap; +import io.papermc.paper.entity.EntitySerializationFlag; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; @@ -9,7 +10,9 @@ import org.bukkit.block.data.BlockData; import org.bukkit.damage.DamageEffect; import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageType; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.inventory.CreativeCategory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -198,13 +201,81 @@ public interface UnsafeValues { */ @NotNull ItemStack deserializeItemFromJson(@NotNull com.google.gson.JsonObject data) throws IllegalArgumentException; - byte[] serializeEntity(org.bukkit.entity.Entity entity); + /** + * Serializes the provided entity. + * + * @param entity entity + * @return serialized entity data + * @see #serializeEntity(Entity, EntitySerializationFlag...) + * @see #deserializeEntity(byte[], World, boolean, boolean) + * @throws IllegalArgumentException if couldn't serialize the entity + * @since 1.17.1 + */ + default byte @NotNull [] serializeEntity(@NotNull Entity entity) { + return serializeEntity(entity, new EntitySerializationFlag[0]); + } - default org.bukkit.entity.Entity deserializeEntity(byte[] data, World world) { + /** + * Serializes the provided entity. + * + * @param entity entity + * @param serializationFlags serialization flags + * @return serialized entity data + * @throws IllegalArgumentException if couldn't serialize the entity + * @see #deserializeEntity(byte[], World, boolean, boolean) + * @since 1.21.4 + */ + byte @NotNull [] serializeEntity(@NotNull Entity entity, @NotNull EntitySerializationFlag... serializationFlags); + + /** + * Deserializes the entity from data. + *
The entity's {@link java.util.UUID} as well as passengers will not be preserved. + * + * @param data serialized entity data + * @param world world + * @return deserialized entity + * @throws IllegalArgumentException if invalid serialized entity data provided + * @see #deserializeEntity(byte[], World, boolean, boolean) + * @see #serializeEntity(Entity, EntitySerializationFlag...) + * @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason) + * @since 1.17.1 + */ + default @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world) { return deserializeEntity(data, world, false); } - org.bukkit.entity.Entity deserializeEntity(byte[] data, World world, boolean preserveUUID); + /** + * Deserializes the entity from data. + *
The entity's passengers will not be preserved. + * + * @param data serialized entity data + * @param world world + * @param preserveUUID whether to preserve the entity's uuid + * @return deserialized entity + * @throws IllegalArgumentException if invalid serialized entity data provided + * @see #deserializeEntity(byte[], World, boolean, boolean) + * @see #serializeEntity(Entity, EntitySerializationFlag...) + * @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason) + * @since 1.17.1 + */ + default @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID) { + return deserializeEntity(data, world, preserveUUID, false); + } + + /** + * Deserializes the entity from data. + * + * @param data serialized entity data + * @param world world + * @param preserveUUID whether to preserve uuids of the entity and its passengers + * @param preservePassengers whether to preserve passengers + * @return deserialized entity + * @throws IllegalArgumentException if invalid serialized entity data provided + * @see #serializeEntity(Entity, EntitySerializationFlag...) + * @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason) + * @since 1.21.4 + */ + @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID, boolean preservePassengers); /** * Creates and returns the next EntityId available. diff --git a/paper-api/src/main/java/org/bukkit/entity/Entity.java b/paper-api/src/main/java/org/bukkit/entity/Entity.java index 3fe738c0d..ddf7829ee 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -14,6 +14,7 @@ import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.block.PistonMoveReaction; import org.bukkit.command.CommandSender; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.material.Directional; @@ -1072,11 +1073,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent *

* Also, this method will fire the same events as a normal entity spawn. * - * @param location The location to spawn the entity at. - * @return Whether the entity was successfully spawned. + * @param location the location to spawn the entity at + * @return whether the entity was successfully spawned + * @since 1.17.1 */ - public default boolean spawnAt(@NotNull Location location) { - return spawnAt(location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); + default boolean spawnAt(@NotNull Location location) { + return spawnAt(location, CreatureSpawnEvent.SpawnReason.DEFAULT); } /** @@ -1086,11 +1088,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent *

* Also, this method will fire the same events as a normal entity spawn. * - * @param location The location to spawn the entity at. - * @param reason The reason for the entity being spawned. - * @return Whether the entity was successfully spawned. + * @param location the location to spawn the entity at + * @param reason the reason for the entity being spawned + * @return whether the entity was successfully spawned + * @since 1.17.1 */ - public boolean spawnAt(@NotNull Location location, @NotNull org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason); + boolean spawnAt(@NotNull Location location, @NotNull CreatureSpawnEvent.SpawnReason reason); /** * Check if entity is inside powdered snow. diff --git a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch index 45b4a15fe..93faf3756 100644 --- a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch @@ -26719,7 +26719,7 @@ index 2f49dbc919f7f5eea9abce6106723c72f5ae45fb..87d4291a3944f706a694536da6de0f28 } } diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index 70f6d068b3f3665b282d9750310c883839120ab2..870b9efd445ddadb3725e88351555ad986ce7c72 100644 +index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7dfda69f28 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java @@ -91,6 +91,11 @@ public class ServerEntity { @@ -27496,7 +27496,7 @@ index 192977dd661ee795ada13db895db770293e9b402..95a4e37a3c93f9b3c56c7a7376ed521c } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index ff5889f8fed0707a6654d9d21862e32e2ebc866d..e61fe83479f095e8addbd3e8f1d5179c998ae1eb 100644 +index 097ec55166b9e9269142be58992c29687122fe28..aeabb79512aabd7a9e8af1be72e1745f0e7eefe4 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team; @@ -28372,7 +28372,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab6814aef9ee 100644 +index 189385600b9094291152035b17df869eaccc0428..25a1089a7376f0cbd96bb43b5c203640c88fc282 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -28725,7 +28725,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 } private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { -@@ -2664,23 +2812,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2662,23 +2810,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -28849,7 +28849,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4104,15 +4339,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4102,15 +4337,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28875,7 +28875,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 } public int countPlayerPassengers() { -@@ -4250,77 +4487,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4248,77 +4485,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(partialTick, this.yRotO, this.yRot); } @@ -29066,7 +29066,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 public boolean touchingUnloadedChunk() { AABB aabb = this.getBoundingBox().inflate(1.0); -@@ -4473,6 +4769,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4471,6 +4767,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29082,7 +29082,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 if (!checkPosition(this, x, y, z)) { return; } -@@ -4603,6 +4908,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4601,6 +4906,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { @@ -29095,7 +29095,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4614,7 +4925,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4612,7 +4923,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29104,7 +29104,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68 this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); // Paper start - Folia schedulers -@@ -4648,7 +4959,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4646,7 +4957,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index f1de578de..780a51d40 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -706,52 +706,44 @@ public void awardKillScore(Entity entity, DamageSource damageSource) { if (entity instanceof ServerPlayer) { -@@ -1752,34 +_,70 @@ +@@ -1752,15 +_,22 @@ } public boolean saveAsPassenger(CompoundTag compound) { +- if (this.removalReason != null && !this.removalReason.shouldSave()) { + // CraftBukkit start - allow excluding certain data when saving -+ return this.saveAsPassenger(compound, true); ++ // Paper start - Raw entity serialization API ++ return this.saveAsPassenger(compound, true, false, false); + } -+ -+ public boolean saveAsPassenger(CompoundTag compound, boolean includeAll) { ++ public boolean saveAsPassenger(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { ++ // Paper end - Raw entity serialization API + // CraftBukkit end - if (this.removalReason != null && !this.removalReason.shouldSave()) { ++ if (this.removalReason != null && !this.removalReason.shouldSave() && !forceSerialization) { // Paper - Raw entity serialization API return false; } else { - String encodeId = this.getEncodeId(); +- String encodeId = this.getEncodeId(); - if (encodeId == null) { -+ if (!this.persist || encodeId == null) { // CraftBukkit - persist flag ++ String encodeId = this.getEncodeId(includeNonSaveable); // Paper - Raw entity serialization API ++ if ((!this.persist && !forceSerialization) || encodeId == null) { // CraftBukkit - persist flag // Paper - Raw entity serialization API return false; } else { compound.putString("id", encodeId); - this.saveWithoutId(compound); -+ this.saveWithoutId(compound, includeAll); // CraftBukkit - pass on includeAll ++ this.saveWithoutId(compound, includeAll, includeNonSaveable, forceSerialization); // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API return true; } } - } -+ -+ // Paper start - Entity serialization api -+ public boolean serializeEntity(CompoundTag compound) { -+ List pass = new java.util.ArrayList<>(this.getPassengers()); -+ this.passengers = ImmutableList.of(); -+ boolean result = save(compound); -+ this.passengers = ImmutableList.copyOf(pass); -+ return result; -+ } -+ // Paper end - Entity serialization api - - public boolean save(CompoundTag compound) { - return !this.isPassenger() && this.saveAsPassenger(compound); +@@ -1771,15 +_,37 @@ } public CompoundTag saveWithoutId(CompoundTag compound) { + // CraftBukkit start - allow excluding certain data when saving -+ return this.saveWithoutId(compound, true); ++ // Paper start - Raw entity serialization API ++ return this.saveWithoutId(compound, true, false, false); + } + -+ public CompoundTag saveWithoutId(CompoundTag compound, boolean includeAll) { ++ public CompoundTag saveWithoutId(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { ++ // Paper end - Raw entity serialization API + // CraftBukkit end try { - if (this.vehicle != null) { @@ -827,7 +819,7 @@ for (Entity entity : this.getPassengers()) { CompoundTag compoundTag = new CompoundTag(); - if (entity.saveAsPassenger(compoundTag)) { -+ if (entity.saveAsPassenger(compoundTag, includeAll)) { // CraftBukkit - pass on includeAll ++ if (entity.saveAsPassenger(compoundTag, includeAll, includeNonSaveable, forceSerialization)) { // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API listTag.add(compoundTag); } } @@ -935,19 +927,30 @@ } catch (Throwable var17) { CrashReport crashReport = CrashReport.forThrowable(var17, "Loading entity NBT"); CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded"); -@@ -1949,6 +_,12 @@ - return type.canSerialize() && key != null ? key.toString() : null; - } +@@ -1944,10 +_,21 @@ + @Nullable + public final String getEncodeId() { ++ // Paper start - Raw entity serialization API ++ return getEncodeId(false); ++ } ++ public final @Nullable String getEncodeId(boolean includeNonSaveable) { ++ // Paper end - Raw entity serialization API + EntityType type = this.getType(); + ResourceLocation key = EntityType.getKey(type); +- return type.canSerialize() && key != null ? key.toString() : null; +- } ++ return (type.canSerialize() || includeNonSaveable) && key != null ? key.toString() : null; // Paper - Raw entity serialization API ++ } ++ + // CraftBukkit start - allow excluding certain data when saving + protected void addAdditionalSaveData(CompoundTag tag, boolean includeAll) { + this.addAdditionalSaveData(tag); + } + // CraftBukkit end -+ + protected abstract void readAdditionalSaveData(CompoundTag tag); - protected abstract void addAdditionalSaveData(CompoundTag tag); @@ -1990,11 +_,61 @@ @Nullable diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 5587c8828..86388f04b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -46,6 +46,7 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.entity.Pose; import org.bukkit.entity.SpawnCategory; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -955,7 +956,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public String getAsString() { CompoundTag tag = new CompoundTag(); - if (!this.getHandle().saveAsPassenger(tag, false)) { + if (!this.getHandle().saveAsPassenger(tag, false, false, false)) { return null; } @@ -988,7 +989,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { private Entity copy(net.minecraft.world.level.Level level) { CompoundTag compoundTag = new CompoundTag(); - this.getHandle().saveAsPassenger(compoundTag, false); + this.getHandle().saveAsPassenger(compoundTag, false, true, true); return net.minecraft.world.entity.EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.LOAD, java.util.function.Function.identity()); } @@ -1224,17 +1225,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - tracked players API - // Paper start - raw entity serialization API @Override - public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { + public boolean spawnAt(Location location, CreatureSpawnEvent.SpawnReason reason) { Preconditions.checkNotNull(location, "location cannot be null"); Preconditions.checkNotNull(reason, "reason cannot be null"); this.entity.setLevel(((CraftWorld) location.getWorld()).getHandle()); this.entity.setPos(location.getX(), location.getY(), location.getZ()); this.entity.setRot(location.getYaw(), location.getPitch()); - return !this.entity.valid && this.entity.level().addFreshEntity(this.entity, reason); + final boolean spawned = !this.entity.valid && this.entity.level().addFreshEntity(this.entity, reason); + if (!spawned) return false; // Do not attempt to spawn rest if root was not spawned in + // Like net.minecraft.world.level.ServerLevelAccessor.addFreshEntityWithPassengers(net.minecraft.world.entity.Entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason) + this.entity.getIndirectPassengers().forEach(e -> e.level().addFreshEntity(e, reason)); + return true; } - // Paper end - raw entity serialization API // Paper start - entity powdered snow API @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java index 6642bdc11..cb8d7fe3a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java @@ -66,7 +66,7 @@ public class CraftEntitySnapshot implements EntitySnapshot { public static CraftEntitySnapshot create(CraftEntity entity) { CompoundTag tag = new CompoundTag(); - if (!entity.getHandle().saveAsPassenger(tag, false)) { + if (!entity.getHandle().saveAsPassenger(tag, false, false, false)) { return null; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index b6665e187..5f6d67b0e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.util; +import ca.spottedleaf.moonrise.common.PlatformHooks; import com.google.common.base.Charsets; import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; @@ -13,24 +14,34 @@ import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.EnumSet; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Stream; +import io.papermc.paper.entity.EntitySerializationFlag; import net.minecraft.SharedConstants; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.item.ItemParser; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; import net.minecraft.util.datafix.DataFixers; import net.minecraft.util.datafix.fixes.References; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.level.block.Block; @@ -43,6 +54,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.UnsafeValues; +import org.bukkit.World; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; @@ -51,10 +63,12 @@ import org.bukkit.block.data.BlockData; // import org.bukkit.craftbukkit.CraftFeatureFlag; // Paper import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.damage.CraftDamageEffect; import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder; +import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.legacy.CraftLegacy; import org.bukkit.craftbukkit.legacy.FieldRename; @@ -513,7 +527,7 @@ public final class CraftMagicNumbers implements UnsafeValues { Preconditions.checkNotNull(item, "null cannot be serialized"); Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized"); - return serializeNbtToBytes((net.minecraft.nbt.CompoundTag) (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(MinecraftServer.getServer().registryAccess())); + return serializeNbtToBytes((CompoundTag) (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(MinecraftServer.getServer().registryAccess())); } @Override @@ -521,9 +535,9 @@ public final class CraftMagicNumbers implements UnsafeValues { Preconditions.checkNotNull(data, "null cannot be deserialized"); Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); - net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); + CompoundTag compound = deserializeNbtFromBytes(data); final int dataVersion = compound.getInt("DataVersion"); - compound = ca.spottedleaf.moonrise.common.PlatformHooks.get().convertNBT(References.ITEM_STACK, MinecraftServer.getServer().fixerUpper, compound, dataVersion, this.getDataVersion()); // Paper - possibly use dataconverter + compound = PlatformHooks.get().convertNBT(References.ITEM_STACK, MinecraftServer.getServer().fixerUpper, compound, dataVersion, this.getDataVersion()); // Paper - possibly use dataconverter return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } @@ -558,32 +572,98 @@ public final class CraftMagicNumbers implements UnsafeValues { } @Override - public byte[] serializeEntity(org.bukkit.entity.Entity entity) { + public byte[] serializeEntity(org.bukkit.entity.Entity entity, EntitySerializationFlag... serializationFlags) { Preconditions.checkNotNull(entity, "null cannot be serialized"); - Preconditions.checkArgument(entity instanceof org.bukkit.craftbukkit.entity.CraftEntity, "only CraftEntities can be serialized"); + Preconditions.checkArgument(entity instanceof CraftEntity, "Only CraftEntities can be serialized"); - net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); - ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().serializeEntity(compound); + Set flags = Set.of(serializationFlags); + final boolean serializePassangers = flags.contains(EntitySerializationFlag.PASSENGERS); + final boolean forceSerialization = flags.contains(EntitySerializationFlag.FORCE); + final boolean allowPlayerSerialization = flags.contains(EntitySerializationFlag.PLAYER); + final boolean allowMiscSerialization = flags.contains(EntitySerializationFlag.MISC); + final boolean includeNonSaveable = allowPlayerSerialization || allowMiscSerialization; + + net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + (serializePassangers ? nmsEntity.getSelfAndPassengers() : Stream.of(nmsEntity)).forEach(e -> { + // Ensure force flag is not needed + Preconditions.checkArgument( + (e.getBukkitEntity().isValid() && e.getBukkitEntity().isPersistent()) || forceSerialization, + "Cannot serialize invalid or non-persistent entity %s(%s) without the FORCE flag", + e.getType().toShortString(), + e.getStringUUID() + ); + + if (e instanceof Player) { + // Ensure player flag is not needed + Preconditions.checkArgument( + allowPlayerSerialization, + "Cannot serialize player(%s) without the PLAYER flag", + e.getStringUUID() + ); + } else { + // Ensure player flag is not needed + Preconditions.checkArgument( + nmsEntity.getType().canSerialize() || allowMiscSerialization, + "Cannot serialize misc non-saveable entity %s(%s) without the MISC flag", + e.getType().toShortString(), + e.getStringUUID() + ); + } + }); + + CompoundTag compound = new CompoundTag(); + if (serializePassangers) { + if (!nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization)) { + throw new IllegalArgumentException("Couldn't serialize entity"); + } + } else { + List pass = new ArrayList<>(nmsEntity.getPassengers()); + nmsEntity.passengers = com.google.common.collect.ImmutableList.of(); + boolean serialized = nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization); + nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass); + if (!serialized) { + throw new IllegalArgumentException("Couldn't serialize entity"); + } + } return serializeNbtToBytes(compound); } @Override - public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world, boolean preserveUUID) { + public org.bukkit.entity.Entity deserializeEntity(byte[] data, World world, boolean preserveUUID, boolean preservePassengers) { Preconditions.checkNotNull(data, "null cannot be deserialized"); - Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); + Preconditions.checkArgument(data.length > 0, "Cannot deserialize empty data"); - net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); + CompoundTag compound = deserializeNbtFromBytes(data); int dataVersion = compound.getInt("DataVersion"); - compound = ca.spottedleaf.moonrise.common.PlatformHooks.get().convertNBT(References.ENTITY, MinecraftServer.getServer().fixerUpper, compound, dataVersion, this.getDataVersion()); // Paper - possibly use dataconverter - if (!preserveUUID) { - // Generate a new UUID so we don't have to worry about deserializing the same entity twice - compound.remove("UUID"); + compound = PlatformHooks.get().convertNBT(References.ENTITY, MinecraftServer.getServer().fixerUpper, compound, dataVersion, this.getDataVersion()); // Paper - possibly use dataconverter + if (!preservePassengers) { + compound.remove("Passengers"); } - return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle(), net.minecraft.world.entity.EntitySpawnReason.LOAD) - .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); + net.minecraft.world.entity.Entity nmsEntity = deserializeEntity(compound, ((CraftWorld) world).getHandle(), preserveUUID); + return nmsEntity.getBukkitEntity(); } - private byte[] serializeNbtToBytes(net.minecraft.nbt.CompoundTag compound) { + private net.minecraft.world.entity.Entity deserializeEntity(CompoundTag compound, ServerLevel world, boolean preserveUUID) { + if (!preserveUUID) { + // Generate a new UUID, so we don't have to worry about deserializing the same entity twice + compound.remove("UUID"); + } + net.minecraft.world.entity.Entity nmsEntity = net.minecraft.world.entity.EntityType.create(compound, world, net.minecraft.world.entity.EntitySpawnReason.LOAD) + .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")); + if (compound.contains("Passengers", Tag.TAG_LIST)) { + ListTag passengersCompound = compound.getList("Passengers", Tag.TAG_COMPOUND); + for (Tag tag : passengersCompound) { + if (!(tag instanceof CompoundTag serializedPassenger)) { + continue; + } + net.minecraft.world.entity.Entity passengerEntity = deserializeEntity(serializedPassenger, world, preserveUUID); + passengerEntity.startRiding(nmsEntity, true); + } + } + return nmsEntity; + } + + private byte[] serializeNbtToBytes(CompoundTag compound) { compound.putInt("DataVersion", getDataVersion()); java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); try { @@ -597,8 +677,8 @@ public final class CraftMagicNumbers implements UnsafeValues { return outputStream.toByteArray(); } - private net.minecraft.nbt.CompoundTag deserializeNbtFromBytes(byte[] data) { - net.minecraft.nbt.CompoundTag compound; + private CompoundTag deserializeNbtFromBytes(byte[] data) { + CompoundTag compound; try { compound = net.minecraft.nbt.NbtIo.readCompressed( new java.io.ByteArrayInputStream(data), net.minecraft.nbt.NbtAccounter.unlimitedHeap() From 953f6f929e7b54c906b9a9b293237503981c3ad5 Mon Sep 17 00:00:00 2001 From: kokiriglade Date: Thu, 26 Dec 2024 23:57:34 +0000 Subject: [PATCH 16/40] Banner pattern registry modification (#11803) --- .../data/BannerPatternRegistryEntry.java | 65 +++++++++++++++++++ .../paper/registry/event/RegistryEvents.java | 3 + .../paper/registry/PaperRegistries.java | 3 +- .../data/PaperBannerPatternRegistryEntry.java | 65 +++++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/data/BannerPatternRegistryEntry.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/data/PaperBannerPatternRegistryEntry.java diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/BannerPatternRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/BannerPatternRegistryEntry.java new file mode 100644 index 000000000..8ca672a5b --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/BannerPatternRegistryEntry.java @@ -0,0 +1,65 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import net.kyori.adventure.key.Key; +import org.bukkit.block.banner.PatternType; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link PatternType} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface BannerPatternRegistryEntry { + + /** + * Provides the asset id of the pattern type, which is the location of the sprite to use. + * + * @return the asset id. + */ + Key assetId(); + + /** + * Provides the translation key for displaying the pattern inside the banner's tooltip. + * + * @return the translation key. + */ + String translationKey(); + + /** + * A mutable builder for the {@link BannerPatternRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends BannerPatternRegistryEntry, RegistryBuilder { + + /** + * Sets the asset id of the pattern type, which is the location of the sprite to use. + * + * @param assetId the asset id. + * @return this builder instance. + * @see BannerPatternRegistryEntry#assetId() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder assetId(Key assetId); + + /** + * Sets the translation key for displaying the pattern inside the banner's tooltip. + * + * @param translationKey the translation key. + * @return this builder instance. + * @see BannerPatternRegistryEntry#translationKey() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder translationKey(String translationKey); + + } + +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java index 40deffbd0..cfda2a7e2 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java @@ -1,11 +1,13 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.BannerPatternRegistryEntry; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; import io.papermc.paper.registry.data.GameEventRegistryEntry; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; import org.bukkit.Art; import org.bukkit.GameEvent; +import org.bukkit.block.banner.PatternType; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -23,6 +25,7 @@ public final class RegistryEvents { public static final RegistryEventProvider GAME_EVENT = create(RegistryKey.GAME_EVENT); public static final RegistryEventProvider ENCHANTMENT = create(RegistryKey.ENCHANTMENT); public static final RegistryEventProvider PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT); + public static final RegistryEventProvider BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN); private RegistryEvents() { } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java index a41356e13..c79981e50 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.datacomponent.DataComponentTypes; import io.papermc.paper.datacomponent.PaperDataComponentType; +import io.papermc.paper.registry.data.PaperBannerPatternRegistryEntry; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; @@ -106,7 +107,7 @@ public final class PaperRegistries { start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).build().delayed(), start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).serializationUpdater(FieldRename.ENCHANTMENT_RENAME).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).delayed(), start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), - start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new).build().delayed(), + start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new).writable(PaperBannerPatternRegistryEntry.PaperBuilder::new).delayed(), start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new).build().delayed(), diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperBannerPatternRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperBannerPatternRegistryEntry.java new file mode 100644 index 000000000..70d226a14 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperBannerPatternRegistryEntry.java @@ -0,0 +1,65 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.util.Conversions; +import net.kyori.adventure.key.Key; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.entity.BannerPattern; +import org.bukkit.block.banner.PatternType; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.*; + +public class PaperBannerPatternRegistryEntry implements BannerPatternRegistryEntry { + + protected @Nullable ResourceLocation assetId; + protected @Nullable String translationKey; + + public PaperBannerPatternRegistryEntry( + final Conversions ignoredConversions, + final @Nullable BannerPattern internal + ) { + if (internal == null) return; + + this.assetId = internal.assetId(); + this.translationKey = internal.translationKey(); + } + + @Override + public Key assetId() { + return PaperAdventure.asAdventure(asConfigured(this.assetId, "assetId")); + } + + @Override + public String translationKey() { + return asConfigured(this.translationKey, "translationKey"); + } + + public static final class PaperBuilder extends PaperBannerPatternRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable BannerPattern internal) { + super(conversions, internal); + } + + @Override + public Builder assetId(final Key assetId) { + this.assetId = PaperAdventure.asVanilla(asArgument(assetId, "assetId")); + return this; + } + + @Override + public Builder translationKey(final String translationKey) { + this.translationKey = asArgument(translationKey, "translationKey"); + return this; + } + + @Override + public BannerPattern build() { + return new BannerPattern( + asConfigured(this.assetId, "assetId"), + this.translationKey() + ); + } + } +} From a5b8df66745f696bcc3234525ac4b26761f0f09c Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 26 Dec 2024 16:49:07 -0800 Subject: [PATCH 17/40] add tagkey file for entity type (#11832) --- .../registry/keys/tags/EntityTypeTagKeys.java | 288 ++++++++++++++++++ .../java/io/papermc/generator/Generators.java | 4 + 2 files changed, 292 insertions(+) create mode 100644 paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java new file mode 100644 index 000000000..5a671ff8b --- /dev/null +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java @@ -0,0 +1,288 @@ +package io.papermc.paper.registry.keys.tags; + +import static net.kyori.adventure.key.Key.key; + +import io.papermc.paper.generated.GeneratedFrom; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.tag.TagKey; +import net.kyori.adventure.key.Key; +import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Vanilla keys for {@link RegistryKey#ENTITY_TYPE}. + * + * @apiNote The fields provided here are a direct representation of + * what is available from the vanilla game source. They may be + * changed (including removals) on any Minecraft version + * bump, so cross-version compatibility is not provided on the + * same level as it is on most of the other API. + */ +@SuppressWarnings({ + "unused", + "SpellCheckingInspection" +}) +@GeneratedFrom("1.21.4") +@NullMarked +@ApiStatus.Experimental +public final class EntityTypeTagKeys { + /** + * {@code #minecraft:aquatic} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey AQUATIC = create(key("aquatic")); + + /** + * {@code #minecraft:arrows} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey ARROWS = create(key("arrows")); + + /** + * {@code #minecraft:arthropod} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey ARTHROPOD = create(key("arthropod")); + + /** + * {@code #minecraft:axolotl_always_hostiles} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey AXOLOTL_ALWAYS_HOSTILES = create(key("axolotl_always_hostiles")); + + /** + * {@code #minecraft:axolotl_hunt_targets} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey AXOLOTL_HUNT_TARGETS = create(key("axolotl_hunt_targets")); + + /** + * {@code #minecraft:beehive_inhabitors} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey BEEHIVE_INHABITORS = create(key("beehive_inhabitors")); + + /** + * {@code #minecraft:boat} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey BOAT = create(key("boat")); + + /** + * {@code #minecraft:can_breathe_under_water} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey CAN_BREATHE_UNDER_WATER = create(key("can_breathe_under_water")); + + /** + * {@code #minecraft:can_turn_in_boats} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey CAN_TURN_IN_BOATS = create(key("can_turn_in_boats")); + + /** + * {@code #minecraft:deflects_projectiles} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey DEFLECTS_PROJECTILES = create(key("deflects_projectiles")); + + /** + * {@code #minecraft:dismounts_underwater} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey DISMOUNTS_UNDERWATER = create(key("dismounts_underwater")); + + /** + * {@code #minecraft:fall_damage_immune} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FALL_DAMAGE_IMMUNE = create(key("fall_damage_immune")); + + /** + * {@code #minecraft:freeze_hurts_extra_types} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FREEZE_HURTS_EXTRA_TYPES = create(key("freeze_hurts_extra_types")); + + /** + * {@code #minecraft:freeze_immune_entity_types} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FREEZE_IMMUNE_ENTITY_TYPES = create(key("freeze_immune_entity_types")); + + /** + * {@code #minecraft:frog_food} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FROG_FOOD = create(key("frog_food")); + + /** + * {@code #minecraft:ignores_poison_and_regen} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey IGNORES_POISON_AND_REGEN = create(key("ignores_poison_and_regen")); + + /** + * {@code #minecraft:illager} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey ILLAGER = create(key("illager")); + + /** + * {@code #minecraft:illager_friends} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey ILLAGER_FRIENDS = create(key("illager_friends")); + + /** + * {@code #minecraft:immune_to_infested} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey IMMUNE_TO_INFESTED = create(key("immune_to_infested")); + + /** + * {@code #minecraft:immune_to_oozing} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey IMMUNE_TO_OOZING = create(key("immune_to_oozing")); + + /** + * {@code #minecraft:impact_projectiles} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey IMPACT_PROJECTILES = create(key("impact_projectiles")); + + /** + * {@code #minecraft:inverted_healing_and_harm} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey INVERTED_HEALING_AND_HARM = create(key("inverted_healing_and_harm")); + + /** + * {@code #minecraft:no_anger_from_wind_charge} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey NO_ANGER_FROM_WIND_CHARGE = create(key("no_anger_from_wind_charge")); + + /** + * {@code #minecraft:non_controlling_rider} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey NON_CONTROLLING_RIDER = create(key("non_controlling_rider")); + + /** + * {@code #minecraft:not_scary_for_pufferfish} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey NOT_SCARY_FOR_PUFFERFISH = create(key("not_scary_for_pufferfish")); + + /** + * {@code #minecraft:powder_snow_walkable_mobs} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey POWDER_SNOW_WALKABLE_MOBS = create(key("powder_snow_walkable_mobs")); + + /** + * {@code #minecraft:raiders} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey RAIDERS = create(key("raiders")); + + /** + * {@code #minecraft:redirectable_projectile} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REDIRECTABLE_PROJECTILE = create(key("redirectable_projectile")); + + /** + * {@code #minecraft:sensitive_to_bane_of_arthropods} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey SENSITIVE_TO_BANE_OF_ARTHROPODS = create(key("sensitive_to_bane_of_arthropods")); + + /** + * {@code #minecraft:sensitive_to_impaling} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey SENSITIVE_TO_IMPALING = create(key("sensitive_to_impaling")); + + /** + * {@code #minecraft:sensitive_to_smite} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey SENSITIVE_TO_SMITE = create(key("sensitive_to_smite")); + + /** + * {@code #minecraft:skeletons} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey SKELETONS = create(key("skeletons")); + + /** + * {@code #minecraft:undead} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey UNDEAD = create(key("undead")); + + /** + * {@code #minecraft:wither_friends} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey WITHER_FRIENDS = create(key("wither_friends")); + + /** + * {@code #minecraft:zombies} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey ZOMBIES = create(key("zombies")); + + private EntityTypeTagKeys() { + } + + /** + * Creates a tag key for {@link EntityType} in the registry {@code minecraft:entity_type}. + * + * @param key the tag key's key + * @return a new tag key + */ + @ApiStatus.Experimental + public static TagKey create(final Key key) { + return TagKey.create(RegistryKey.ENTITY_TYPE, key); + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/Generators.java b/paper-api-generator/src/main/java/io/papermc/generator/Generators.java index 73e4f7082..677a1d449 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/Generators.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/Generators.java @@ -21,6 +21,7 @@ import org.bukkit.block.banner.PatternType; import org.bukkit.damage.DamageType; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Cat; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Frog; import org.bukkit.entity.Villager; import org.bukkit.entity.Wolf; @@ -79,6 +80,9 @@ public interface Generators { simpleTagKey("BannerPatternTagKeys", PatternType.class, Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN), simpleTagKey("PaintingVariantTagKeys", Art.class, Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT), simpleTagKey("InstrumentTagKeys", MusicInstrument.class, Registries.INSTRUMENT, RegistryKey.INSTRUMENT), + + // api only + simpleTagKey("EntityTypeTagKeys", EntityType.class, Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE), new MobGoalGenerator("VanillaGoal", "com.destroystokyo.paper.entity.ai") }; From c530c39f4e8790ce29e27df03e864bb4f8250747 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 27 Dec 2024 12:31:54 +0100 Subject: [PATCH 18/40] More var name fixes --- .../world/level/block/BedBlock.java.patch | 40 ++++++++----------- .../level/block/BigDripleafBlock.java.patch | 4 +- .../world/level/block/Block.java.patch | 2 +- .../world/level/block/BushBlock.java.patch | 10 +---- .../world/level/block/CakeBlock.java.patch | 2 +- .../world/level/block/CaveVines.java.patch | 4 +- .../level/block/ComposterBlock.java.patch | 8 ++-- .../world/level/block/CrafterBlock.java.patch | 8 ++-- .../block/DropExperienceBlock.java.patch | 11 +++-- .../world/level/block/DropperBlock.java.patch | 4 +- .../level/block/RedStoneOreBlock.java.patch | 9 ++--- .../block/entity/SignBlockEntity.java.patch | 16 ++++---- .../block/entity/SkullBlockEntity.java.patch | 4 +- .../block/piston/PistonBaseBlock.java.patch | 19 --------- .../block/state/BlockBehaviour.java.patch | 4 +- .../inventory/CraftBlockInventoryHolder.java | 6 +-- 16 files changed, 57 insertions(+), 94 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch index ad2f90861..f56e52852 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch @@ -5,11 +5,11 @@ } - if (!canSetSpawn(level)) { -+ if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into EntityHuman ++ if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into Player level.removeBlock(pos, false); BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite()); if (level.getBlockState(blockPos).is(this)) { -@@ -103,22 +_,62 @@ +@@ -103,22 +_,56 @@ level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); return InteractionResult.SUCCESS_SERVER; } else if (state.getValue(OCCUPIED)) { @@ -21,20 +21,20 @@ return InteractionResult.SUCCESS_SERVER; } else { + // CraftBukkit start -+ BlockState finaliblockdata = state; -+ BlockPos finalblockposition = pos; ++ final BlockState finalBlockState = state; ++ final BlockPos finalBlockPos = pos; + // CraftBukkit end player.startSleepInBed(pos).ifLeft(bedSleepingProblem -> { + // Paper start - PlayerBedFailEnterEvent + if (bedSleepingProblem != null) { -+ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalblockposition), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage())); ++ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalBlockPos), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage())); + if (!event.callEvent()) { + return; + } + // Paper end - PlayerBedFailEnterEvent + // CraftBukkit start - handling bed explosion from below here + if (event.getWillExplode()) { // Paper - PlayerBedFailEnterEvent -+ this.explodeBed(finaliblockdata, level, finalblockposition); ++ this.explodeBed(finalBlockState, level, finalBlockPos); + } else + // CraftBukkit end if (bedSleepingProblem.getMessage() != null) { @@ -49,24 +49,18 @@ } } -+ // CraftBukkit start -+ private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) { -+ { -+ { -+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition).getState(); // CraftBukkit - capture BlockState before remove block -+ world.removeBlock(blockposition, false); -+ BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite()); ++ // CraftBukkit start - Copied from the above method ++ private InteractionResult explodeBed(BlockState state, Level level, BlockPos pos) { ++ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos).getState(); // CraftBukkit - capture BlockState before remove block ++ level.removeBlock(pos, false); ++ BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite()); ++ if (level.getBlockState(blockPos).is(this)) { ++ level.removeBlock(blockPos, false); ++ } + -+ if (world.getBlockState(blockposition1).getBlock() == this) { -+ world.removeBlock(blockposition1, false); -+ } -+ -+ Vec3 vec3d = blockposition.getCenter(); -+ -+ world.explode(null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state -+ return InteractionResult.SUCCESS; -+ } -+ } ++ Vec3 center = pos.getCenter(); ++ level.explode(null, level.damageSources().badRespawnPointExplosion(center, blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state ++ return InteractionResult.SUCCESS_SERVER; + } + // CraftBukkit end + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch index 11a7f5541..f3f15caba 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch @@ -19,8 +19,8 @@ - this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null); + // CraftBukkit start - tilt dripleaf + org.bukkit.event.Cancellable cancellable; -+ if (entity instanceof net.minecraft.world.entity.player.Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((net.minecraft.world.entity.player.Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ if (entity instanceof net.minecraft.world.entity.player.Player player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); + } else { + cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index e58b07c7a..1fe47eae6 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -133,7 +133,7 @@ + return 0; // CraftBukkit + } + // CraftBukkit start -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + return 0; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch index 709e307ca..377f1220e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch @@ -1,13 +1,5 @@ --- a/net/minecraft/world/level/block/BushBlock.java +++ b/net/minecraft/world/level/block/BushBlock.java -@@ -6,6 +_,7 @@ - import net.minecraft.tags.BlockTags; - import net.minecraft.util.RandomSource; - import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelReader; - import net.minecraft.world.level.ScheduledTickAccess; - import net.minecraft.world.level.block.state.BlockBehaviour; @@ -35,9 +_,15 @@ BlockState neighborState, RandomSource random @@ -18,7 +10,7 @@ + // CraftBukkit start + if (!state.canSurvive(level, pos)) { + // Suppress during worldgen -+ if (!(level instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper ++ if (!(level instanceof net.minecraft.server.level.ServerLevel serverLevel && serverLevel.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(serverLevel, pos).isCancelled()) { // Paper + return Blocks.AIR.defaultBlockState(); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch index d564317a0..f3add7001 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch @@ -29,7 +29,7 @@ - player.getFoodData().eat(2, 0.1F); - int bitesValue = state.getValue(BITES); + // CraftBukkit start -+ // entityhuman.getFoodData().eat(2, 0.1F); ++ // player.getFoodData().eat(2, 0.1F); + int oldFoodLevel = player.getFoodData().foodLevel; + + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch index 6355a6f4b..f24e49e93 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch @@ -10,8 +10,8 @@ + return InteractionResult.SUCCESS; + } + -+ if (entity instanceof net.minecraft.world.entity.player.Player) { -+ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (net.minecraft.world.entity.player.Player) entity, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1))); ++ if (entity instanceof net.minecraft.world.entity.player.Player player) { ++ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, player, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1))); + if (event.isCancelled()) { + return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch index 2f9e73d10..1306f54ed 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -39,8 +39,8 @@ public static BlockState extractProduce(Entity entity, BlockState state, Level level, BlockPos pos) { + // CraftBukkit start + if (entity != null && !(entity instanceof Player)) { -+ BlockState iblockdata1 = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos); -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, iblockdata1)) { ++ BlockState emptyState = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, emptyState)) { + return state; + } + } @@ -100,9 +100,9 @@ public static class EmptyContainer extends SimpleContainer implements WorldlyContainer { - public EmptyContainer() { -+ public EmptyContainer(LevelAccessor generatoraccess, BlockPos blockposition) { // CraftBukkit ++ public EmptyContainer(LevelAccessor levelAccessor, BlockPos blockPos) { // CraftBukkit super(0); -+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit ++ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(levelAccessor, blockPos, this); // CraftBukkit } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch index b592d3f85..fb9ecec88 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch @@ -31,8 +31,8 @@ + + org.bukkit.inventory.Inventory destinationInventory; + // Have to special case large chests as they work oddly -+ if (containerAt instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ if (containerAt instanceof CompoundContainer compoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer); + } else { + destinationInventory = containerAt.getOwner().getInventory(); + } @@ -57,8 +57,8 @@ + + org.bukkit.inventory.Inventory destinationInventory; + // Have to special case large chests as they work oddly -+ if (containerAt instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ if (containerAt instanceof CompoundContainer compoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer); + } else { + destinationInventory = containerAt.getOwner().getInventory(); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch index 1487606ce..6fbb433e7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch @@ -4,16 +4,15 @@ @Override protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { super.spawnAfterBreak(state, level, pos, stack, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(level, pos, stack, this.xpRange); -- } + // CraftBukkit start - Delegate to getExpDrop + } + + @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange); ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { +- this.tryDropExperience(level, pos, stack, this.xpRange); +- } ++ return this.tryDropExperience(level, pos, stack, this.xpRange); + } + + return 0; diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch index 1b70c5b62..bcab2da23 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch @@ -39,8 +39,8 @@ + + org.bukkit.inventory.Inventory destinationInventory; + // Have to special case large chests as they work oddly -+ if (containerAt instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ if (containerAt instanceof CompoundContainer compoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer); + } else { + destinationInventory = containerAt.getOwner().getInventory(); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch index 6f93bcddd..a68f66333 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch @@ -71,15 +71,14 @@ @Override protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { super.spawnAfterBreak(state, level, pos, stack, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(level, pos, stack, UniformInt.of(1, 5)); + // CraftBukkit start - Delegated to getExpDrop + } + + @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, UniformInt.of(1, 5)); ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { +- this.tryDropExperience(level, pos, stack, UniformInt.of(1, 5)); ++ return this.tryDropExperience(level, pos, stack, UniformInt.of(1, 5)); } + + return 0; diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index b84d89679..13adcff53 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -1,11 +1,9 @@ --- a/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -54,11 +_,16 @@ - return new SignText(); +@@ -55,10 +_,15 @@ } -- public boolean isFacingFrontText(Player player) { -+ public boolean isFacingFrontText(net.minecraft.world.entity.player.Player player) { + public boolean isFacingFrontText(Player player) { + // Paper start - More Sign Block API + return this.isFacingFrontText(player.getX(), player.getZ()); + } @@ -15,8 +13,8 @@ Vec3 signHitboxCenterPosition = signBlock.getSignHitboxCenterPosition(this.getBlockState()); - double d = player.getX() - (this.getBlockPos().getX() + signHitboxCenterPosition.x); - double d1 = player.getZ() - (this.getBlockPos().getZ() + signHitboxCenterPosition.z); -+ double d = x - ((double) this.getBlockPos().getX() + signHitboxCenterPosition.x); // Paper - More Sign Block API -+ double d1 = z - ((double) this.getBlockPos().getZ() + signHitboxCenterPosition.z); // Paper - More Sign Block AP ++ double d = x - (this.getBlockPos().getX() + signHitboxCenterPosition.x); // Paper - More Sign Block API ++ double d1 = z - (this.getBlockPos().getZ() + signHitboxCenterPosition.z); // Paper - More Sign Block AP float yRotationDegrees = signBlock.getYRotationDegrees(this.getBlockState()); float f = (float)(Mth.atan2(d1, d) * 180.0F / (float)Math.PI) - 90.0F; return Mth.degreesDifferenceAbs(yRotationDegrees, f) <= 90.0F; @@ -136,14 +134,14 @@ + } + }; + -+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, Level world, BlockPos pos) { ++ private CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) { + // CraftBukkit end String string = player == null ? "Sign" : player.getName().getString(); Component component = (Component)(player == null ? Component.literal("Sign") : player.getDisplayName()); - return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); + + // Paper start - Fix commands from signs not firing command events -+ CommandSource commandSource = world.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) { ++ CommandSource commandSource = level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) { + @Override + public void sendSystemMessage(Component message) { + if (player instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) { @@ -158,7 +156,7 @@ + } : this.commandSource; + // Paper end - Fix commands from signs not firing command events + // CraftBukkit - this -+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, string, component, world.getServer(), player); // Paper - Fix commands from signs not firing command events ++ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch index c28bc3845..89553e4e2 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch @@ -64,9 +64,9 @@ - LoadingCache>> loadingCache = profileCacheById; - return loadingCache != null ? loadingCache.getUnchecked(profileUuid) : CompletableFuture.completedFuture(Optional.empty()); + // Paper start - player profile events -+ public static CompletableFuture> fetchGameProfile(UUID uuid, @Nullable String name) { ++ public static CompletableFuture> fetchGameProfile(UUID profileUuid, @Nullable String name) { + LoadingCache, CompletableFuture>> loadingCache = profileCacheById; -+ return loadingCache != null ? loadingCache.getUnchecked(new com.mojang.datafixers.util.Pair<>(uuid, name != null ? new com.mojang.authlib.GameProfile(uuid, name) : null)) : CompletableFuture.completedFuture(Optional.empty()); ++ return loadingCache != null ? loadingCache.getUnchecked(new com.mojang.datafixers.util.Pair<>(profileUuid, name != null ? new com.mojang.authlib.GameProfile(profileUuid, name) : null)) : CompletableFuture.completedFuture(Optional.empty()); + // Paper end - player profile events } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch index 9ee94df16..8f8179f69 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch @@ -1,24 +1,5 @@ --- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -145,6 +_,18 @@ - i = 2; - } - -+ // CraftBukkit start -+ // if (!this.isSticky) { // Paper - Fix sticky pistons and BlockPistonRetractEvent; Move further down -+ // org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ // BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.of(), CraftBlock.notchToBlockFace(enumdirection)); -+ // world.getCraftServer().getPluginManager().callEvent(event); -+ // -+ // if (event.isCancelled()) { -+ // return; -+ // } -+ // } -+ // PAIL: checkME - what happened to setTypeAndData? -+ // CraftBukkit end - level.blockEvent(pos, this, i, direction.get3DDataValue()); - } - } @@ -174,6 +_,12 @@ @Override protected boolean triggerEvent(BlockState state, Level level, BlockPos pos, int id, int param) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index ee4aa83de..f9c4ef45c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -9,8 +9,8 @@ + } + + // CraftBukkit start -+ protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, @Nullable net.minecraft.world.item.context.UseOnContext context) { -+ this.onPlace(iblockdata, world, blockposition, iblockdata1, flag); ++ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston, @Nullable net.minecraft.world.item.context.UseOnContext context) { ++ this.onPlace(state, level, pos, oldState, movedByPiston); + } + // CraftBukkit end diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java index 7129eb5f5..1407ff103 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java @@ -13,9 +13,9 @@ public class CraftBlockInventoryHolder implements BlockInventoryHolder { private final Block block; private final Inventory inventory; - public CraftBlockInventoryHolder(LevelAccessor world, BlockPos pos, Container inv) { - this.block = CraftBlock.at(world, pos); - this.inventory = new CraftInventory(inv); + public CraftBlockInventoryHolder(LevelAccessor levelAccessor, BlockPos pos, Container container) { + this.block = CraftBlock.at(levelAccessor, pos); + this.inventory = new CraftInventory(container); } // Paper start - Add missing InventoryHolders public CraftBlockInventoryHolder(net.minecraft.world.inventory.ContainerLevelAccess levelAccess, Inventory inventory) { From 2b73d1957c9ef7a59ea5190e46276eb92fced336 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 27 Dec 2024 13:45:04 +0100 Subject: [PATCH 19/40] More var name fixes --- .../patches/features/0004-Anti-Xray.patch | 16 +++---- .../0016-Rewrite-dataconverter-system.patch | 12 +++--- .../0017-Moonrise-optimisation-patches.patch | 36 ++++++++-------- .../world/level/BlockGetter.java.patch | 32 ++++++++------ .../level/block/EnderChestBlock.java.patch | 6 ++- .../world/level/block/FireBlock.java.patch | 16 ++----- .../block/LayeredCauldronBlock.java.patch | 16 +++---- .../world/level/block/LightBlock.java.patch | 6 +-- .../world/level/block/LiquidBlock.java.patch | 18 ++++---- .../world/level/block/NoteBlock.java.patch | 14 ------ .../level/block/PressurePlateBlock.java.patch | 4 +- .../level/block/RedStoneOreBlock.java.patch | 4 +- .../level/block/SnifferEggBlock.java.patch | 6 +-- .../world/level/chunk/ChunkAccess.java.patch | 26 +++++------ .../level/chunk/ChunkGenerator.java.patch | 22 +++++----- .../world/level/chunk/LevelChunk.java.patch | 2 +- .../level/chunk/LevelChunkSection.java.patch | 4 +- .../chunk/storage/ChunkStorage.java.patch | 43 +++---------------- .../level/chunk/storage/RegionFile.java.patch | 10 +---- .../storage/SerializableChunkData.java.patch | 12 +++--- .../level/entity/EntityAccess.java.patch | 4 +- .../PersistentEntitySectionManager.java.patch | 4 +- .../NoiseBasedChunkGenerator.java.patch | 5 --- .../structure/StructurePiece.java.patch | 30 ++++++------- .../level/material/FlowingFluid.java.patch | 2 +- .../level/material/WaterFluid.java.patch | 6 +-- .../storage/PlayerDataStorage.java.patch | 8 ++-- .../generator/CustomChunkGenerator.java | 6 +-- .../util/DelegatedGeneratorAccess.java | 4 +- 29 files changed, 156 insertions(+), 218 deletions(-) diff --git a/paper-server/patches/features/0004-Anti-Xray.patch b/paper-server/patches/features/0004-Anti-Xray.patch index 92c417ecb..2a2def278 100644 --- a/paper-server/patches/features/0004-Anti-Xray.patch +++ b/paper-server/patches/features/0004-Anti-Xray.patch @@ -239,7 +239,7 @@ index 0f346faa82b988e86834c38837f6f11bea7f31c6..771d6ed6a7c889c09efd4ff6e20298c8 if (blockState == null) { // CraftBukkit start - remove blockstate if failed (or the same) diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index 809b3c37d3749c76c3c243cd91c593d03693e9b3..860d1c9729c4ee97ec6f40f7aa969829070b27c0 100644 +index c82780db7fe5b1557a7802d3111f38099be55ac1..d63d745a0220963a297cfedf1e8983aeb471a045 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java @@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @@ -261,7 +261,7 @@ index 809b3c37d3749c76c3c243cd91c593d03693e9b3..860d1c9729c4ee97ec6f40f7aa969829 } } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 51a136cf015de730ca0d1b48cf618a2ed69ea89f..96b0342ab7b922aa16d07b6c00542e6cb66c974a 100644 +index ce781ba2c8b3f9f051201d3809a9cb041036f93a..cad71ac79fc52225a192aa5c5d07b13c831fc2c1 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -109,7 +109,7 @@ public class LevelChunk extends ChunkAccess { @@ -270,11 +270,11 @@ index 51a136cf015de730ca0d1b48cf618a2ed69ea89f..96b0342ab7b922aa16d07b6c00542e6c ) { - super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); + super(pos, data, level, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry - this.level = (net.minecraft.server.level.ServerLevel) level; // CraftBukkit - type + this.level = (ServerLevel) level; // CraftBukkit - type this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>(); diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java -index baa9f3e2e6e45c250930658e82bad70a3a292b05..fc21c3268c4b4fda2933d71f0913db28e3796653 100644 +index b3d600b0d6deaf44f232dfc86e1456c867e1c07f..a7fabde0f32f09d7f7bed65576ce469f069a21fa 100644 --- a/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -38,9 +38,15 @@ public class LevelChunkSection { @@ -550,7 +550,7 @@ index bfbb1a2bb4abbb369a24f2f01439e9ea3e16794b..8d6ed8be4d93f7d4e6ea80c351020d88 int getSerializedSize(); diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 37437a86d74291fab1de9495008aafb15dfadce0..cf6e2053d81f7b0f8c8e58b9c0fad3285ebc047d 100644 +index c7c87bc8df86ceeef3e15a8f23fc252d4cee1984..3b55e7fb27d680204b8621666ae9200870def3eb 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -94,7 +94,7 @@ public record SerializableChunkData( @@ -607,9 +607,9 @@ index 37437a86d74291fab1de9495008aafb15dfadce0..cf6e2053d81f7b0f8c8e58b9c0fad328 @@ -414,7 +418,7 @@ public record SerializableChunkData( // CraftBukkit start - read/write - private static Codec>> makeBiomeCodecRW(Registry iregistry) { -- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS)); -+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes + private static Codec>> makeBiomeCodecRW(Registry biomeRegistry) { +- return PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS)); ++ return PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes } // CraftBukkit end diff --git a/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch b/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch index 1f0f67af8..ef5f7da45 100644 --- a/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch +++ b/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch @@ -30633,10 +30633,10 @@ index 0d65bf24f515b80701150fdc430f324a533cb478..b92a3da5c325e69f5601416d4205fb33 Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> atomicReference.get().runServer(), "Server thread"); thread.setUncaughtExceptionHandler((thread1, exception) -> LOGGER.error("Uncaught exception in server thread", exception)); diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d5946cf2501 100644 +index 1a0455936cbca2d3812866b332e00a3aaacae8bd..5ba7f724687401c9ea1756a6491498e03548a257 100644 --- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -85,7 +85,7 @@ public class ChunkStorage implements AutoCloseable { +@@ -54,7 +54,7 @@ public class ChunkStorage implements AutoCloseable { } else { try { // CraftBukkit start @@ -30644,8 +30644,8 @@ index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d59 + if (false && version < 1466) { // Paper - no longer needed, data converter system / DFU handles it now CompoundTag level = chunkData.getCompound("Level"); if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { - net.minecraft.server.level.ServerChunkCache cps = (generatoraccess == null) ? null : ((net.minecraft.server.level.ServerLevel) generatoraccess).getChunkSource(); -@@ -96,7 +96,7 @@ public class ChunkStorage implements AutoCloseable { + // Light is purged updating to 1.14+. We need to set light populated to true so the converter recognizes the chunk as being "full" +@@ -63,7 +63,7 @@ public class ChunkStorage implements AutoCloseable { } // CraftBukkit end if (version < 1493) { @@ -30654,7 +30654,7 @@ index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d59 if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) { LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage); chunkData = legacyStructureHandler.updateFromLegacy(chunkData); -@@ -113,7 +113,7 @@ public class ChunkStorage implements AutoCloseable { +@@ -80,7 +80,7 @@ public class ChunkStorage implements AutoCloseable { // Spigot end injectDatafixingContext(chunkData, levelKey, chunkGeneratorKey); @@ -30741,7 +30741,7 @@ index feb4cd21e26598509dc140028496a6f4254c0680..de43e54698125ce9f319d4889dd49f70 } diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java -index 6c9640f5432e9110e7811b6db246d268c6243feb..45f2800c4862a726490048576fca8e1f24252676 100644 +index d68c6c978ac0f154ffe541fd204bec03f033ae96..c44110b123ba5912af18faf0065e9ded780da9b7 100644 --- a/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/net/minecraft/world/level/storage/PlayerDataStorage.java @@ -115,7 +115,7 @@ public class PlayerDataStorage { diff --git a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch index 93faf3756..13e59780d 100644 --- a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch @@ -30907,7 +30907,7 @@ index 8d98cba3830dc5dfb5cae9a6f5fedfffee0d2cd8..73962e79a0f3d892e3155443a1b84508 public interface NoiseBiomeSource { diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java -index 91d7d250f7c3de8a71aef26e23c12764b06b322b..0d36b1ac7d54283af71f2494accded11c059dba5 100644 +index a4eb9a10b6c1351c7341bc031bb9f819e17ff1e5..976de81d65b6494cdad20f4ec5125fceec86f951 100644 --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java @@ -259,7 +259,7 @@ public class Block extends BlockBehaviour implements ItemLike { @@ -30920,7 +30920,7 @@ index 91d7d250f7c3de8a71aef26e23c12764b06b322b..0d36b1ac7d54283af71f2494accded11 public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) { diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java -index 25e49a24cedfa8ad04245d59fcac3231bcd62103..061d94a35d957ca72a01bae959d38aab59b1a64d 100644 +index fa816de449a6077c05fee76835a1625f5b2008ac..5473b4006f7e0266ea11a7b05cef78a113c30d97 100644 --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -416,7 +416,7 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -31399,7 +31399,7 @@ index 92350434746f06bbf4a161c6bc42602de7b45220..1c24f38d21da1be9740512981f219924 public Property.Value value(T value) { diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf0a5998c6 100644 +index d63d745a0220963a297cfedf1e8983aeb471a045..6d565b52552534ce9cacfc35ad1bf4adcb69eac3 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java @@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick; @@ -31537,8 +31537,8 @@ index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf + // Paper end - get block chunk optimisation } // CraftBukkit start - public void setBiome(int i, int j, int k, Holder biome) { -@@ -507,12 +572,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh + public void setBiome(int x, int y, int z, Holder biome) { +@@ -503,12 +568,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } public void initializeLightSources() { @@ -31554,7 +31554,7 @@ index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf public record PackedTicks(List> blocks, List> fluids) { diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java -index 65117a9cb9d1b8684cae8d36ea3b8e2050fb928c..a9d65e28b849c9660a14ef7c16ed17bd5182bd7e 100644 +index b320519578f7e2c52b2116afb247e071b322696e..6ed51cf42b5864194d671b5b56f5b9bdf0291dc0 100644 --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -116,7 +116,7 @@ public abstract class ChunkGenerator { @@ -31717,7 +31717,7 @@ index e7c0f4da8508fbca467326f475668d66454d7b77..41856c98d97e7eb0782f8e441b9a269a @Override public BlockEntity getBlockEntity(BlockPos pos) { diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 96b0342ab7b922aa16d07b6c00542e6cb66c974a..c1ae7755e8d6fa8501d2210dab7605d993c55722 100644 +index cad71ac79fc52225a192aa5c5d07b13c831fc2c1..761fdcd4a4e18f45547afd8edff44f61c6eeacb4 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -52,7 +52,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -31896,7 +31896,7 @@ index 96b0342ab7b922aa16d07b6c00542e6cb66c974a..c1ae7755e8d6fa8501d2210dab7605d9 @Nullable diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java -index fc21c3268c4b4fda2933d71f0913db28e3796653..2ff691bcd32f587e8add2d8eda7e7339ccbde6e8 100644 +index a7fabde0f32f09d7f7bed65576ce469f069a21fa..412e7b1cf8c24f0ddf6d174967bedad576f10aba 100644 --- a/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks; @@ -32627,7 +32627,7 @@ index 7a4d299d2ce36982204e30de9278ddfd5b37c3df..b8348976e80578d9eff64eea68c04c60 private final ChunkStatus status; @Nullable diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1c3b75ba6 100644 +index 5ba7f724687401c9ea1756a6491498e03548a257..64343a3f6e6009eed5b392482ec053be8e00ee63 100644 --- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -22,20 +22,30 @@ import net.minecraft.world.level.chunk.ChunkGenerator; @@ -32665,7 +32665,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1 } // CraftBukkit start -@@ -99,7 +109,9 @@ public class ChunkStorage implements AutoCloseable { +@@ -66,7 +76,9 @@ public class ChunkStorage implements AutoCloseable { chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) { LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage); @@ -32675,7 +32675,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1 } } -@@ -163,7 +175,13 @@ public class ChunkStorage implements AutoCloseable { +@@ -130,7 +142,13 @@ public class ChunkStorage implements AutoCloseable { } public CompletableFuture> read(ChunkPos chunkPos) { @@ -32690,7 +32690,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1 } public CompletableFuture write(ChunkPos pos, Supplier tagSupplier) { -@@ -179,29 +197,54 @@ public class ChunkStorage implements AutoCloseable { +@@ -146,29 +164,54 @@ public class ChunkStorage implements AutoCloseable { }; // Paper end - guard against possible chunk pos desync this.handleLegacyStructureIndex(pos); @@ -32784,7 +32784,7 @@ index 889e188e920edb284f04b264bcdd06146f54a4cb..2199a9e2a0141c646d108f2687a27f1d private final Long2ObjectLinkedOpenHashMap> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>(); private static final int REGION_CACHE_SIZE = 1024; diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java -index 783a2d80f6197dd0af0dc81909f0353a8ea2ecf4..7da388ffab162c282cad0f297bb7304f3c2abbaf 100644 +index 4eb07097986aac67421dd8e6a17cc5436da91187..984db72272d552c7210bd6f437ea88694ddd2828 100644 --- a/net/minecraft/world/level/chunk/storage/RegionFile.java +++ b/net/minecraft/world/level/chunk/storage/RegionFile.java @@ -22,7 +22,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; @@ -33324,7 +33324,7 @@ index 7dc1ffffd9d0fec54dbc254c154ee85ee750174d..778bd73a938c94ecb85ca0f8b686ff4e record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index cf6e2053d81f7b0f8c8e58b9c0fad3285ebc047d..70a9972252576e039ac126f6057a6ed66b80cdfc 100644 +index 3b55e7fb27d680204b8621666ae9200870def3eb..879d411775a2fece1d8a970300cb3a550baa6305 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -148,7 +148,7 @@ public record SerializableChunkData( @@ -33700,10 +33700,10 @@ index 342c83309b19c64d86e0dd97c1756c96be52772b..423779a2b690f387a4f0bd07b97b50e0 } } diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 29d9f6e54421c539e9e55ab9f51b4c872da3fbb8..d77016287f5f9a0964d56f05d2d5256ef2e6e86c 100644 +index 6d61739574155f89511b9adcaf1174841bdc7da7..65728ef17e63d71833677fdcbd5bb90794b4822b 100644 --- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -78,7 +78,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { +@@ -77,7 +77,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { return CompletableFuture.supplyAsync(() -> { this.doCreateBiomes(blender, randomState, structureManager, chunk); return chunk; @@ -33712,7 +33712,7 @@ index 29d9f6e54421c539e9e55ab9f51b4c872da3fbb8..d77016287f5f9a0964d56f05d2d5256e } private void doCreateBiomes(Blender blender, RandomState random, StructureManager structureManager, ChunkAccess chunk) { -@@ -318,7 +318,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { +@@ -317,7 +317,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { } return var20; @@ -34002,7 +34002,7 @@ index ca23af013967b50420ebee178878ea79333de53b..d41b9266625ca6c5e32c5126f35a1f77 public int getLightSectionCount() { diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java -index 130ef38a50f1df1faa26b433b0c605a4507f71af..f6daca279788c3d983a9ee213df85d5d93fc6eed 100644 +index 86fd2b831f42bdb5bd045e44b26489d5a8697dd9..e30499bdcd6600e5c9d4a755c1182fb6dff3735f 100644 --- a/net/minecraft/world/level/material/FlowingFluid.java +++ b/net/minecraft/world/level/material/FlowingFluid.java @@ -45,6 +45,48 @@ public abstract class FlowingFluid extends Fluid { diff --git a/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch index f32901905..5816f86ef 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch @@ -25,7 +25,7 @@ FluidState getFluidState(BlockPos pos); default int getLightEmission(BlockPos pos) { -@@ -66,10 +_,25 @@ +@@ -66,19 +_,46 @@ ); } @@ -33,31 +33,39 @@ - return traverseBlocks(context.getFrom(), context.getTo(), context, (traverseContext, traversePos) -> { - BlockState blockState = this.getBlockState(traversePos); - FluidState fluidState = this.getFluidState(traversePos); +- Vec3 from = traverseContext.getFrom(); +- Vec3 to = traverseContext.getTo(); +- VoxelShape blockShape = traverseContext.getBlockShape(blockState, this, traversePos); + // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace -+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { ++ default BlockHitResult clip(ClipContext context, BlockPos traversePos) { + // Paper start - Add predicate for blocks when raytracing -+ return clip(raytrace1, blockposition, null); ++ return clip(context, traversePos, null); + } + -+ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos, java.util.function.Predicate canCollide) { ++ default BlockHitResult clip(ClipContext context, BlockPos traversePos, java.util.function.Predicate canCollide) { + // Paper end - Add predicate for blocks when raytracing + // Paper start - Prevent raytrace from loading chunks + BlockState blockState = this.getBlockStateIfLoaded(traversePos); + if (blockState == null) { + // copied the last function parameter (listed below) -+ Vec3 vec3d = traverseContext.getFrom().subtract(traverseContext.getTo()); ++ Vec3 vec3d = context.getFrom().subtract(context.getTo()); + -+ return BlockHitResult.miss(traverseContext.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(traverseContext.getTo())); ++ return BlockHitResult.miss(context.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(context.getTo())); + } + // Paper end - Prevent raytrace from loading chunks + if (blockState.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, traversePos)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate + FluidState fluidState = blockState.getFluidState(); // Paper - Perf: don't need to go to world state again - Vec3 from = traverseContext.getFrom(); - Vec3 to = traverseContext.getTo(); - VoxelShape blockShape = traverseContext.getBlockShape(blockState, this, traversePos); -@@ -79,6 +_,18 @@ - double d = blockHitResult == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult.getLocation()); - double d1 = blockHitResult1 == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult1.getLocation()); ++ Vec3 from = context.getFrom(); ++ Vec3 to = context.getTo(); ++ VoxelShape blockShape = context.getBlockShape(blockState, this, traversePos); + BlockHitResult blockHitResult = this.clipWithInteractionOverride(from, to, traversePos, blockShape, blockState); +- VoxelShape fluidShape = traverseContext.getFluidShape(fluidState, this, traversePos); ++ VoxelShape fluidShape = context.getFluidShape(fluidState, this, traversePos); + BlockHitResult blockHitResult1 = fluidShape.clip(from, to, traversePos); +- double d = blockHitResult == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult.getLocation()); +- double d1 = blockHitResult1 == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult1.getLocation()); ++ double d = blockHitResult == null ? Double.MAX_VALUE : context.getFrom().distanceToSqr(blockHitResult.getLocation()); ++ double d1 = blockHitResult1 == null ? Double.MAX_VALUE : context.getFrom().distanceToSqr(blockHitResult1.getLocation()); return d <= d1 ? blockHitResult : blockHitResult1; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch index 82a4a56c8..30b8c15a5 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/EnderChestBlock.java +++ b/net/minecraft/world/level/block/EnderChestBlock.java -@@ -78,16 +_,15 @@ +@@ -78,16 +_,17 @@ PlayerEnderChestContainer enderChestInventory = player.getEnderChestInventory(); if (enderChestInventory != null && level.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) { BlockPos blockPos = pos.above(); @@ -18,7 +18,9 @@ + // Paper start - Fix InventoryOpenEvent cancellation - moved up; + enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations + if (level instanceof ServerLevel serverLevel && player.openMenu( -+ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, enderChestInventory), CONTAINER_TITLE) ++ new SimpleMenuProvider( ++ (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE ++ ) + ).isPresent()) { + // Paper end - Fix InventoryOpenEvent cancellation - moved up; player.awardStat(Stats.OPEN_ENDERCHEST); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch index ebd1c8425..3d286f8b4 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch @@ -1,13 +1,5 @@ --- a/net/minecraft/world/level/block/FireBlock.java +++ b/net/minecraft/world/level/block/FireBlock.java -@@ -14,6 +_,7 @@ - import net.minecraft.tags.BiomeTags; - import net.minecraft.util.RandomSource; - import net.minecraft.world.item.context.BlockPlaceContext; -+import net.minecraft.world.item.context.UseOnContext; - import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.GameRules; - import net.minecraft.world.level.Level; @@ -122,7 +_,25 @@ BlockState neighborState, RandomSource random @@ -40,7 +32,7 @@ @Override protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { - level.scheduleTick(pos, this, getFireTickDelay(level.random)); -+ level.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option ++ level.scheduleTick(pos, this, getFireTickDelay(level)); // Paper - Add fire-tick-delay option if (level.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { if (!state.canSurvive(level, pos)) { - level.removeBlock(pos, false); @@ -154,7 +146,7 @@ - protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { - super.onPlace(state, level, pos, oldState, isMoving); - level.scheduleTick(pos, this, getFireTickDelay(level.random)); -+ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, UseOnContext context) { ++ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, net.minecraft.world.item.context.UseOnContext context) { + super.onPlace(state, level, pos, oldState, isMoving, context); + // CraftBukkit end + level.scheduleTick(pos, this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option @@ -162,8 +154,8 @@ - private static int getFireTickDelay(RandomSource random) { - return 30 + random.nextInt(10); -+ private static int getFireTickDelay(Level world) { // Paper - Add fire-tick-delay option -+ return world.paperConfig().environment.fireTickDelay + world.random.nextInt(10); // Paper - Add fire-tick-delay option ++ private static int getFireTickDelay(Level level) { // Paper - Add fire-tick-delay option ++ return level.paperConfig().environment.fireTickDelay + level.random.nextInt(10); // Paper - Add fire-tick-delay option } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch index f4af9face..6d49c999f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch @@ -41,33 +41,33 @@ + // CraftBukkit start + LayeredCauldronBlock.lowerFillLevel(state, level, pos, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.UNKNOWN); + } -+ public static boolean lowerFillLevel(BlockState state, Level level, BlockPos BlockPos, Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { ++ public static boolean lowerFillLevel(BlockState state, Level level, BlockPos pos, Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { + int i = (Integer) state.getValue(LayeredCauldronBlock.LEVEL) - 1; + BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) state.setValue(LayeredCauldronBlock.LEVEL, i); + -+ return LayeredCauldronBlock.changeLevel(level, BlockPos, iblockdata1, entity, reason); ++ return LayeredCauldronBlock.changeLevel(level, pos, iblockdata1, entity, reason); + } + + // CraftBukkit start + // Paper start - Call CauldronLevelChangeEvent -+ public static boolean changeLevel(Level world, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable -+ return changeLevel(world, pos, newBlock, entity, reason, true); ++ public static boolean changeLevel(Level level, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable ++ return changeLevel(level, pos, newBlock, entity, reason, true); + } + -+ public static boolean changeLevel(Level world, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable ++ public static boolean changeLevel(Level level, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable + // Paper end - Call CauldronLevelChangeEvent -+ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, pos); ++ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, pos); + newState.setData(newBlock); + + org.bukkit.event.block.CauldronLevelChangeEvent event = new org.bukkit.event.block.CauldronLevelChangeEvent( -+ org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), ++ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), + (entity == null) ? null : entity.getBukkitEntity(), reason, newState + ); + if (!event.callEvent()) { + return false; + } + newState.update(true); -+ if (sendGameEvent) world.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent ++ if (sendGameEvent) level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent + return true; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch index c9fda343b..8b3d19d59 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch @@ -6,9 +6,9 @@ } + // Paper start - prevent unintended light block manipulation + @Override -+ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hit) { -+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation -+ return super.useItemOn(stack, state, world, pos, player, hand, hit); ++ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hitResult) { ++ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (level instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hitResult.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation ++ return super.useItemOn(stack, state, level, pos, player, hand, hitResult); + } + // Paper end - prevent unintended light block manipulation diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch index 35dc60692..4450068d1 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch @@ -11,21 +11,21 @@ + } + } + // Paper start - Configurable speed for water flowing over lava -+ public int getFlowSpeed(Level world, BlockPos blockposition) { ++ public int getFlowSpeed(Level level, BlockPos pos) { + if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) { + if ( -+ isLava(world, blockposition.north(1)) || -+ isLava(world, blockposition.south(1)) || -+ isLava(world, blockposition.west(1)) || -+ isLava(world, blockposition.east(1)) ++ isLava(level, pos.north(1)) || ++ isLava(level, pos.south(1)) || ++ isLava(level, pos.west(1)) || ++ isLava(level, pos.east(1)) + ) { -+ return world.paperConfig().environment.waterOverLavaFlowSpeed; ++ return level.paperConfig().environment.waterOverLavaFlowSpeed; + } + } -+ return this.fluid.getTickDelay(world); ++ return this.fluid.getTickDelay(level); + } -+ private static boolean isLava(Level world, BlockPos blockPos) { -+ final FluidState fluidState = world.getFluidIfLoaded(blockPos); ++ private static boolean isLava(Level level, BlockPos pos) { ++ final FluidState fluidState = level.getFluidIfLoaded(pos); + return fluidState != null && fluidState.is(FluidTags.LAVA); + } + // Paper end - Configurable speed for water flowing over lava diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch index 0ff72778c..76965a2ac 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch @@ -29,20 +29,6 @@ } level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(hasNeighborSignal)), 3); -@@ -104,6 +_,13 @@ - - private void playNote(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) { - if (state.getValue(INSTRUMENT).worksAboveNoteBlock() || level.getBlockState(pos.above()).isAir()) { -+ // CraftBukkit start -+ // 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()) { -+ // return; -+ // } -+ // CraftBukkit end -+ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event? - level.blockEvent(pos, this, 0, 0); - level.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, pos); - } @@ -121,7 +_,7 @@ @Override protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch index 235e99adf..a28da6fbd 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch @@ -20,8 +20,8 @@ + org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager(); + org.bukkit.event.Cancellable cancellable; + -+ if (entity instanceof Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ if (entity instanceof Player player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); + } else { + cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + manager.callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch index a68f66333..c2c101fbf 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch @@ -14,8 +14,8 @@ if (!entity.isSteppingCarefully()) { - interact(state, level, pos); + // CraftBukkit start -+ if (entity instanceof Player) { -+ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ if (entity instanceof Player player) { ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); + if (!event.isCancelled()) { + RedStoneOreBlock.interact(level.getBlockState(pos), level, pos, entity); // add entity + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch index aa5c5e281..dc26f22de 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch @@ -5,9 +5,9 @@ } + // Paper start - Call BlockFadeEvent -+ private void rescheduleTick(ServerLevel world, BlockPos pos) { -+ int baseDelay = hatchBoost(world, pos) ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper - Configure sniffer egg hatch time -+ world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS)); ++ private void rescheduleTick(ServerLevel level, BlockPos pos) { ++ int baseDelay = hatchBoost(level, pos) ? level.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : level.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper - Configure sniffer egg hatch time ++ level.scheduleTick(pos, this, (baseDelay / 3) + level.random.nextInt(RANDOM_HATCH_OFFSET_TICKS)); + // reschedule to avoid being stuck here and behave like the other calls (see #onPlace) + } + // Paper end - Call BlockFadeEvent diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch index d1b576982..f20d2cd0c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -64,27 +64,23 @@ } public abstract ChunkStatus getPersistedStatus(); -@@ -446,6 +_,26 @@ +@@ -446,6 +_,22 @@ throw new ReportedException(crashReport); } } + // CraftBukkit start -+ public void setBiome(int i, int j, int k, Holder biome) { ++ public void setBiome(int x, int y, int z, Holder biome) { + try { -+ int l = QuartPos.fromBlock(this.getMinY()); -+ int i1 = l + QuartPos.fromBlock(this.getHeight()) - 1; -+ int j1 = Mth.clamp(j, l, i1); -+ int k1 = this.getSectionIndex(QuartPos.toBlock(j1)); -+ -+ this.sections[k1].setBiome(i & 3, j1 & 3, k & 3, biome); ++ int minY = QuartPos.fromBlock(this.getMinY()); ++ int maxY = minY + QuartPos.fromBlock(this.getHeight()) - 1; ++ int clampedY = Mth.clamp(y, minY, maxY); ++ int sectionIndex = this.getSectionIndex(QuartPos.toBlock(clampedY)); ++ this.sections[sectionIndex].setBiome(x & 3, clampedY & 3, z & 3, biome); + } catch (Throwable throwable) { -+ CrashReport crashreport = CrashReport.forThrowable(throwable, "Setting biome"); -+ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Biome being set"); -+ -+ crashreportsystemdetails.setDetail("Location", () -> { -+ return CrashReportCategory.formatLocation(this, i, j, k); -+ }); -+ throw new ReportedException(crashreport); ++ CrashReport report = CrashReport.forThrowable(throwable, "Setting biome"); ++ CrashReportCategory reportCategory = report.addCategory("Biome being set"); ++ reportCategory.setDetail("Location", () -> CrashReportCategory.formatLocation(this, x, y, z)); ++ throw new ReportedException(report); + } + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkGenerator.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkGenerator.java.patch index 5fa4572bc..b2e3cf186 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkGenerator.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkGenerator.java.patch @@ -94,24 +94,24 @@ } } + // CraftBukkit start -+ public void applyBiomeDecoration(WorldGenLevel world, ChunkAccess chunk, StructureManager structureAccessor) { -+ this.applyBiomeDecoration(world, chunk, structureAccessor, true); ++ public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager) { ++ this.applyBiomeDecoration(level, chunk, structureManager, true); + } + -+ public void applyBiomeDecoration(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager, boolean vanilla) { -+ if (vanilla) { -+ this.addVanillaDecorations(generatoraccessseed, ichunkaccess, structuremanager); ++ public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager, boolean addVanillaDecorations) { ++ if (addVanillaDecorations) { ++ this.addVanillaDecorations(level, chunk, structureManager); + } + -+ org.bukkit.World world = generatoraccessseed.getMinecraftWorld().getWorld(); ++ org.bukkit.World world = level.getMinecraftWorld().getWorld(); + // only call when a populator is present (prevents unnecessary entity conversion) + if (!world.getPopulators().isEmpty()) { -+ org.bukkit.craftbukkit.generator.CraftLimitedRegion limitedRegion = new org.bukkit.craftbukkit.generator.CraftLimitedRegion(generatoraccessseed, ichunkaccess.getPos()); -+ int x = ichunkaccess.getPos().x; -+ int z = ichunkaccess.getPos().z; ++ org.bukkit.craftbukkit.generator.CraftLimitedRegion limitedRegion = new org.bukkit.craftbukkit.generator.CraftLimitedRegion(level, chunk.getPos()); ++ int x = chunk.getPos().x; ++ int z = chunk.getPos().z; + for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { -+ WorldgenRandom seededrandom = new WorldgenRandom(new net.minecraft.world.level.levelgen.LegacyRandomSource(generatoraccessseed.getSeed())); -+ seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), x, z); ++ WorldgenRandom seededrandom = new WorldgenRandom(new net.minecraft.world.level.levelgen.LegacyRandomSource(level.getSeed())); ++ seededrandom.setDecorationSeed(level.getSeed(), x, z); + populator.populate(world, new org.bukkit.craftbukkit.util.RandomSourceWrapper.RandomWrapper(seededrandom), x, z, limitedRegion); + } + limitedRegion.saveEntities(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch index dcd413b18..29f06860a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -29,7 +29,7 @@ ) { super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); - this.level = level; -+ this.level = (net.minecraft.server.level.ServerLevel) level; // CraftBukkit - type ++ this.level = (ServerLevel) level; // CraftBukkit - type this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>(); for (Heightmap.Types types : Heightmap.Types.values()) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunkSection.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunkSection.java.patch index f4a6ffa6f..96c848d7c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunkSection.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunkSection.java.patch @@ -37,8 +37,8 @@ return this.biomes.get(x, y, z); } + // CraftBukkit start -+ public void setBiome(int i, int j, int k, Holder biome) { -+ this.biomes.set(i, j, k, biome); ++ public void setBiome(int x, int y, int z, Holder biome) { ++ this.biomes.set(x, y, z, biome); + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch index 9188002f3..666d4d9cb 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch @@ -1,41 +1,10 @@ --- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -38,17 +_,63 @@ +@@ -38,17 +_,30 @@ return this.worker.isOldChunkAround(pos, radius); } + // CraftBukkit start -+ private boolean check(net.minecraft.server.level.ServerChunkCache cps, int x, int z) { -+ if (true) return true; // Paper - Perf: this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full" -+ ChunkPos pos = new ChunkPos(x, z); -+ if (cps != null) { -+ com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); -+ if (cps.hasChunk(x, z)) { -+ return true; -+ } -+ } -+ -+ CompoundTag nbt; -+ try { -+ nbt = this.read(pos).get().orElse(null); -+ } catch (InterruptedException | java.util.concurrent.ExecutionException ex) { -+ throw new RuntimeException(ex); -+ } -+ if (nbt != null) { -+ CompoundTag level = nbt.getCompound("Level"); -+ if (level.getBoolean("TerrainPopulated")) { -+ return true; -+ } -+ -+ net.minecraft.world.level.chunk.status.ChunkStatus status = net.minecraft.world.level.chunk.status.ChunkStatus.byName(level.getString("Status")); -+ if (status != null && status.isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.FEATURES)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ public CompoundTag upgradeChunkTag( - ResourceKey levelKey, + ResourceKey levelKey, @@ -44,7 +13,7 @@ - Optional>> chunkGeneratorKey + Optional>> chunkGeneratorKey, + ChunkPos pos, -+ @Nullable net.minecraft.world.level.LevelAccessor generatoraccess ++ @Nullable net.minecraft.world.level.LevelAccessor levelAccessor + // CraftBukkit end ) { int version = getVersion(chunkData); @@ -56,10 +25,8 @@ + if (version < 1466) { + CompoundTag level = chunkData.getCompound("Level"); + if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { -+ net.minecraft.server.level.ServerChunkCache cps = (generatoraccess == null) ? null : ((net.minecraft.server.level.ServerLevel) generatoraccess).getChunkSource(); -+ if (this.check(cps, pos.x - 1, pos.z) && this.check(cps, pos.x - 1, pos.z - 1) && this.check(cps, pos.x, pos.z - 1)) { -+ level.putBoolean("LightPopulated", true); -+ } ++ // Light is purged updating to 1.14+. We need to set light populated to true so the converter recognizes the chunk as being "full" ++ level.putBoolean("LightPopulated", true); + } + } + // CraftBukkit end @@ -72,7 +39,7 @@ + // Spigot start - SPIGOT-6806: Quick and dirty way to prevent below zero generation in old chunks, by setting the status to heightmap instead of empty + boolean stopBelowZero = false; -+ boolean belowZeroGenerationInExistingChunks = (generatoraccess != null) ? ((net.minecraft.server.level.ServerLevel) generatoraccess).spigotConfig.belowZeroGenerationInExistingChunks : org.spigotmc.SpigotConfig.belowZeroGenerationInExistingChunks; ++ boolean belowZeroGenerationInExistingChunks = (levelAccessor != null) ? ((net.minecraft.server.level.ServerLevel) levelAccessor).spigotConfig.belowZeroGenerationInExistingChunks : org.spigotmc.SpigotConfig.belowZeroGenerationInExistingChunks; + + if (version <= 2730 && !belowZeroGenerationInExistingChunks) { + stopBelowZero = "full".equals(chunkData.getCompound("Level").getString("Status")); diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFile.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFile.java.patch index 93e36df68..adc8aaa96 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFile.java.patch @@ -46,7 +46,7 @@ return false; } } -@@ -331,13 +_,18 @@ +@@ -331,6 +_,11 @@ try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { chunkData.position(5); fileChannel.write(chunkData); @@ -58,11 +58,3 @@ } return () -> Files.move(path, externalChunkFile, StandardCopyOption.REPLACE_EXISTING); - } - - private void writeHeader() throws IOException { -- this.header.position(0); -+ ((java.nio.Buffer) this.header).position(0); // CraftBukkit - decompile error - this.file.write(this.header, 0L); - } - diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch index 56133882a..5461001e9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch @@ -80,8 +80,8 @@ } + // CraftBukkit start - load chunk persistent data from nbt - SPIGOT-6814: Already load PDC here to account for 1.17 to 1.18 chunk upgrading. -+ if (this.persistentDataContainer instanceof CompoundTag) { -+ chunkAccess.persistentDataContainer.putAll((CompoundTag) this.persistentDataContainer); ++ if (this.persistentDataContainer instanceof CompoundTag compoundTag) { ++ chunkAccess.persistentDataContainer.putAll(compoundTag); + } + // CraftBukkit end + @@ -107,8 +107,8 @@ } + // CraftBukkit start - read/write -+ private static Codec>> makeBiomeCodecRW(Registry iregistry) { -+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS)); ++ private static Codec>> makeBiomeCodecRW(Registry biomeRegistry) { ++ return PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS)); + } + // CraftBukkit end + @@ -168,8 +168,8 @@ if (structureStart != null) { + // CraftBukkit start - load persistent data for structure start + net.minecraft.nbt.Tag persistentBase = compound.getCompound(string).get("StructureBukkitValues"); -+ if (persistentBase instanceof CompoundTag) { -+ structureStart.persistentDataContainer.putAll((CompoundTag) persistentBase); ++ if (persistentBase instanceof CompoundTag compoundTag) { ++ structureStart.persistentDataContainer.putAll(compoundTag); + } + // CraftBukkit end map.put(structure, structureStart); diff --git a/paper-server/patches/sources/net/minecraft/world/level/entity/EntityAccess.java.patch b/paper-server/patches/sources/net/minecraft/world/level/entity/EntityAccess.java.patch index 6c5e3be1c..fb266ce5b 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/entity/EntityAccess.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/entity/EntityAccess.java.patch @@ -5,8 +5,8 @@ void setRemoved(Entity.RemovalReason removalReason); + // CraftBukkit start - add Bukkit remove cause -+ default void setRemoved(Entity.RemovalReason entity_removalreason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { -+ this.setRemoved(entity_removalreason); ++ default void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause eventCause) { ++ this.setRemoved(removalReason); + } + // CraftBukkit end + diff --git a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch index 384e9f3c5..18b27de6e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch @@ -5,8 +5,8 @@ } + // CraftBukkit start - add method to get all entities in chunk -+ public List getEntities(ChunkPos chunkCoordIntPair) { -+ return this.sectionStorage.getExistingSectionsInChunk(chunkCoordIntPair.toLong()).flatMap(EntitySection::getEntities).map(entity -> (Entity) entity).collect(Collectors.toList()); ++ public List getEntities(ChunkPos chunkPos) { ++ return this.sectionStorage.getExistingSectionsInChunk(chunkPos.toLong()).flatMap(EntitySection::getEntities).map(entity -> (Entity) entity).collect(Collectors.toList()); + } + + public boolean isPending(long pair) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch index c986ea09a..636705b99 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch @@ -1,10 +1,5 @@ --- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -1,3 +_,4 @@ -+// keep - package net.minecraft.world.level.levelgen; - - import com.google.common.annotations.VisibleForTesting; @@ -218,7 +_,7 @@ @Override public void buildSurface(WorldGenRegion level, StructureManager structureManager, RandomState random, ChunkAccess chunk) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch index 9baa2a5f6..aa1428c00 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch @@ -26,32 +26,32 @@ } + // CraftBukkit start -+ protected boolean placeCraftBlockEntity(ServerLevelAccessor serverLevelAccessor, BlockPos pos, org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState, int flags) { -+ if (serverLevelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { ++ protected boolean placeCraftBlockEntity(ServerLevelAccessor levelAccessor, BlockPos pos, org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState, int flags) { ++ if (levelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { + return transformerAccess.setCraftBlock(pos, craftBlockEntityState, flags); + } -+ boolean result = serverLevelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags); -+ BlockEntity tileEntity = serverLevelAccessor.getBlockEntity(pos); -+ if (tileEntity != null) { -+ tileEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), serverLevelAccessor.registryAccess()); ++ boolean result = levelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags); ++ BlockEntity blockEntity = levelAccessor.getBlockEntity(pos); ++ if (blockEntity != null) { ++ blockEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), levelAccessor.registryAccess()); + } + return result; + } + -+ protected void placeCraftSpawner(ServerLevelAccessor worldAccess, BlockPos position, org.bukkit.entity.EntityType entityType, int i) { ++ protected void placeCraftSpawner(ServerLevelAccessor levelAccessor, BlockPos pos, org.bukkit.entity.EntityType entityType, int flags) { + // This method is used in structures that are generated by code and place spawners as they set the entity after the block was placed making it impossible for plugins to access that information -+ org.bukkit.craftbukkit.block.CraftCreatureSpawner spawner = (org.bukkit.craftbukkit.block.CraftCreatureSpawner) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, Blocks.SPAWNER.defaultBlockState(), null); ++ org.bukkit.craftbukkit.block.CraftCreatureSpawner spawner = (org.bukkit.craftbukkit.block.CraftCreatureSpawner) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(levelAccessor, pos, Blocks.SPAWNER.defaultBlockState(), null); + spawner.setSpawnedType(entityType); -+ this.placeCraftBlockEntity(worldAccess, position, spawner, i); ++ this.placeCraftBlockEntity(levelAccessor, pos, spawner, flags); + } + -+ protected void setCraftLootTable(ServerLevelAccessor worldAccess, BlockPos position, RandomSource randomSource, ResourceKey loottableKey) { ++ protected void setCraftLootTable(ServerLevelAccessor levelAccessor, BlockPos pos, RandomSource randomSource, ResourceKey lootTable) { + // This method is used in structures that use data markers to a loot table to loot containers as otherwise plugins won't have access to that information. -+ net.minecraft.world.level.block.entity.BlockEntity tileEntity = worldAccess.getBlockEntity(position); -+ if (tileEntity instanceof net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity tileEntityLootable) { -+ tileEntityLootable.setLootTable(loottableKey, randomSource.nextLong()); -+ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { -+ transformerAccess.setCraftBlock(position, (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, tileEntity.getBlockState(), tileEntityLootable.saveWithFullMetadata(worldAccess.registryAccess())), 3); ++ net.minecraft.world.level.block.entity.BlockEntity blockEntity = levelAccessor.getBlockEntity(pos); ++ if (blockEntity instanceof net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity lootContainerBlockEntity) { ++ lootContainerBlockEntity.setLootTable(lootTable, randomSource.nextLong()); ++ if (levelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { ++ transformerAccess.setCraftBlock(pos, (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(levelAccessor, pos, blockEntity.getBlockState(), lootContainerBlockEntity.saveWithFullMetadata(levelAccessor.registryAccess())), 3); + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/material/FlowingFluid.java.patch b/paper-server/patches/sources/net/minecraft/world/level/material/FlowingFluid.java.patch index 9457eaacf..d6fbecf87 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/material/FlowingFluid.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/material/FlowingFluid.java.patch @@ -58,7 +58,7 @@ } } -+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent ++ protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(level, pos, state); } // Paper - Add BlockBreakBlockEvent protected abstract void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state); protected int getSlopeDistance(LevelReader level, BlockPos pos, int depth, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadContext) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/material/WaterFluid.java.patch b/paper-server/patches/sources/net/minecraft/world/level/material/WaterFluid.java.patch index 59826b744..32fa03281 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/material/WaterFluid.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/material/WaterFluid.java.patch @@ -7,9 +7,9 @@ - + // Paper start - Add BlockBreakBlockEvent + @Override -+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { -+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null; -+ Block.dropResources(state, world, pos, tileentity, source); ++ protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state, BlockPos source) { ++ BlockEntity tileentity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null; ++ Block.dropResources(state, level, pos, tileentity, source); + } + // Paper end - Add BlockBreakBlockEvent @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch index e452ec4ba..a462f3265 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch @@ -82,12 +82,12 @@ - Optional optional = this.load(player, ".dat"); + // CraftBukkit start + return this.load(player.getName().getString(), player.getStringUUID()).map((tag) -> { -+ if (player instanceof ServerPlayer) { -+ CraftPlayer player1 = (CraftPlayer) player.getBukkitEntity(); ++ if (player instanceof ServerPlayer serverPlayer) { ++ CraftPlayer craftPlayer = serverPlayer.getBukkitEntity(); + // Only update first played if it is older than the one we have + long modified = new File(this.playerDir, player.getStringUUID() + ".dat").lastModified(); -+ if (modified < player1.getFirstPlayed()) { -+ player1.setFirstPlayed(modified); ++ if (modified < craftPlayer.getFirstPlayed()) { ++ craftPlayer.setFirstPlayed(modified); + } + } + diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java index 6bf553bd4..c60c05b9e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java @@ -291,13 +291,13 @@ public class CustomChunkGenerator extends InternalChunkGenerator { } @Override - public void applyBiomeDecoration(WorldGenLevel world, ChunkAccess chunk, StructureManager structureAccessor) { + public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager) { WorldgenRandom random = CustomChunkGenerator.getSeededRandom(); int x = chunk.getPos().x; int z = chunk.getPos().z; - random.setSeed(Mth.getSeed(x, "should-decoration".hashCode(), z) ^ world.getSeed()); - super.applyBiomeDecoration(world, chunk, structureAccessor, this.generator.shouldGenerateDecorations(this.world.getWorld(), new RandomSourceWrapper.RandomWrapper(random), x, z)); + random.setSeed(Mth.getSeed(x, "should-decoration".hashCode(), z) ^ level.getSeed()); + super.applyBiomeDecoration(level, chunk, structureManager, this.generator.shouldGenerateDecorations(this.world.getWorld(), new RandomSourceWrapper.RandomWrapper(random), x, z)); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java index 54c443466..f41ea23bb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java @@ -613,8 +613,8 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { } @Override - public BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { - return this.handle.clip(raytrace1, blockposition); + public BlockHitResult clip(ClipContext context, BlockPos traversePos) { + return this.handle.clip(context, traversePos); } @Override From 326c6870479deb7c4f8b5aa22d15795502953c29 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 27 Dec 2024 13:47:25 +0100 Subject: [PATCH 20/40] Fix whack diff from last commit --- .../world/level/BlockGetter.java.patch | 32 +++++++------------ .../util/DelegatedGeneratorAccess.java | 4 +-- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch index 5816f86ef..41d701302 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BlockGetter.java.patch @@ -25,7 +25,7 @@ FluidState getFluidState(BlockPos pos); default int getLightEmission(BlockPos pos) { -@@ -66,19 +_,46 @@ +@@ -66,10 +_,25 @@ ); } @@ -33,39 +33,31 @@ - return traverseBlocks(context.getFrom(), context.getTo(), context, (traverseContext, traversePos) -> { - BlockState blockState = this.getBlockState(traversePos); - FluidState fluidState = this.getFluidState(traversePos); -- Vec3 from = traverseContext.getFrom(); -- Vec3 to = traverseContext.getTo(); -- VoxelShape blockShape = traverseContext.getBlockShape(blockState, this, traversePos); + // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace -+ default BlockHitResult clip(ClipContext context, BlockPos traversePos) { ++ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos) { + // Paper start - Add predicate for blocks when raytracing -+ return clip(context, traversePos, null); ++ return clip(traverseContext, traversePos, null); + } + -+ default BlockHitResult clip(ClipContext context, BlockPos traversePos, java.util.function.Predicate canCollide) { ++ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos, java.util.function.Predicate canCollide) { + // Paper end - Add predicate for blocks when raytracing + // Paper start - Prevent raytrace from loading chunks + BlockState blockState = this.getBlockStateIfLoaded(traversePos); + if (blockState == null) { + // copied the last function parameter (listed below) -+ Vec3 vec3d = context.getFrom().subtract(context.getTo()); ++ Vec3 vec3d = traverseContext.getFrom().subtract(traverseContext.getTo()); + -+ return BlockHitResult.miss(context.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(context.getTo())); ++ return BlockHitResult.miss(traverseContext.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(traverseContext.getTo())); + } + // Paper end - Prevent raytrace from loading chunks + if (blockState.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, traversePos)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate + FluidState fluidState = blockState.getFluidState(); // Paper - Perf: don't need to go to world state again -+ Vec3 from = context.getFrom(); -+ Vec3 to = context.getTo(); -+ VoxelShape blockShape = context.getBlockShape(blockState, this, traversePos); - BlockHitResult blockHitResult = this.clipWithInteractionOverride(from, to, traversePos, blockShape, blockState); -- VoxelShape fluidShape = traverseContext.getFluidShape(fluidState, this, traversePos); -+ VoxelShape fluidShape = context.getFluidShape(fluidState, this, traversePos); - BlockHitResult blockHitResult1 = fluidShape.clip(from, to, traversePos); -- double d = blockHitResult == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult.getLocation()); -- double d1 = blockHitResult1 == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult1.getLocation()); -+ double d = blockHitResult == null ? Double.MAX_VALUE : context.getFrom().distanceToSqr(blockHitResult.getLocation()); -+ double d1 = blockHitResult1 == null ? Double.MAX_VALUE : context.getFrom().distanceToSqr(blockHitResult1.getLocation()); + Vec3 from = traverseContext.getFrom(); + Vec3 to = traverseContext.getTo(); + VoxelShape blockShape = traverseContext.getBlockShape(blockState, this, traversePos); +@@ -79,6 +_,18 @@ + double d = blockHitResult == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult.getLocation()); + double d1 = blockHitResult1 == null ? Double.MAX_VALUE : traverseContext.getFrom().distanceToSqr(blockHitResult1.getLocation()); return d <= d1 ? blockHitResult : blockHitResult1; + } + // CraftBukkit end diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java index f41ea23bb..09e875521 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java @@ -613,8 +613,8 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { } @Override - public BlockHitResult clip(ClipContext context, BlockPos traversePos) { - return this.handle.clip(context, traversePos); + public BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos) { + return this.handle.clip(traverseContext, traversePos); } @Override From 13c94e40ad73be7ff7a1b740cfd2637e93013028 Mon Sep 17 00:00:00 2001 From: 96DarkCode96 <76725766+96DarkCode96@users.noreply.github.com> Date: Fri, 27 Dec 2024 22:04:17 +0100 Subject: [PATCH 21/40] Updated adventure to 4.18.0 (#11809) --- paper-api/build.gradle.kts | 2 +- paper-server/build.gradle.kts | 2 +- .../java/io/papermc/paper/adventure/AdventureCodecs.java | 8 ++++++-- .../io/papermc/paper/adventure/AdventureCodecsTest.java | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/paper-api/build.gradle.kts b/paper-api/build.gradle.kts index 9a03c630b..3ea140477 100644 --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts @@ -11,7 +11,7 @@ java { val annotationsVersion = "24.1.0" val bungeeCordChatVersion = "1.20-R0.2" -val adventureVersion = "4.17.0" +val adventureVersion = "4.18.0" val slf4jVersion = "2.0.9" val log4jVersion = "2.17.1" diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index baa638e0d..09554e3ac 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -128,7 +128,7 @@ dependencies { implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 implementation("net.minecrell:terminalconsoleappender:1.3.0") - implementation("net.kyori:adventure-text-serializer-ansi:4.17.0") // Keep in sync with adventureVersion from Paper-API build file + implementation("net.kyori:adventure-text-serializer-ansi:4.18.0") // Keep in sync with adventureVersion from Paper-API build file /* Required to add the missing Log4j2Plugins.dat file from log4j-core diff --git a/paper-server/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java b/paper-server/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java index 2c5702a42..7a47f0fda 100644 --- a/paper-server/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java +++ b/paper-server/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java @@ -11,7 +11,6 @@ import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; @@ -37,6 +36,7 @@ import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.ShadowColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; @@ -79,6 +79,8 @@ public final class AdventureCodecs { public static final Codec COMPONENT_CODEC = recursive("adventure Component", AdventureCodecs::createCodec); public static final StreamCodec STREAM_COMPONENT_CODEC = ByteBufCodecs.fromCodecWithRegistriesTrusted(COMPONENT_CODEC); + static final Codec SHADOW_COLOR_CODEC = ExtraCodecs.ARGB_COLOR_CODEC.xmap(ShadowColor::shadowColor, ShadowColor::value); + static final Codec TEXT_COLOR_CODEC = Codec.STRING.comapFlatMap(s -> { if (s.startsWith("#")) { @Nullable TextColor value = TextColor.fromHexString(s); @@ -220,6 +222,7 @@ public final class AdventureCodecs { public static final MapCodec