From d5c1214b8e9621bbe7c2d16add870e5bc158809b Mon Sep 17 00:00:00 2001 From: kokiriglade <60290002+kokiriglade@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:10:54 +0000 Subject: [PATCH] Painting variant registry modification API (#11648) --- patches/api/Expanded-Art-API.patch | 40 +++++ ...ntroduce-registry-entry-and-builders.patch | 145 ++++++++++++++++++ .../Add-registry-entry-and-builders.patch | 133 +++++++++++++++- patches/server/DataComponent-API.patch | 2 +- patches/server/Expanded-Art-API.patch | 53 +++++++ 5 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 patches/api/Expanded-Art-API.patch create mode 100644 patches/server/Expanded-Art-API.patch diff --git a/patches/api/Expanded-Art-API.patch b/patches/api/Expanded-Art-API.patch new file mode 100644 index 0000000000..39625adfbf --- /dev/null +++ b/patches/api/Expanded-Art-API.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kokiriglade <60290002+celerry@users.noreply.github.com> +Date: Sat, 23 Nov 2024 18:08:13 +0000 +Subject: [PATCH] Expanded Art API + + +diff --git a/src/main/java/org/bukkit/Art.java b/src/main/java/org/bukkit/Art.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/Art.java ++++ b/src/main/java/org/bukkit/Art.java +@@ -0,0 +0,0 @@ public interface Art extends OldEnum, Keyed { + @NotNull NamespacedKey getKey(); + // Paper end - deprecate getKey + ++ // Paper start - name and author components, assetId key ++ /** ++ * Get the painting's title. ++ * ++ * @return the title ++ */ ++ net.kyori.adventure.text.@Nullable Component title(); ++ ++ /** ++ * Get the painting's author. ++ * ++ * @return the author ++ */ ++ net.kyori.adventure.text.@Nullable Component author(); ++ ++ /** ++ * Get the painting's asset id ++ * ++ * @return the asset id ++ */ ++ net.kyori.adventure.key.@NotNull Key assetId(); ++ // Paper end - name and author components, assetId key ++ + /** + * Get a painting by its numeric ID + * diff --git a/patches/api/Introduce-registry-entry-and-builders.patch b/patches/api/Introduce-registry-entry-and-builders.patch index 6f91370b9f..e345a913fc 100644 --- a/patches/api/Introduce-registry-entry-and-builders.patch +++ b/patches/api/Introduce-registry-entry-and-builders.patch @@ -3,6 +3,7 @@ From: Bjarne Koll Date: Thu, 13 Jun 2024 22:35:05 +0200 Subject: [PATCH] Introduce registry entry and builders +Co-authored-by: kokiriglade diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -414,6 +415,147 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Builder range(@Range(from = 0, to = Integer.MAX_VALUE) int range); + } +} +diff --git a/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java +@@ -0,0 +0,0 @@ ++package io.papermc.paper.registry.data; ++ ++import io.papermc.paper.registry.RegistryBuilder; ++import java.util.Optional; ++import net.kyori.adventure.key.Key; ++import net.kyori.adventure.text.Component; ++import org.bukkit.Art; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.Range; ++import org.jspecify.annotations.NullMarked; ++import org.jspecify.annotations.Nullable; ++ ++/** ++ * A data-centric version-specific registry entry for the {@link Art} type. ++ */ ++@ApiStatus.Experimental ++@NullMarked ++@ApiStatus.NonExtendable ++public interface PaintingVariantRegistryEntry { ++ ++ /** ++ * Provides the width of this variant in blocks. ++ * ++ * @return the width ++ * @see Art#getBlockWidth() ++ */ ++ @Range(from = 1, to = 16) ++ int width(); ++ ++ /** ++ * Provides the height of this variant in blocks. ++ * ++ * @return the height ++ * @see Art#getBlockHeight() ++ */ ++ @Range(from = 1, to = 16) ++ int height(); ++ ++ /** ++ * Provides the title of the painting visible in the creative inventory. ++ * ++ * @return the title ++ * @see Art#title() ++ */ ++ @Nullable Component title(); ++ ++ /** ++ * Provides the author of the painting visible in the creative inventory. ++ * ++ * @return the author ++ * @see Art#author() ++ */ ++ @Nullable Component author(); ++ ++ /** ++ * Provides the assetId of the variant, which is the location of the sprite to use. ++ * ++ * @return the asset id ++ * @see Art#assetId() ++ */ ++ Key assetId(); ++ ++ /** ++ * A mutable builder for the {@link PaintingVariantRegistryEntry} plugins may change in applicable registry events. ++ *

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

    ++ *
  • {@link #width(int)}
  • ++ *
  • {@link #height(int)}
  • ++ *
  • {@link #assetId(Key)}
  • ++ *
++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Builder extends PaintingVariantRegistryEntry, RegistryBuilder { ++ ++ /** ++ * Sets the width of the painting in blocks. ++ * ++ * @param width the width in blocks ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#width() ++ * @see Art#getBlockWidth() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder width(@Range(from = 0, to = 16) int width); ++ ++ /** ++ * Sets the height of the painting in blocks. ++ * ++ * @param height the height in blocks ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#height() ++ * @see Art#getBlockHeight() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder height(@Range(from = 0, to = 16) int height); ++ ++ /** ++ * Sets the title of the painting. ++ * ++ * @param title the title ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#title() ++ * @see Art#title() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder title(@Nullable Component title); ++ ++ /** ++ * Sets the author of the painting. ++ * ++ * @param author the author ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#author() ++ * @see Art#author() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder author(@Nullable Component author); ++ ++ /** ++ * Sets the assetId of the variant, which is the location of the sprite to use. ++ * ++ * @param assetId the asset id ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#assetId() ++ * @see Art#assetId() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder assetId(Key assetId); ++ ++ } ++ ++} diff --git a/src/main/java/io/papermc/paper/registry/data/package-info.java b/src/main/java/io/papermc/paper/registry/data/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -439,6 +581,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import io.papermc.paper.registry.RegistryKey; +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.enchantments.Enchantment; import org.jetbrains.annotations.ApiStatus; @@ -455,6 +599,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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); + private RegistryEvents() { } diff --git a/patches/server/Add-registry-entry-and-builders.patch b/patches/server/Add-registry-entry-and-builders.patch index a607a80cc2..f3bae1a3ed 100644 --- a/patches/server/Add-registry-entry-and-builders.patch +++ b/patches/server/Add-registry-entry-and-builders.patch @@ -15,6 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; +import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; ++import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.tag.TagKey; import java.util.Collections; @@ -35,7 +36,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + writable(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new, PaperEnchantmentRegistryEntry.PaperBuilder::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), entry(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG, JukeboxSong.class, CraftJukeboxSong::new).delayed(), entry(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN, PatternType.class, CraftPatternType::new).delayed(), - entry(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new).delayed(), +- entry(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new).delayed(), ++ writable(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new, PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), + entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new).delayed(), + + // api-only diff --git a/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -339,6 +344,132 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } +} +diff --git a/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java +@@ -0,0 +0,0 @@ ++package io.papermc.paper.registry.data; ++ ++import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.registry.PaperRegistryBuilder; ++import io.papermc.paper.registry.TypedKey; ++import io.papermc.paper.registry.data.util.Conversions; ++import java.util.Optional; ++import java.util.OptionalInt; ++import net.kyori.adventure.key.Key; ++import net.minecraft.network.chat.Component; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.world.entity.decoration.PaintingVariant; ++import org.bukkit.Art; ++import org.jetbrains.annotations.Range; ++import org.jspecify.annotations.NullMarked; ++import org.jspecify.annotations.Nullable; ++ ++import static io.papermc.paper.registry.data.util.Checks.asArgument; ++import static io.papermc.paper.registry.data.util.Checks.asArgumentRange; ++import static io.papermc.paper.registry.data.util.Checks.asConfigured; ++ ++@NullMarked ++public class PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry { ++ ++ protected OptionalInt width = OptionalInt.empty(); ++ protected OptionalInt height = OptionalInt.empty(); ++ protected @Nullable Component title; ++ protected @Nullable Component author; ++ protected @Nullable ResourceLocation assetId; ++ ++ protected final Conversions conversions; ++ ++ public PaperPaintingVariantRegistryEntry( ++ final Conversions conversions, ++ final TypedKey ignoredKey, ++ final @Nullable PaintingVariant nms ++ ) { ++ this.conversions = conversions; ++ if(nms == null) return; ++ ++ this.width = OptionalInt.of(nms.width()); ++ this.height = OptionalInt.of(nms.height()); ++ this.title = nms.title().orElse(null); ++ this.author = nms.title().orElse(null); ++ this.assetId = nms.assetId(); ++ } ++ ++ @Override ++ public @Range(from = 1, to = 16) int width() { ++ return asConfigured(this.width, "width"); ++ } ++ ++ @Override ++ public @Range(from = 1, to = 16) int height() { ++ return asConfigured(this.height, "height"); ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@Nullable Component title() { ++ return this.title == null ? null : this.conversions.asAdventure(this.title); ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@Nullable Component author() { ++ return this.author == null ? null : this.conversions.asAdventure(this.author); ++ } ++ ++ @Override ++ public Key assetId() { ++ return PaperAdventure.asAdventure(asConfigured(this.assetId, "assetId")); ++ } ++ ++ public static final class PaperBuilder extends PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry.Builder, PaperRegistryBuilder { ++ ++ public PaperBuilder(final Conversions conversions, final TypedKey key, final @Nullable PaintingVariant nms) { ++ super(conversions, key, nms); ++ } ++ ++ @Override ++ public Builder width(@Range(from = 0, to = 16) final int width) { ++ this.width = OptionalInt.of(asArgumentRange(width, "width", 1, 16)); ++ return this; ++ } ++ ++ @Override ++ public Builder height(@Range(from = 0, to = 16) final int height) { ++ this.height = OptionalInt.of(asArgumentRange(height, "height", 1, 16)); ++ return this; ++ } ++ ++ @Override ++ public Builder title(final net.kyori.adventure.text.@Nullable Component title) { ++ this.title = this.conversions.asVanilla(title); ++ return this; ++ } ++ ++ @Override ++ public Builder author(final net.kyori.adventure.text.@Nullable Component author) { ++ this.author = this.conversions.asVanilla(author); ++ return this; ++ } ++ ++ @Override ++ public Builder assetId(final Key assetId) { ++ this.assetId = PaperAdventure.asVanilla(asArgument(assetId, "assetId")); ++ return this; ++ } ++ ++ @Override ++ public PaintingVariant build() { ++ return new PaintingVariant( ++ this.width(), ++ this.height(), ++ asConfigured(this.assetId, "assetId"), ++ Optional.ofNullable(this.title), ++ Optional.ofNullable(this.author) ++ ); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/registry/data/util/Checks.java b/src/main/java/io/papermc/paper/registry/data/util/Checks.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/DataComponent-API.patch b/patches/server/DataComponent-API.patch index ca10995882..96a4927eab 100644 --- a/patches/server/DataComponent-API.patch +++ b/patches/server/DataComponent-API.patch @@ -3600,7 +3600,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import io.papermc.paper.datacomponent.PaperComponentType; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; - import io.papermc.paper.registry.entry.RegistryEntry; + import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; @@ -0,0 +0,0 @@ public final class PaperRegistries { entry(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE, Attribute.class, CraftAttribute::new), entry(Registries.FLUID, RegistryKey.FLUID, Fluid.class, CraftFluid::new), diff --git a/patches/server/Expanded-Art-API.patch b/patches/server/Expanded-Art-API.patch new file mode 100644 index 0000000000..8ea7fe8921 --- /dev/null +++ b/patches/server/Expanded-Art-API.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kokiriglade <60290002+celerry@users.noreply.github.com> +Date: Sat, 23 Nov 2024 18:58:49 +0000 +Subject: [PATCH] Expanded Art API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftArt.java b/src/main/java/org/bukkit/craftbukkit/CraftArt.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftArt.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftArt.java +@@ -0,0 +0,0 @@ public class CraftArt implements Art, Handleable { + + private final NamespacedKey key; + private final PaintingVariant paintingVariant; ++ private final net.kyori.adventure.text.@org.jspecify.annotations.Nullable Component adventureTitle; // Paper - name and author components, assetId key ++ private final net.kyori.adventure.text.@org.jspecify.annotations.Nullable Component adventureAuthor; // Paper - name and author components, assetId key ++ private final net.kyori.adventure.key.@org.jspecify.annotations.NonNull Key adventureAssetId; // Paper - name and author components, assetId key + private final String name; + private final int ordinal; + +@@ -0,0 +0,0 @@ public class CraftArt implements Art, Handleable { + this.name = key.toString(); + } + this.ordinal = CraftArt.count++; ++ this.adventureTitle = paintingVariant.title().map(io.papermc.paper.adventure.PaperAdventure::asAdventure).orElse(null); // Paper - name and author components, assetId key ++ this.adventureAuthor = paintingVariant.author().map(io.papermc.paper.adventure.PaperAdventure::asAdventure).orElse(null); // Paper - name and author components, assetId key ++ this.adventureAssetId = io.papermc.paper.adventure.PaperAdventure.asAdventure(paintingVariant.assetId()); // Paper - name and author components, assetId key + } + + @Override +@@ -0,0 +0,0 @@ public class CraftArt implements Art, Handleable { + return this.paintingVariant.height(); + } + ++ // Paper start - name and author components, assetId key ++ @Override ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component title() { ++ return this.adventureTitle; ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component author() { ++ return this.adventureAuthor; ++ } ++ ++ public net.kyori.adventure.key.@org.jspecify.annotations.NonNull Key assetId() { ++ return this.adventureAssetId; ++ } ++ // Paper end - name and author components, assetId key ++ + @Override + public int getId() { + return CraftRegistry.getMinecraftRegistry(Registries.PAINTING_VARIANT).getId(this.paintingVariant);