diff options
-rw-r--r-- | patches/api/0485-WIP-DataComponent-API.patch | 514 | ||||
-rw-r--r-- | patches/server/1054-WIP-DataComponent-API.patch | 851 |
2 files changed, 1334 insertions, 31 deletions
diff --git a/patches/api/0485-WIP-DataComponent-API.patch b/patches/api/0485-WIP-DataComponent-API.patch index d3de7b1237..660b3e2e14 100644 --- a/patches/api/0485-WIP-DataComponent-API.patch +++ b/patches/api/0485-WIP-DataComponent-API.patch @@ -39,34 +39,46 @@ index 0000000000000000000000000000000000000000..50d15b4e0ed5cd17fdc95476ee4650ef +} diff --git a/src/main/java/io/papermc/paper/component/DataComponentTypes.java b/src/main/java/io/papermc/paper/component/DataComponentTypes.java new file mode 100644 -index 0000000000000000000000000000000000000000..ea1a789086ba3f853cc0ac91cbe603fc3c416592 +index 0000000000000000000000000000000000000000..e094dbc6919ee7fe08270e8865f80375b4dc7f8a --- /dev/null +++ b/src/main/java/io/papermc/paper/component/DataComponentTypes.java -@@ -0,0 +1,99 @@ +@@ -0,0 +1,111 @@ +package io.papermc.paper.component; + ++import io.papermc.paper.component.item.BannerPatternLayers; +import io.papermc.paper.component.item.BundleContents; +import io.papermc.paper.component.item.ChargedProjectiles; +import io.papermc.paper.component.item.CustomModelData; +import io.papermc.paper.component.item.DyedItemColor; ++import io.papermc.paper.component.item.Fireworks; +import io.papermc.paper.component.item.FoodProperties; ++import io.papermc.paper.component.item.ItemArmorTrim; +import io.papermc.paper.component.item.ItemAttributeModifiers; ++import io.papermc.paper.component.item.ItemContainerContents; +import io.papermc.paper.component.item.ItemEnchantments; +import io.papermc.paper.component.item.ItemLore; ++import io.papermc.paper.component.item.LockCode; ++import io.papermc.paper.component.item.LodestoneTracker; +import io.papermc.paper.component.item.MapDecorations; +import io.papermc.paper.component.item.MapID; +import io.papermc.paper.component.item.MapItemColor; +import io.papermc.paper.component.item.MapPostProcessing; +import io.papermc.paper.component.item.PotDecorations; +import io.papermc.paper.component.item.PotionContents; ++import io.papermc.paper.component.item.ResolvableProfile; +import io.papermc.paper.component.item.SeededContainerLoot; +import io.papermc.paper.component.item.SuspiciousStewEffects; +import io.papermc.paper.component.item.Unbreakable; ++import io.papermc.paper.component.item.WritableBookContent; ++import io.papermc.paper.component.item.WrittenBookContent; +import net.kyori.adventure.text.Component; +import org.bukkit.DyeColor; ++import org.bukkit.FireworkEffect; ++import org.bukkit.MusicInstrument; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.ItemRarity; ++import org.bukkit.inventory.meta.WritableBookMeta; +import java.security.Key; +import java.util.List; + @@ -106,28 +118,28 @@ index 0000000000000000000000000000000000000000..ea1a789086ba3f853cc0ac91cbe603fc + public static final DataComponentType.Valued<BundleContents> BUNDLE_CONTENTS = valued("bundle_contents"); + public static final DataComponentType.Valued<PotionContents> POTION_CONTENTS = valued("potion_contents"); + public static final DataComponentType.Valued<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = valued("suspicious_stew_effects"); -+ // writable_book_content -+ // written_book_content -+ // trim ++ public static final DataComponentType.Valued<WritableBookContent> WRITABLE_BOOK_CONTENT = valued("writable_book_content"); ++ public static final DataComponentType.Valued<WrittenBookContent> WRITTEN_BOOK_CONTENT = valued("written_book_content"); ++ public static final DataComponentType.Valued<ItemArmorTrim> TRIM = valued("trim"); + // debug_stick_state - Block Property API + // entity_data + // bucket_entity_data + // block_entity_data -+ // instrument ++ public static final DataComponentType.Valued<MusicInstrument> INSTRUMENT = valued("instrument"); + public static final DataComponentType.Valued<Integer> OMINOUS_BOTTLE_AMPLIFIER = valued("ominous_bottle_amplifier"); + public static final DataComponentType.Valued<List<Key>> RECIPES = valued("recipes"); -+ // lodestone_tracker -+ // firework_explosion -+ // fireworks -+ // profile -+ // note_block_sound -+ // banner_patterns ++ public static final DataComponentType.Valued<LodestoneTracker> LODESTONE_TRACKER = valued("lodestone_tracker"); ++ public static final DataComponentType.Valued<FireworkEffect> FIREWORK_EXPLOSION = valued("firework_explosion"); ++ public static final DataComponentType.Valued<Fireworks> FIREWORKS = valued("fireworks"); ++ public static final DataComponentType.Valued<ResolvableProfile> PROFILE = valued("profile"); ++ public static final DataComponentType.Valued<NamespacedKey> NOTE_BLOCK_SOUND = valued("note_block_sound"); ++ public static final DataComponentType.Valued<BannerPatternLayers> BANNER_PATTERNS = valued("banner_patterns"); + public static final DataComponentType.Valued<DyeColor> BASE_COLOR = valued("base_color"); + public static final DataComponentType.Valued<PotDecorations> POT_DECORATIONS = valued("pot_decorations"); -+ // container ++ public static final DataComponentType.Valued<ItemContainerContents> CONTAINER = valued("container"); + // block_state + // bees -+ // lock ++ public static final DataComponentType.Valued<LockCode> LOCK = valued("lock"); + public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot"); + + private static DataComponentType.NonValued unvalued(final String name) { @@ -142,6 +154,46 @@ index 0000000000000000000000000000000000000000..ea1a789086ba3f853cc0ac91cbe603fc + private DataComponentTypes() { + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/BannerPatternLayers.java b/src/main/java/io/papermc/paper/component/item/BannerPatternLayers.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a6afa95840ba6dce2f7cd08451c385e04e629520 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/BannerPatternLayers.java +@@ -0,0 +1,34 @@ ++package io.papermc.paper.component.item; ++ ++import org.bukkit.block.banner.Pattern; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.Unmodifiable; ++import java.util.List; ++ ++public interface BannerPatternLayers { ++ ++ @Contract(value = "-> new", pure = true) ++ static BannerPatternLayers.@NonNull Builder bannerPatternLayers() { ++ return ComponentTypesBridge.Holder.bridge().bannerPatternLayers(); ++ } ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull @Unmodifiable List<Pattern> getPatterns(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder add(@NonNull Pattern pattern); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addAll(@NonNull List<Pattern> patterns); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ BannerPatternLayers build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/BundleContents.java b/src/main/java/io/papermc/paper/component/item/BundleContents.java new file mode 100644 index 0000000000000000000000000000000000000000..8686f4022395d3cd64a077b388e6f48595dac6f7 @@ -222,10 +274,10 @@ index 0000000000000000000000000000000000000000..dcf759607fd49aefd2abce280e0f3f43 +} diff --git a/src/main/java/io/papermc/paper/component/item/ComponentTypesBridge.java b/src/main/java/io/papermc/paper/component/item/ComponentTypesBridge.java new file mode 100644 -index 0000000000000000000000000000000000000000..0173820bd80354e4af215398db9308d38c6e59ab +index 0000000000000000000000000000000000000000..62395ea2f1f63ecb64e712840b561f099eee877e --- /dev/null +++ b/src/main/java/io/papermc/paper/component/item/ComponentTypesBridge.java -@@ -0,0 +1,58 @@ +@@ -0,0 +1,76 @@ +package io.papermc.paper.component.item; + +import java.util.Optional; @@ -274,6 +326,24 @@ index 0000000000000000000000000000000000000000..0173820bd80354e4af215398db9308d3 + + SeededContainerLoot.Builder seededContainerLoot(final Key lootTableKey); + ++ WrittenBookContent.Builder writtenBookContent(); ++ ++ WritableBookContent.Builder writeableBookContent(); ++ ++ ItemArmorTrim.Builder itemArmorTrim(); ++ ++ LodestoneTracker.Builder lodestoneTracker(); ++ ++ Fireworks.Builder fireworks(); ++ ++ ResolvableProfile.Builder resolvableProfile(); ++ ++ BannerPatternLayers.Builder bannerPatternLayers(); ++ ++ LockCode.Builder lockCode(); ++ ++ ItemContainerContents.Builder itemContainerContents(); ++ + @ApiStatus.Internal + final class Holder { + @@ -350,6 +420,52 @@ index 0000000000000000000000000000000000000000..825ec454ad412ecacce8da8c2a8dcc35 + @NonNull DyedItemColor build(); + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/Fireworks.java b/src/main/java/io/papermc/paper/component/item/Fireworks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1e698ab0ce40d4cf1b9f8386f3a06115db531415 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/Fireworks.java +@@ -0,0 +1,40 @@ ++package io.papermc.paper.component.item; ++ ++import java.util.List; ++import org.bukkit.FireworkEffect; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface Fireworks { ++ ++ @Contract(value = "-> new", pure = true) ++ static Fireworks.@NonNull Builder fireworks() { ++ return ComponentTypesBridge.Holder.bridge().fireworks(); ++ } ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull @Unmodifiable List<FireworkEffect> effects(); ++ ++ int flightDuration(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder flightDuration(@NonNull int duration); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder add(@NonNull FireworkEffect effect); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addAll(@NonNull List<FireworkEffect> effects); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ Fireworks build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/FoodProperties.java b/src/main/java/io/papermc/paper/component/item/FoodProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..fd8a2c011c214fe667938c22fdbe0c54db676e6f @@ -417,6 +533,42 @@ index 0000000000000000000000000000000000000000..fd8a2c011c214fe667938c22fdbe0c54 + @NonNull FoodProperties build(); + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/ItemArmorTrim.java b/src/main/java/io/papermc/paper/component/item/ItemArmorTrim.java +new file mode 100644 +index 0000000000000000000000000000000000000000..98c916092a30550308a03a0030d7b08693374b28 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/ItemArmorTrim.java +@@ -0,0 +1,30 @@ ++package io.papermc.paper.component.item; ++ ++import org.bukkit.inventory.meta.trim.ArmorTrim; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++public interface ItemArmorTrim extends ShownInTooltip<ItemArmorTrim> { ++ ++ @Contract(value = "-> new", pure = true) ++ static ItemArmorTrim.@NonNull Builder itemArmorTrim() { ++ return ComponentTypesBridge.Holder.bridge().itemArmorTrim(); ++ } ++ ++ @NotNull ++ ArmorTrim armorTrim(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder extends ShownInTooltip.Builder<Builder> { ++ ++ @Contract(value = "_, _, _ -> this", mutates = "this") ++ @NonNull Builder armorTrim(@NonNull ArmorTrim armorTrim); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ ItemArmorTrim build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/ItemAttributeModifiers.java b/src/main/java/io/papermc/paper/component/item/ItemAttributeModifiers.java new file mode 100644 index 0000000000000000000000000000000000000000..ab1ed5e705256855dc35300161bc922f02e8227a @@ -459,6 +611,46 @@ index 0000000000000000000000000000000000000000..ab1ed5e705256855dc35300161bc922f + @NonNull ItemAttributeModifiers build(); + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/ItemContainerContents.java b/src/main/java/io/papermc/paper/component/item/ItemContainerContents.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fd297e9ec49a78adc34e39eb6ee446a8b2840513 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/ItemContainerContents.java +@@ -0,0 +1,34 @@ ++package io.papermc.paper.component.item; ++ ++import java.util.List; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface ItemContainerContents { ++ ++ @Contract(value = "-> new", pure = true) ++ static ItemContainerContents.@NonNull Builder bundleContents() { ++ return ComponentTypesBridge.Holder.bridge().itemContainerContents(); ++ } ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull @Unmodifiable List<ItemStack> getItems(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder add(@NonNull ItemStack itemStack); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addAll(@NonNull List<ItemStack> itemStack); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ ItemContainerContents build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/ItemEnchantments.java b/src/main/java/io/papermc/paper/component/item/ItemEnchantments.java new file mode 100644 index 0000000000000000000000000000000000000000..ee1b18269cbc1b71f753d9eea2dfe59ffbc69e2c @@ -551,6 +743,85 @@ index 0000000000000000000000000000000000000000..0f9f645ad2fbffb26636dfb702295fb3 + + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/LockCode.java b/src/main/java/io/papermc/paper/component/item/LockCode.java +new file mode 100644 +index 0000000000000000000000000000000000000000..08e4b46ec6c0be076eeeb91153365b1f0c815e52 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/LockCode.java +@@ -0,0 +1,28 @@ ++package io.papermc.paper.component.item; ++ ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++public interface LockCode { ++ ++ @Contract(value = "-> new", pure = true) ++ static LockCode.@NonNull Builder lockCode() { ++ return ComponentTypesBridge.Holder.bridge().lockCode(); ++ } ++ ++ String lock(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder lock(@NotNull String code); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ LockCode build(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/component/item/LodestoneTracker.java b/src/main/java/io/papermc/paper/component/item/LodestoneTracker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c931a9aed26334888ac982e6373c0fe6047d54b0 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/LodestoneTracker.java +@@ -0,0 +1,39 @@ ++package io.papermc.paper.component.item; ++ ++import io.papermc.paper.util.Filtered; ++import java.util.Collection; ++import java.util.List; ++import org.bukkit.Location; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface LodestoneTracker { ++ ++ @Contract(value = "-> new", pure = true) ++ static LodestoneTracker.@NonNull Builder lodestoneTracker() { ++ return ComponentTypesBridge.Holder.bridge().lodestoneTracker(); ++ } ++ ++ @Nullable Location location(); ++ ++ boolean tracked(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder location(@Nullable Location page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder tracked(boolean tracked); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ LodestoneTracker build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/MapDecorations.java b/src/main/java/io/papermc/paper/component/item/MapDecorations.java new file mode 100644 index 0000000000000000000000000000000000000000..d22f08c08c209facd31c14c44c52221f0105b35b @@ -783,6 +1054,63 @@ index 0000000000000000000000000000000000000000..2fea9c373b4a86f98510bcf85979e35e + @NonNull PotionContents build(); + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/ResolvableProfile.java b/src/main/java/io/papermc/paper/component/item/ResolvableProfile.java +new file mode 100644 +index 0000000000000000000000000000000000000000..56489fc38cfa180463799e902a3d3fbaf67ed84d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/ResolvableProfile.java +@@ -0,0 +1,51 @@ ++package io.papermc.paper.component.item; ++ ++import java.util.Collection; ++import java.util.List; ++import java.util.UUID; ++import java.util.concurrent.CompletableFuture; ++import com.destroystokyo.paper.profile.PlayerProfile; ++import com.destroystokyo.paper.profile.ProfileProperty; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface ResolvableProfile { ++ ++ @Contract(value = "-> new", pure = true) ++ static ResolvableProfile.@NonNull Builder resolvableProfile() { ++ return ComponentTypesBridge.Holder.bridge().resolvableProfile(); ++ } ++ ++ @Nullable UUID uuid(); ++ ++ @Nullable String name(); ++ ++ @Unmodifiable @NonNull Collection<ProfileProperty> properties(); ++ ++ @NotNull CompletableFuture<PlayerProfile> resolve(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder name(@Nullable String name); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder uuid(@Nullable UUID uuid); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addAllProperties(@NonNull List<ProfileProperty> properties); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addProperty(@NonNull ProfileProperty property); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ ResolvableProfile build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/SeededContainerLoot.java b/src/main/java/io/papermc/paper/component/item/SeededContainerLoot.java new file mode 100644 index 0000000000000000000000000000000000000000..eb89ff28b773f3fe24b0073513d5fc2abf4c370e @@ -922,6 +1250,128 @@ index 0000000000000000000000000000000000000000..36e48ef697c001fff1697542eae6f79b + + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/WritableBookContent.java b/src/main/java/io/papermc/paper/component/item/WritableBookContent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..919b81435247986177c17f1c6e4424b2c61dbdd9 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/WritableBookContent.java +@@ -0,0 +1,42 @@ ++package io.papermc.paper.component.item; ++ ++import io.papermc.paper.util.Filtered; ++import java.util.Collection; ++import java.util.List; ++import net.kyori.adventure.text.Component; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface WritableBookContent { ++ ++ @Contract(value = "-> new", pure = true) ++ static WritableBookContent.@NonNull Builder writeableBookContent() { ++ return ComponentTypesBridge.Holder.bridge().writeableBookContent(); ++ } ++ ++ @NotNull @Unmodifiable List<Filtered<String>> pages(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPage(@NonNull String page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPages(@NonNull Collection<String> page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPageFiltered(@NonNull Filtered<String> page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPagesFiltered(@NonNull Collection<Filtered<String>> pages); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ WritableBookContent build(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/component/item/WrittenBookContent.java b/src/main/java/io/papermc/paper/component/item/WrittenBookContent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ed3969d9bd0332d845c655da3c271aff08f1b752 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/WrittenBookContent.java +@@ -0,0 +1,68 @@ ++package io.papermc.paper.component.item; ++ ++import java.util.Collection; ++import java.util.List; ++import java.util.logging.Filter; ++import io.papermc.paper.util.Filtered; ++import net.kyori.adventure.text.Component; ++import org.bukkit.potion.PotionEffect; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++public interface WrittenBookContent { ++ ++ @Contract(value = "-> new", pure = true) ++ static WrittenBookContent.@NonNull Builder writtenBookContent() { ++ return ComponentTypesBridge.Holder.bridge().writtenBookContent(); ++ } ++ ++ @NotNull Filtered<String> title(); ++ ++ @NotNull String author(); ++ ++ int generation(); ++ ++ @NotNull @Unmodifiable List<Filtered<Component>> pages(); ++ ++ boolean resolved(); ++ ++ @ApiStatus.NonExtendable ++ interface Builder { ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder title(@NonNull String title); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder titleFiltered(@NonNull Filtered<String> title); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder author(@NonNull String author); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder generation(int generation); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder resolved(boolean resolved); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPage(@NonNull Component page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPages(@NonNull Collection<Component> page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPageFiltered(@NonNull Filtered<Component> page); ++ ++ @Contract(value = "_ -> this", mutates = "this") ++ @NonNull Builder addPagesFiltered(@NonNull Collection<Filtered<Component>> pages); ++ ++ @Contract(value = "-> new", pure = true) ++ @NonNull ++ WrittenBookContent build(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/package-info.java b/src/main/java/io/papermc/paper/component/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..37c9e2b084fe4c82242ae64569bb76beb6a88c09 @@ -950,6 +1400,38 @@ index 7b79bf33074355020e0b3b5ef40c7f2e6ba644b4..5cf3aa4641822c91adfbd70a847ca529 RegistryKey<MapCursor.Type> MAP_DECORATION_TYPE = create("map_decoration_type"); + RegistryKey<DataComponentType> DATA_COMPONENT_TYPE = create("data_component_type"); } +diff --git a/src/main/java/io/papermc/paper/util/Filtered.java b/src/main/java/io/papermc/paper/util/Filtered.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c3355a59d008920ab4afb910925f433548e2f956 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/util/Filtered.java +@@ -0,0 +1,26 @@ ++package io.papermc.paper.util; ++ ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Denotes that this type is filterable by the client, and may be shown differently ++ * depending on the player's set configuration. ++ * @param <T> type of value ++ */ ++public interface Filtered<T> { ++ ++ static <T> Filtered<T> of(@NonNull T raw, @Nullable T filtered) { ++ record Instance<T>(T raw, T filtered) implements Filtered<T> { } ++ ++ return new Instance<>(raw, filtered); ++ } ++ ++ T raw(); ++ ++ @Nullable ++ T filtered(); ++} diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java index 7509b61dfdc0a6675256970cb850b08f9e814580..28e2628d8d0a6af742b2fa89e5581e6b0d1a38a4 100644 --- a/src/main/java/org/bukkit/Material.java diff --git a/patches/server/1054-WIP-DataComponent-API.patch b/patches/server/1054-WIP-DataComponent-API.patch index 16317fd188..10a6b4746c 100644 --- a/patches/server/1054-WIP-DataComponent-API.patch +++ b/patches/server/1054-WIP-DataComponent-API.patch @@ -37,26 +37,33 @@ index 0000000000000000000000000000000000000000..e538819c873a324c58bcd8e73f89510e +} diff --git a/src/main/java/io/papermc/paper/component/ComponentAdapters.java b/src/main/java/io/papermc/paper/component/ComponentAdapters.java new file mode 100644 -index 0000000000000000000000000000000000000000..e6a57e276cfa8be5943302edafbbdeb3f5aff404 +index 0000000000000000000000000000000000000000..08e04fb9ecd9be1c3b13d114d07040bb36fec4c1 --- /dev/null +++ b/src/main/java/io/papermc/paper/component/ComponentAdapters.java -@@ -0,0 +1,151 @@ +@@ -0,0 +1,162 @@ +package io.papermc.paper.component; + +import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.component.item.PaperBannerPatternLayers; +import io.papermc.paper.component.item.PaperBundleContents; +import io.papermc.paper.component.item.PaperChargedProjectiles; +import io.papermc.paper.component.item.PaperCustomModelData; +import io.papermc.paper.component.item.PaperDyedItemColor; ++import io.papermc.paper.component.item.PaperFireworks; +import io.papermc.paper.component.item.PaperFoodProperties; ++import io.papermc.paper.component.item.PaperItemArmorTrim; +import io.papermc.paper.component.item.PaperItemAttributeModifiers; ++import io.papermc.paper.component.item.PaperItemContainerContents; +import io.papermc.paper.component.item.PaperItemEnchantments; +import io.papermc.paper.component.item.PaperItemLore; ++import io.papermc.paper.component.item.PaperLockCode; ++import io.papermc.paper.component.item.PaperLodestoneTracker; +import io.papermc.paper.component.item.PaperMapDecorations; +import io.papermc.paper.component.item.PaperMapID; +import io.papermc.paper.component.item.PaperMapItemColor; +import io.papermc.paper.component.item.PaperPotDecorations; +import io.papermc.paper.component.item.PaperPotionContents; ++import io.papermc.paper.component.item.PaperResolvableProfile; +import io.papermc.paper.component.item.PaperSeededContainerLoot; +import io.papermc.paper.component.item.PaperSuspiciousStewEffects; +import io.papermc.paper.component.item.PaperUnbreakable; @@ -66,6 +73,8 @@ index 0000000000000000000000000000000000000000..e6a57e276cfa8be5943302edafbbdeb3 +import java.util.List; +import java.util.Map; +import java.util.function.Function; ++import io.papermc.paper.component.item.PaperWritableBookContent; ++import io.papermc.paper.component.item.PaperWrittenBookContent; +import net.kyori.adventure.key.Key; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; @@ -76,6 +85,8 @@ index 0000000000000000000000000000000000000000..e6a57e276cfa8be5943302edafbbdeb3 +import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.component.MapPostProcessing; +import org.bukkit.DyeColor; ++import org.bukkit.craftbukkit.CraftMusicInstrument; ++import org.bukkit.craftbukkit.inventory.CraftMetaFirework; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.Handleable; +import org.bukkit.inventory.ItemRarity; @@ -125,9 +136,9 @@ index 0000000000000000000000000000000000000000..e6a57e276cfa8be5943302edafbbdeb3 + register(DataComponents.BUNDLE_CONTENTS, PaperBundleContents::new); + register(DataComponents.POTION_CONTENTS, PaperPotionContents::new); + register(DataComponents.SUSPICIOUS_STEW_EFFECTS, PaperSuspiciousStewEffects::new); -+ // writable book content -+ // written book content -+ // trim ++ register(DataComponents.WRITTEN_BOOK_CONTENT, PaperWrittenBookContent::new); ++ register(DataComponents.WRITABLE_BOOK_CONTENT, PaperWritableBookContent::new); ++ register(DataComponents.TRIM, PaperItemArmorTrim::new); + // debug stick state + // entity data + // bucket entity data @@ -148,16 +159,16 @@ index 0000000000000000000000000000000000000000..e6a57e276cfa8be5943302edafbbdeb3 + + return Collections.unmodifiableList(nms); + }); -+ // lodestone tracker -+ // firework explosion -+ // fireworks -+ // profile -+ // note block sound ++ register(DataComponents.LODESTONE_TRACKER, PaperLodestoneTracker::new); ++ register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion); ++ register(DataComponents.FIREWORKS, PaperFireworks::new); ++ register(DataComponents.PROFILE, PaperResolvableProfile::new); ++ register(DataComponents.NOTE_BLOCK_SOUND, CraftNamespacedKey::fromMinecraft, CraftNamespacedKey::toMinecraft); + register(DataComponents.BASE_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData())); + register(DataComponents.POT_DECORATIONS, PaperPotDecorations::new); + // block state (block data) + // bees -+ // lock ++ register(DataComponents.LOCK, PaperLockCode::new); + register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new); + + // TODO: REMOVE THIS... we want to build the PR... so lets just make things UNTYPED! @@ -318,10 +329,10 @@ index 0000000000000000000000000000000000000000..5639559368e6866e9b0afa6688f3b12c +} diff --git a/src/main/java/io/papermc/paper/component/item/ComponentTypesBridgesImpl.java b/src/main/java/io/papermc/paper/component/item/ComponentTypesBridgesImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..c6583b428491d5d523a40ef42a94d4c1184b8ed9 +index 0000000000000000000000000000000000000000..548c392e045fd8ca6ebdbb3e6ee871cabceab707 --- /dev/null +++ b/src/main/java/io/papermc/paper/component/item/ComponentTypesBridgesImpl.java -@@ -0,0 +1,99 @@ +@@ -0,0 +1,139 @@ +package io.papermc.paper.component.item; + +import net.kyori.adventure.key.Key; @@ -420,6 +431,120 @@ index 0000000000000000000000000000000000000000..c6583b428491d5d523a40ef42a94d4c1 + public SeededContainerLoot.Builder seededContainerLoot(final Key lootTableKey) { + return new PaperSeededContainerLoot.BuilderImpl(new NamespacedKey(lootTableKey.namespace(), lootTableKey.value())); + } ++ ++ @Override ++ public WrittenBookContent.Builder writtenBookContent() { ++ return new PaperWrittenBookContent.BuilderImpl(); ++ } ++ ++ @Override ++ public WritableBookContent.Builder writeableBookContent() { ++ return new PaperWritableBookContent.BuilderImpl(); ++ } ++ ++ @Override ++ public ItemArmorTrim.Builder itemArmorTrim() { ++ return new PaperItemArmorTrim.BuilderImpl(); ++ } ++ ++ @Override ++ public LodestoneTracker.Builder lodestoneTracker() { ++ return new PaperLodestoneTracker.BuilderImpl(); ++ } ++ ++ @Override ++ public Fireworks.Builder fireworks() { ++ return new PaperFireworks.BuilderImpl(); ++ } ++ ++ @Override ++ public ResolvableProfile.Builder resolvableProfile() { ++ return new PaperResolvableProfile.BuilderImpl(); ++ } ++ ++ @Override ++ public BannerPatternLayers.Builder bannerPatternLayers() { ++ return new PaperBannerPatternLayers.BuilderImpl(); ++ } ++ ++ @Override ++ public LockCode.Builder lockCode() { ++ return new PaperLockCode.BuilderImpl(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperBannerPatternLayers.java b/src/main/java/io/papermc/paper/component/item/PaperBannerPatternLayers.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fa1d453538d9fa1e0efa6bfffdf0ae9dd1c616e5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperBannerPatternLayers.java +@@ -0,0 +1,68 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.base.Function; ++import com.google.common.collect.Lists; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.List; ++import java.util.Optional; ++import org.bukkit.DyeColor; ++import org.bukkit.block.banner.Pattern; ++import org.bukkit.block.banner.PatternType; ++import org.bukkit.craftbukkit.CraftRegistry; ++import org.bukkit.craftbukkit.block.banner.CraftPatternType; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.Unmodifiable; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperBannerPatternLayers( ++ net.minecraft.world.level.block.entity.BannerPatternLayers impl ++) implements BannerPatternLayers, Handleable<net.minecraft.world.level.block.entity.BannerPatternLayers> { ++ ++ @Override ++ public net.minecraft.world.level.block.entity.BannerPatternLayers getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @NonNull @Unmodifiable List<Pattern> getPatterns() { ++ return Collections.unmodifiableList( ++ Lists.transform( ++ this.impl.layers(), // this already copies the itemstacks to maintain immutability ++ input -> { ++ Optional<PatternType> type = CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.BANNER_PATTERN, input.pattern()); ++ return new Pattern(DyeColor.getByWoolData((byte) input.color().getId()), type.orElseThrow()); ++ } ++ ) ++ ); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private final net.minecraft.world.level.block.entity.BannerPatternLayers.Builder builder = new net.minecraft.world.level.block.entity.BannerPatternLayers.Builder(); ++ ++ @Override ++ public @NonNull Builder add(@NonNull final Pattern pattern) { ++ this.builder.add( ++ CraftPatternType.bukkitToMinecraftHolder(pattern.getPattern()), ++ net.minecraft.world.item.DyeColor.byId(pattern.getColor().getWoolData()) ++ ); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addAll(@NonNull final List<Pattern> patterns) { ++ patterns.forEach(this::add); ++ return this; ++ } ++ ++ @Override ++ public @NonNull BannerPatternLayers build() { ++ return new PaperBannerPatternLayers(this.builder.build()); ++ } ++ } +} diff --git a/src/main/java/io/papermc/paper/component/item/PaperBundleContents.java b/src/main/java/io/papermc/paper/component/item/PaperBundleContents.java new file mode 100644 @@ -650,6 +775,82 @@ index 0000000000000000000000000000000000000000..1e2b03f7de79a2b2559bb896f2ea8286 + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperFireworks.java b/src/main/java/io/papermc/paper/component/item/PaperFireworks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3c32b35ed56eb238ff6562a6512aa1d7d007fb2f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperFireworks.java +@@ -0,0 +1,70 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.collect.Lists; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.List; ++import net.minecraft.world.item.component.FireworkExplosion; ++import org.bukkit.FireworkEffect; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftMetaFirework; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.Unmodifiable; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperFireworks( ++ net.minecraft.world.item.component.Fireworks impl ++) implements Fireworks, Handleable<net.minecraft.world.item.component.Fireworks> { ++ ++ @Override ++ public net.minecraft.world.item.component.Fireworks getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @NonNull @Unmodifiable List<FireworkEffect> effects() { ++ return Collections.unmodifiableList( ++ Lists.transform( ++ this.impl.explosions(), ++ CraftMetaFirework::getEffect ++ ) ++ ); ++ } ++ ++ @Override ++ public int flightDuration() { ++ return this.impl.flightDuration(); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private final List<FireworkExplosion> effects = new ArrayList<>(); ++ private int duration; ++ ++ @Override ++ public @NonNull Builder flightDuration(@NonNull final int duration) { ++ this.duration = duration; ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder add(@NonNull final FireworkEffect effect) { ++ this.effects.add(CraftMetaFirework.getExplosion(effect)); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addAll(@NonNull final List<FireworkEffect> effects) { ++ effects.forEach(this::add); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Fireworks build() { ++ return new PaperFireworks(new net.minecraft.world.item.component.Fireworks(this.duration, this.effects)); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/PaperFoodProperties.java b/src/main/java/io/papermc/paper/component/item/PaperFoodProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..cb19f766943ac3aabddf03b958d151c25f8a9a16 @@ -777,6 +978,83 @@ index 0000000000000000000000000000000000000000..cb19f766943ac3aabddf03b958d151c2 + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperItemArmorTrim.java b/src/main/java/io/papermc/paper/component/item/PaperItemArmorTrim.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3f1c41aa799e02fff1af787d63c9e5efa8f851e8 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperItemArmorTrim.java +@@ -0,0 +1,71 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.collect.Lists; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.List; ++import org.bukkit.attribute.Attribute; ++import org.bukkit.attribute.AttributeModifier; ++import org.bukkit.craftbukkit.CraftEquipmentSlot; ++import org.bukkit.craftbukkit.attribute.CraftAttribute; ++import org.bukkit.craftbukkit.attribute.CraftAttributeInstance; ++import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial; ++import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.bukkit.inventory.EquipmentSlotGroup; ++import org.bukkit.inventory.meta.trim.ArmorTrim; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperItemArmorTrim( ++ net.minecraft.world.item.armortrim.ArmorTrim impl ++) implements ItemArmorTrim, Handleable<net.minecraft.world.item.armortrim.ArmorTrim> { ++ ++ @Override ++ public net.minecraft.world.item.armortrim.ArmorTrim getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public boolean showInTooltip() { ++ return this.impl.showInTooltip; ++ } ++ ++ @Override ++ public ItemArmorTrim showInTooltip(final boolean showInTooltip) { ++ return new PaperItemArmorTrim(this.impl.withTooltip(showInTooltip)); ++ } ++ ++ @Override ++ public @NotNull ArmorTrim armorTrim() { ++ return new ArmorTrim(CraftTrimMaterial.minecraftHolderToBukkit(this.impl.material()), CraftTrimPattern.minecraftHolderToBukkit(this.impl.pattern())); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private net.minecraft.world.item.armortrim.ArmorTrim armorTrim; ++ private boolean showInTooltip = true; ++ ++ @Override ++ public Builder showInTooltip(final boolean showInTooltip) { ++ this.showInTooltip = showInTooltip; ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder armorTrim(@NonNull final ArmorTrim armorTrim) { ++ this.armorTrim = new net.minecraft.world.item.armortrim.ArmorTrim( ++ CraftTrimMaterial.bukkitToMinecraftHolder(armorTrim.getMaterial()), ++ CraftTrimPattern.bukkitToMinecraftHolder(armorTrim.getPattern()) ++ ); ++ return this; ++ } ++ ++ @Override ++ public @NonNull ItemArmorTrim build() { ++ return new PaperItemArmorTrim(this.armorTrim.withTooltip(this.showInTooltip)); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/PaperItemAttributeModifiers.java b/src/main/java/io/papermc/paper/component/item/PaperItemAttributeModifiers.java new file mode 100644 index 0000000000000000000000000000000000000000..26b195f590025406232fde513f602fd3ff536405 @@ -872,6 +1150,64 @@ index 0000000000000000000000000000000000000000..26b195f590025406232fde513f602fd3 + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperItemContainerContents.java b/src/main/java/io/papermc/paper/component/item/PaperItemContainerContents.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4227aa0b63ac4041b0ddc9821e4573ca791158b1 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperItemContainerContents.java +@@ -0,0 +1,52 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.collect.Lists; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.List; ++import java.util.stream.Collectors; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperItemContainerContents( ++ net.minecraft.world.item.component.ItemContainerContents impl ++) implements ItemContainerContents, Handleable<net.minecraft.world.item.component.ItemContainerContents> { ++ ++ @Override ++ public net.minecraft.world.item.component.ItemContainerContents getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public List<ItemStack> getItems() { ++ return this.impl.stream().map(CraftItemStack::asCraftMirror).collect(Collectors.toUnmodifiableList()); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private final List<net.minecraft.world.item.ItemStack> items = new ArrayList<>(); ++ ++ @Override ++ public Builder add(final ItemStack itemStack) { ++ this.items.add(CraftItemStack.asNMSCopy(itemStack)); ++ return this; ++ } ++ ++ @Override ++ public Builder addAll(final List<ItemStack> itemStack) { ++ for (final ItemStack item : itemStack) { ++ this.items.add(CraftItemStack.asNMSCopy(item)); ++ } ++ return this; ++ } ++ ++ @Override ++ public ItemContainerContents build() { ++ return new PaperItemContainerContents(net.minecraft.world.item.component.ItemContainerContents.fromItems(this.items)); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/PaperItemEnchantments.java b/src/main/java/io/papermc/paper/component/item/PaperItemEnchantments.java new file mode 100644 index 0000000000000000000000000000000000000000..ed99ed52fe47b231dae2b78bd1bc363389f9c11f @@ -1030,6 +1366,123 @@ index 0000000000000000000000000000000000000000..b972ceebd3d5965d4926262b752c33a0 + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperLockCode.java b/src/main/java/io/papermc/paper/component/item/PaperLockCode.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2b544947f9fac0f4945f428b43071498b48b69c3 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperLockCode.java +@@ -0,0 +1,38 @@ ++package io.papermc.paper.component.item; ++ ++import org.bukkit.craftbukkit.util.Handleable; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperLockCode( ++ net.minecraft.world.LockCode impl ++) implements LockCode, Handleable<net.minecraft.world.LockCode> { ++ ++ @Override ++ public net.minecraft.world.LockCode getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public String lock() { ++ return this.impl.key(); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private String lock = ""; ++ ++ @Override ++ public @NonNull Builder lock(@NotNull final String code) { ++ this.lock = lock; ++ return this; ++ } ++ ++ @Override ++ public LockCode build() { ++ return new PaperLockCode(new net.minecraft.world.LockCode(this.lock)); ++ } ++ } ++} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperLodestoneTracker.java b/src/main/java/io/papermc/paper/component/item/PaperLodestoneTracker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..547561acf87d34244a44548432521c82f0af7684 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperLodestoneTracker.java +@@ -0,0 +1,67 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.base.Preconditions; ++import com.google.common.collect.Lists; ++import io.papermc.paper.util.Filtered; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.List; ++import java.util.Optional; ++import java.util.function.Function; ++import net.minecraft.core.GlobalPos; ++import net.minecraft.server.network.Filterable; ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.entity.memory.CraftMemoryMapper; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperLodestoneTracker( ++ net.minecraft.world.item.component.LodestoneTracker impl ++) implements LodestoneTracker, Handleable<net.minecraft.world.item.component.LodestoneTracker> { ++ ++ @Override ++ public net.minecraft.world.item.component.LodestoneTracker getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @Nullable Location location() { ++ return this.impl.target().map(CraftMemoryMapper::fromNms).orElse(null); ++ } ++ ++ @Override ++ public boolean tracked() { ++ return this.impl.tracked(); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private Optional<GlobalPos> pos = Optional.empty(); ++ private boolean tracked = true; ++ ++ @Override ++ public @NonNull Builder location(@Nullable final Location page) { ++ this.pos = Optional.ofNullable(page).map(CraftMemoryMapper::toNms); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder tracked(final boolean tracked) { ++ this.tracked = tracked; ++ return this; ++ } ++ ++ @Override ++ public @NonNull LodestoneTracker build() { ++ return new PaperLodestoneTracker( ++ new net.minecraft.world.item.component.LodestoneTracker(this.pos, this.tracked) ++ ); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/PaperMapDecorations.java b/src/main/java/io/papermc/paper/component/item/PaperMapDecorations.java new file mode 100644 index 0000000000000000000000000000000000000000..2d97d20e0b16558a61ef21d2595b920e528d9879 @@ -1157,7 +1610,7 @@ index 0000000000000000000000000000000000000000..805a86b4da99e82b3fa4254b62c0e265 +} diff --git a/src/main/java/io/papermc/paper/component/item/PaperMapItemColor.java b/src/main/java/io/papermc/paper/component/item/PaperMapItemColor.java new file mode 100644 -index 0000000000000000000000000000000000000000..307fdefe165380c31e51b81c431b88709efbc494 +index 0000000000000000000000000000000000000000..5f4833a78aff61e6ae1a1568cf58f4c5e66823d5 --- /dev/null +++ b/src/main/java/io/papermc/paper/component/item/PaperMapItemColor.java @@ -0,0 +1,38 @@ @@ -1185,7 +1638,7 @@ index 0000000000000000000000000000000000000000..307fdefe165380c31e51b81c431b8870 + + static final class BuilderImpl implements Builder { + -+ private Color color = Color.WHITE; ++ private Color color = Color.fromRGB(net.minecraft.world.item.component.MapItemColor.DEFAULT.rgb()); + + @Override + public Builder mapColor(final Color color) { @@ -1385,6 +1838,117 @@ index 0000000000000000000000000000000000000000..b98bd15e9d0d32102a6213b4107f85bf + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperResolvableProfile.java b/src/main/java/io/papermc/paper/component/item/PaperResolvableProfile.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b1e189c52b494670cf138ca67d1418620a00e3eb +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperResolvableProfile.java +@@ -0,0 +1,105 @@ ++package io.papermc.paper.component.item; ++ ++import com.destroystokyo.paper.profile.CraftPlayerProfile; ++import com.destroystokyo.paper.profile.PlayerProfile; ++import com.destroystokyo.paper.profile.ProfileProperty; ++import com.google.common.base.Preconditions; ++import com.google.common.collect.Collections2; ++import com.google.common.collect.Lists; ++import com.mojang.authlib.properties.Property; ++import com.mojang.authlib.properties.PropertyMap; ++import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.util.Filtered; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.List; ++import java.util.Optional; ++import java.util.UUID; ++import java.util.concurrent.CompletableFuture; ++import java.util.function.Function; ++import net.kyori.adventure.text.Component; ++import net.minecraft.server.network.Filterable; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperResolvableProfile( ++ net.minecraft.world.item.component.ResolvableProfile impl ++) implements ResolvableProfile, Handleable<net.minecraft.world.item.component.ResolvableProfile> { ++ ++ @Override ++ public net.minecraft.world.item.component.ResolvableProfile getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @Nullable UUID uuid() { ++ return this.impl.id().orElse(null); ++ } ++ ++ @Override ++ public @Nullable String name() { ++ return this.impl.name().orElse(null); ++ } ++ ++ @Override ++ public @Unmodifiable @NonNull Collection<ProfileProperty> properties() { ++ return Collections.unmodifiableCollection( ++ Collections2.transform( ++ this.impl.properties().values(), ++ input -> new ProfileProperty(input.name(), input.value(), input.signature()) ++ ) ++ ); ++ } ++ ++ @Override ++ public @NotNull CompletableFuture<PlayerProfile> resolve() { ++ return this.impl.resolve().thenApply(resolvableProfile -> CraftPlayerProfile.asBukkitCopy(resolvableProfile.gameProfile())); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private Optional<String> name = Optional.empty(); ++ private Optional<UUID> uuid = Optional.empty(); ++ private PropertyMap propertyMap = new PropertyMap(); ++ ++ @Override ++ public @NonNull Builder name(@Nullable final String name) { ++ this.name = Optional.ofNullable(name); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder uuid(@Nullable final UUID uuid) { ++ this.uuid = Optional.ofNullable(uuid); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addProperty(@NonNull final ProfileProperty property) { ++ this.propertyMap.put(property.getName(), new Property(property.getName(), property.getValue(), property.getSignature())); ++ return this; ++ } ++ ++ ++ @Override ++ public @NonNull Builder addAllProperties(@NonNull final List<ProfileProperty> properties) { ++ properties.forEach(this::addProperty); ++ return this; ++ } ++ ++ @Override ++ public ResolvableProfile build() { ++ return new PaperResolvableProfile(new net.minecraft.world.item.component.ResolvableProfile( ++ this.name, ++ this.uuid, ++ this.propertyMap ++ )); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/component/item/PaperSeededContainerLoot.java b/src/main/java/io/papermc/paper/component/item/PaperSeededContainerLoot.java new file mode 100644 index 0000000000000000000000000000000000000000..fc6169ea30df1d91363adcb48556afba30ac34a5 @@ -1564,6 +2128,241 @@ index 0000000000000000000000000000000000000000..8be3187a6c624d4ba74d2a58bc64b1b0 + } + } +} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperWritableBookContent.java b/src/main/java/io/papermc/paper/component/item/PaperWritableBookContent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6b4ccc782352290aa3647032e07955b8c96d4467 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperWritableBookContent.java +@@ -0,0 +1,79 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.base.Preconditions; ++import com.google.common.collect.Lists; ++import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.util.Filtered; ++import net.kyori.adventure.text.Component; ++import net.minecraft.server.network.Filterable; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Unmodifiable; ++import java.util.*; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperWritableBookContent( ++ net.minecraft.world.item.component.WritableBookContent impl ++) implements WritableBookContent, Handleable<net.minecraft.world.item.component.WritableBookContent> { ++ ++ @Override ++ public net.minecraft.world.item.component.WritableBookContent getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @NotNull @Unmodifiable List<Filtered<String>> pages() { ++ return Collections.unmodifiableList( ++ Lists.transform( ++ this.impl.pages(), ++ input -> Filtered.of(input.raw(), input.filtered().orElse(null)) ++ ) ++ ); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private final List<Filterable<String>> pages = new ArrayList<>(); ++ ++ @Override ++ public @NonNull Builder addPage(@NonNull final String page) { ++ Preconditions.checkArgument(page.length() <= net.minecraft.world.item.component.WritableBookContent.PAGE_EDIT_LENGTH, "String is too big!"); ++ Preconditions.checkArgument(this.pages.size() < net.minecraft.world.item.component.WritableBookContent.MAX_PAGES, "Too many pages!"); ++ this.pages.add(Filterable.passThrough(page)); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPages(@NonNull final Collection<String> pages) { ++ pages.forEach(this::addPage); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPageFiltered(@NonNull final Filtered<String> page) { ++ Preconditions.checkArgument(page.raw().length() <= net.minecraft.world.item.component.WritableBookContent.PAGE_EDIT_LENGTH, "Page is too big!"); ++ if (page.filtered() != null) { ++ Preconditions.checkArgument(page.filtered().length() <= net.minecraft.world.item.component.WritableBookContent.PAGE_EDIT_LENGTH, "Filtered page is too big!"); ++ } ++ Preconditions.checkArgument(this.pages.size() < net.minecraft.world.item.component.WritableBookContent.MAX_PAGES, "Too many pages!"); ++ ++ this.pages.add(new Filterable<>(page.raw(), Optional.ofNullable(page.filtered()))); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPagesFiltered(@NonNull final Collection<Filtered<String>> pages) { ++ pages.forEach(this::addPageFiltered); ++ return this; ++ } ++ ++ @Override ++ public @NonNull WritableBookContent build() { ++ return new PaperWritableBookContent( ++ new net.minecraft.world.item.component.WritableBookContent(this.pages) ++ ); ++ } ++ } ++} +diff --git a/src/main/java/io/papermc/paper/component/item/PaperWrittenBookContent.java b/src/main/java/io/papermc/paper/component/item/PaperWrittenBookContent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a87bb09c06c5d3558114f76c97fe347b4b4bf0d6 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/component/item/PaperWrittenBookContent.java +@@ -0,0 +1,144 @@ ++package io.papermc.paper.component.item; ++ ++import com.google.common.base.Function; ++import com.google.common.base.Preconditions; ++import com.google.common.collect.Lists; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.List; ++import java.util.Optional; ++import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.util.Filtered; ++import net.kyori.adventure.text.Component; ++import net.minecraft.server.network.Filterable; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.Handleable; ++import org.bukkit.inventory.ItemStack; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Unmodifiable; ++ ++@DefaultQualifier(NonNull.class) ++public record PaperWrittenBookContent( ++ net.minecraft.world.item.component.WrittenBookContent impl ++) implements WrittenBookContent, Handleable<net.minecraft.world.item.component.WrittenBookContent> { ++ ++ @Override ++ public net.minecraft.world.item.component.WrittenBookContent getHandle() { ++ return this.impl; ++ } ++ ++ @Override ++ public @NotNull Filtered<String> title() { ++ return Filtered.of(this.impl.title().raw(), this.impl.title().filtered().orElse(null)); ++ } ++ ++ @Override ++ public @NotNull String author() { ++ return this.impl.author(); ++ } ++ ++ @Override ++ public int generation() { ++ return this.impl.generation(); ++ } ++ ++ @Override ++ public @NotNull @Unmodifiable List<Filtered<Component>> pages() { ++ return Collections.unmodifiableList( ++ Lists.transform( ++ this.impl.pages(), ++ input -> Filtered.of(PaperAdventure.asAdventure(input.raw()), input.filtered().map(PaperAdventure::asAdventure).orElse(null)) ++ ) ++ ); ++ } ++ ++ @Override ++ public boolean resolved() { ++ return this.impl.resolved(); ++ } ++ ++ static final class BuilderImpl implements Builder { ++ ++ private static final net.minecraft.world.item.component.WrittenBookContent EMPTY = net.minecraft.world.item.component.WrittenBookContent.EMPTY; ++ ++ private final List<Filterable<net.minecraft.network.chat.Component>> pages = new ArrayList<>(); ++ private Filterable<String> title = EMPTY.title(); ++ private String author = EMPTY.author(); ++ private int generation = EMPTY.generation(); ++ private boolean resolved = EMPTY.resolved(); ++ ++ @Override ++ public @NonNull Builder title(@NonNull final String title) { ++ Preconditions.checkArgument(title.length() <= net.minecraft.world.item.component.WrittenBookContent.TITLE_MAX_LENGTH, "Title is too big!"); ++ this.title = Filterable.passThrough(title); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder titleFiltered(@NonNull final Filtered<String> title) { ++ Preconditions.checkArgument(title.raw().length() <= net.minecraft.world.item.component.WrittenBookContent.TITLE_MAX_LENGTH, "Title is too big!"); ++ if (title.filtered() != null) { ++ Preconditions.checkArgument(title.filtered().length() <= net.minecraft.world.item.component.WrittenBookContent.TITLE_MAX_LENGTH, "Filtered title is too big!"); ++ } ++ this.title = new Filterable<>(title.raw(), Optional.ofNullable(title.filtered())); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder author(@NonNull final String author) { ++ this.author = author; ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder generation(final int generation) { ++ Preconditions.checkArgument(generation <= net.minecraft.world.item.component.WrittenBookContent.MAX_GENERATION, "Generation is too big!"); ++ this.generation = generation; ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder resolved(final boolean resolved) { ++ this.resolved = resolved; ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPage(@NonNull final Component page) { ++ this.pages.add(Filterable.passThrough(PaperAdventure.asVanilla(page))); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPages(@NonNull final Collection<Component> pages) { ++ pages.forEach(this::addPage); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPageFiltered(@NonNull final Filtered<Component> page) { ++ this.pages.add(new Filterable<>(PaperAdventure.asVanilla(page.raw()), Optional.ofNullable(page.filtered()).map(PaperAdventure::asVanilla))); ++ return this; ++ } ++ ++ @Override ++ public @NonNull Builder addPagesFiltered(@NonNull final Collection<Filtered<Component>> pages) { ++ pages.forEach(this::addPageFiltered); ++ return this; ++ } ++ ++ @Override ++ public WrittenBookContent build() { ++ return new PaperWrittenBookContent(new net.minecraft.world.item.component.WrittenBookContent( ++ this.title, ++ this.author, ++ this.generation, ++ this.pages, ++ this.resolved ++ )); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java index 51979b3c3f1f3a3c63e0559c70bed9193fd35dbb..df2af45f32af3a1ddef25c5e7cca3973481806e2 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -1753,6 +2552,28 @@ index b54be1122af2b303c0f063ff6b61bf8e2478b0df..a66775b21e829f76de9cf234b702f5f0 + } + // Paper end - data component API } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java +index 77489c3ffaa3a72d4cf105499a77150fca6d8526..e91c8a7c7c62909a3adc29e13c7b6ff83e13cbf8 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java +@@ -79,7 +79,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { + }); + } + +- static FireworkEffect getEffect(FireworkExplosion explosion) { ++ public static FireworkEffect getEffect(FireworkExplosion explosion) { // Paper + FireworkEffect.Builder effect = FireworkEffect.builder() + .flicker(explosion.hasTwinkle()) + .trail(explosion.hasTrail()) +@@ -99,7 +99,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { + return effect.build(); + } + +- static FireworkExplosion getExplosion(FireworkEffect effect) { ++ public static FireworkExplosion getExplosion(FireworkEffect effect) { // Paper + IntList colors = CraftMetaFirework.addColors(effect.getColors()); + IntList fadeColors = CraftMetaFirework.addColors(effect.getFadeColors()); + diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index d5789326d70bb8b029c5448270bbaa6faf52e6e1..02cdd38a55741a56ed9de428d9145e6103b71f65 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java |