From 3b1646ef90912954080ebedde45c08ec88b1b5fa Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 14:42:24 +0200 Subject: [PATCH 01/15] feat: begin rework of SerializableItemStack to use DataComponents --- gradle/libs.versions.toml | 1 + ...neinabyss.conventions.cartridge.gradle.kts | 22 ++ idofront-serializers/build.gradle.kts | 2 +- .../serialization/AttributeSerializer.kt | 10 +- .../serialization/FoodComponentSerializer.kt | 56 ----- .../serialization/FoodEffectWrapper.kt | 7 - .../serialization/SerializableDataTypes.kt | 218 ++++++++++++++++++ .../serialization/SerializableEnchantment.kt | 1 + .../serialization/SerializableItemStack.kt | 144 ++++++------ 9 files changed, 327 insertions(+), 134 deletions(-) create mode 100644 idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts delete mode 100644 idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodComponentSerializer.kt delete mode 100644 idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodEffectWrapper.kt create mode 100644 idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 02067f4..a147a1c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -78,6 +78,7 @@ minecraft-mccoroutine = { module = "com.github.shynixn.mccoroutine:mccoroutine-b minecraft-mccoroutine-core = { module = "com.github.shynixn.mccoroutine:mccoroutine-bukkit-core", version.ref = "mccoroutine" } minecraft-mockbukkit = { module = "com.github.seeseemelk:MockBukkit-v1.21", version.ref = "mockbukkit" } minecraft-papermc = { module = "io.papermc.paper:paper-api", version.ref = "minecraft" } +minecraft-cartridge = { module = "com.mineinabyss.cartridge:cartridge-api", version.ref = "minecraft" } minecraft-plugin-fawe-bukkit = { module = "com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit", version.ref = "fawe" } minecraft-plugin-fawe-core = { module = "com.fastasyncworldedit:FastAsyncWorldEdit-Core", version.ref = "fawe" } minecraft-plugin-itemsadder = { module = "com.github.LoneDev6:api-itemsadder", version.ref = "itemsadder" } diff --git a/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts new file mode 100644 index 0000000..4805414 --- /dev/null +++ b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts @@ -0,0 +1,22 @@ +plugins { + java +} + +val libs = idofrontLibsRef + +repositories { + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") + mavenLocal() +} + +dependencies { + compileOnly(libs.findLibrary("minecraft-cartridge").get()) +} + +tasks { + processResources { + filesMatching(setOf("plugin.yml", "paper-plugin.yml")) { + expand(mutableMapOf("plugin_version" to version)) + } + } +} diff --git a/idofront-serializers/build.gradle.kts b/idofront-serializers/build.gradle.kts index d4bb818..1779659 100644 --- a/idofront-serializers/build.gradle.kts +++ b/idofront-serializers/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") - id("com.mineinabyss.conventions.papermc") + id("com.mineinabyss.conventions.cartridge") id("com.mineinabyss.conventions.publication") id("com.mineinabyss.conventions.testing") alias(libs.plugins.kotlinx.serialization) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt index 00e4179..24656f1 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt @@ -1,5 +1,6 @@ package com.mineinabyss.idofront.serialization +import io.papermc.paper.component.item.ItemAttributeModifiers import kotlinx.serialization.EncodeDefault import kotlinx.serialization.EncodeDefault.Mode.NEVER import kotlinx.serialization.KSerializer @@ -17,13 +18,20 @@ import java.util.* @Serializable @SerialName("SerializableAttribute") -class SerializableAttribute ( +class SerializableAttribute( val attribute: Attribute, val modifier: @Serializable(with = AttributeModifierSerializer::class) AttributeModifier, ) { + + constructor(itemAttributeModifier: ItemAttributeModifiers.Entry) : this( + itemAttributeModifier.attribute(), + itemAttributeModifier.modifier() + ) + operator fun component1(): Attribute { return attribute } + operator fun component2(): AttributeModifier { return modifier } diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodComponentSerializer.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodComponentSerializer.kt deleted file mode 100644 index a362966..0000000 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodComponentSerializer.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.mineinabyss.idofront.serialization - -import com.mineinabyss.idofront.time.inWholeTicks -import com.mineinabyss.idofront.time.ticks -import kotlinx.serialization.KSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import org.bukkit.Material -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.components.FoodComponent -import org.bukkit.inventory.meta.components.FoodComponent.FoodEffect -import org.bukkit.potion.PotionEffect -import org.bukkit.potion.PotionEffectType -import kotlin.time.Duration -import kotlin.time.Duration.Companion.seconds -import kotlin.time.DurationUnit - -@Serializable -@SerialName("FoodComponent") -class FoodComponentSurrogate( - val nutrition: Int, - val saturation: Float, - val eatSeconds: Float = 1.6f, - val canAlwaysEat: Boolean = false, - val usingConvertsTo: SerializableItemStack? = null, - val effects: List = emptyList() -) { - - constructor(food: FoodComponent) : this( - food.nutrition, - food.saturation, - food.eatSeconds, - food.canAlwaysEat(), - food.usingConvertsTo?.toSerializable(), - food.effects.map { FoodEffectWrapper(it.effect, it.probability) }) - - init { - require(nutrition >= 0) { "FoodComponent must have a positive nutrition" } - require(saturation >= 0) { "FoodComponent must have a positive saturation" } - require(eatSeconds >= 0) { "FoodComponent must have a positive eatSeconds" } - require(effects.all { it.probability in 0.0..1.0 }) { "FoodEffect-probability must be between 0.0..1.0" } - } - - val foodComponent: FoodComponent - get() = ItemStack.of(Material.PAPER).itemMeta.food.also { - it.nutrition = nutrition - it.saturation = saturation - it.eatSeconds = eatSeconds - it.setCanAlwaysEat(canAlwaysEat) - it.usingConvertsTo = usingConvertsTo?.toItemStackOrNull() - effects.forEach { e -> it.addEffect(e.effect, e.probability) } - } -} diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodEffectWrapper.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodEffectWrapper.kt deleted file mode 100644 index beae932..0000000 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/FoodEffectWrapper.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mineinabyss.idofront.serialization - -import kotlinx.serialization.Serializable -import org.bukkit.potion.PotionEffect - -@Serializable -class FoodEffectWrapper(val effect: @Serializable(PotionEffectSerializer::class) PotionEffect, val probability: Float = 1.0f) \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt new file mode 100644 index 0000000..0779799 --- /dev/null +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -0,0 +1,218 @@ +package com.mineinabyss.idofront.serialization + +import io.papermc.paper.component.DataComponentType +import io.papermc.paper.component.DataComponentTypes +import io.papermc.paper.component.item.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import org.bukkit.Color +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.ItemMeta +import org.bukkit.potion.PotionEffect + +object SerializableDataTypes { + + fun setData(itemStack: ItemStack, dataComponent: DataComponentType.Valued, any: T?) { + any?.let { itemStack.setData(dataComponent, any) } + } + + interface DataType { + fun setDataType(itemStack: ItemStack) + } + + @Serializable + data class Unbreakable(val shownInTooltip: Boolean = true) : DataType { + constructor(unbreakable: io.papermc.paper.component.item.Unbreakable) : this(unbreakable.showInTooltip()) + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.UNBREAKABLE, + io.papermc.paper.component.item.Unbreakable.unbreakable(shownInTooltip) + ) + } + } + + @Serializable + data class PotionContents( + val potionType: @Serializable(PotionTypeSerializer::class) org.bukkit.potion.PotionType?, + val color: @Serializable(ColorSerializer::class) Color?, + val customEffects: List<@Serializable(PotionEffectSerializer::class) PotionEffect> = emptyList() + ) : DataType { + + constructor(potionContents: io.papermc.paper.component.item.PotionContents) : this( + potionContents.potion(), + potionContents.customColor(), + potionContents.customEffects() + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.POTION_CONTENTS, + io.papermc.paper.component.item.PotionContents.potionContents().potion(potionType).customColor(color) + .addAll(customEffects).build() + ) + } + } + + @Serializable + data class Enchantments( + val enchantments: List, + val showInToolTip: Boolean = true + ) : DataType { + constructor(itemEnchantments: ItemEnchantments) : this(itemEnchantments.enchantments().map(::SerializableEnchantment), itemEnchantments.showInTooltip()) + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.ENCHANTMENTS, + ItemEnchantments.itemEnchantments(enchantments.associate { it.enchant to it.level }, showInToolTip) + ) + } + } + + @Serializable + data class FoodProperties( + val nutrition: Int, + val saturation: Float, + val eatSeconds: Float = 1.6f, + val canAlwaysEat: Boolean = false, + val effects: List = emptyList(), + val usingConvertsTo: SerializableItemStack? = null + ) : DataType { + + constructor(foodProperties: io.papermc.paper.component.item.FoodProperties) : this( + foodProperties.nutrition(), + foodProperties.saturation(), + foodProperties.eatSeconds(), + foodProperties.canAlwaysEat(), + foodProperties.effects().map(::PossibleEffect), + foodProperties.usingConvertsTo()?.toSerializable() + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.FOOD, io.papermc.paper.component.item.FoodProperties.food() + .nutrition(nutrition).saturation(saturation).eatSeconds(eatSeconds).canAlwaysEat(canAlwaysEat) + .addAllEffects(effects.map { it.paperPossibleEffect }) + .usingConvertsTo(usingConvertsTo?.toItemStackOrNull()) + ) + } + + @Serializable + data class PossibleEffect( + val effect: @Serializable(PotionEffectSerializer::class) PotionEffect, + val probability: Float = 1.0f + ) { + + val paperPossibleEffect: io.papermc.paper.component.item.FoodProperties.PossibleEffect = + io.papermc.paper.component.item.FoodProperties.PossibleEffect.of(effect, probability) + + constructor(possibleEffect: io.papermc.paper.component.item.FoodProperties.PossibleEffect) : this( + possibleEffect.effect(), + possibleEffect.probability() + ) + } + } + + @Serializable + @JvmInline + value class CustomModelData(private val customModelData: Int) : DataType { + constructor(customModelData: io.papermc.paper.component.item.CustomModelData) : this(customModelData.data()) + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CUSTOM_MODEL_DATA, + io.papermc.paper.component.item.CustomModelData.customModelData().customModelData(customModelData) + .build() + ) + } + } + + @Serializable + data class DyedColor( + val color: @Serializable(ColorSerializer::class) Color, + val showInToolTip: Boolean + ) : DataType { + constructor(dyedItemColor: DyedItemColor) : this(dyedItemColor.color(), dyedItemColor.showInTooltip()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.DYED_COLOR, DyedItemColor.dyedItemColor(color, showInToolTip)) + } + } + + @Serializable + data class AttributeModifiers( + val attributes: List, + val showInToolTip: Boolean = true + ) : DataType { + + constructor(attributeModifiers: ItemAttributeModifiers) : this(attributeModifiers.modifiers().map(::SerializableAttribute), attributeModifiers.showInTooltip()) + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.itemAttributes().apply { + attributes.forEach { addModifier(it.attribute, it.modifier) } + }.showInTooltip(showInToolTip).build()) + } + } + + @Serializable(with = FireResistantSerializer::class) + object FireResistant : UnvaluedDataType() { + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.FIRE_RESISTANT) + } + } + + @Serializable(with = HideToolTipSerializer::class) + object HideToolTip : UnvaluedDataType() { + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.HIDE_TOOLTIP) + } + } + + @Serializable(with = HideAdditionalTooltipSerializer::class) + object HideAdditionalTooltip : UnvaluedDataType() { + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) + } + } + + @Serializable(with = CreativeSlotLockSerializer::class) + object CreativeSlotLock : UnvaluedDataType() { + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.CREATIVE_SLOT_LOCK) + } + } + + @Serializable(with = IntangibleProjectileSerializer::class) + object IntangibleProjectile : UnvaluedDataType() { + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.INTANGIBLE_PROJECTILE) + } + } + + object FireResistantSerializer : KSerializer by UnvaluedDataTypeSerializer("fireResistant") + object HideToolTipSerializer : KSerializer by UnvaluedDataTypeSerializer("hideTooltip") + object HideAdditionalTooltipSerializer : + KSerializer by UnvaluedDataTypeSerializer("hideAdditionalTooltip") + + object CreativeSlotLockSerializer : KSerializer by UnvaluedDataTypeSerializer("creativeSlotLock") + object IntangibleProjectileSerializer : + KSerializer by UnvaluedDataTypeSerializer("intangibleProjectile") + + abstract class UnvaluedDataType : DataType + + class UnvaluedDataTypeSerializer(private val serialName: String) : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.BOOLEAN) + + override fun serialize(encoder: Encoder, value: T) { + encoder.encodeBoolean(true) + } + + override fun deserialize(decoder: Decoder): T { + decoder.decodeBoolean() // just to match the encoding process + throw UnsupportedOperationException("Deserialization of $serialName is not supported") + } + } + + +} \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableEnchantment.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableEnchantment.kt index 8b45b38..4cc5d41 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableEnchantment.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableEnchantment.kt @@ -17,6 +17,7 @@ data class SerializableEnchantment( val enchant: @Serializable(with = EnchantmentSerializer::class) Enchantment, val level: Int = 1, ) { + constructor(itemEnchantment: Map.Entry) : this(itemEnchantment.key, itemEnchantment.value) init { require(level > 0) { "Level must be atleast 1" } } diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 41ca897..1cccf0f 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -3,7 +3,6 @@ package com.mineinabyss.idofront.serialization import com.mineinabyss.idofront.di.DI -import com.mineinabyss.idofront.items.asColorable import com.mineinabyss.idofront.messaging.idofrontLogger import com.mineinabyss.idofront.nms.hideAttributeTooltipWithItemFlagSet import com.mineinabyss.idofront.plugin.Plugins @@ -12,6 +11,8 @@ import com.mineinabyss.idofront.textcomponents.miniMsg import com.mineinabyss.idofront.textcomponents.serialize import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible +import io.papermc.paper.component.DataComponentTypes +import io.papermc.paper.component.item.ItemLore import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems import kotlinx.serialization.* @@ -45,23 +46,21 @@ typealias SerializableItemStack = @Serializable(with = SerializableItemStackSeri data class BaseSerializableItemStack( @EncodeDefault(NEVER) val type: @Serializable(with = MaterialByNameSerializer::class) Material? = null, @EncodeDefault(NEVER) val amount: Int? = null, - @EncodeDefault(NEVER) val customModelData: Int? = null, + @EncodeDefault(NEVER) val customModelData: SerializableDataTypes.CustomModelData? = null, @EncodeDefault(NEVER) @SerialName("itemName") private val _itemName: String? = null, // This is private as we only want to use itemName in configs @EncodeDefault(NEVER) @SerialName("customName") private val _customName: String? = null, @EncodeDefault(NEVER) @SerialName("lore") private val _lore: List? = null, - @EncodeDefault(NEVER) val unbreakable: Boolean? = null, + @EncodeDefault(NEVER) val unbreakable: SerializableDataTypes.Unbreakable? = null, @EncodeDefault(NEVER) val damage: Int? = null, - @EncodeDefault(NEVER) val durability: Int? = null, - @EncodeDefault(NEVER) val prefab: String? = null, - @EncodeDefault(NEVER) val enchantments: List? = null, + @EncodeDefault(NEVER) val maxDamage: Int? = null, @EncodeDefault(NEVER) val itemFlags: List? = null, - @EncodeDefault(NEVER) val attributeModifiers: List? = null, - @EncodeDefault(NEVER) val basePotionType: @Serializable(with = PotionTypeSerializer::class) PotionType? = null, - @EncodeDefault(NEVER) val customPotionEffects: List<@Serializable(with = PotionEffectSerializer::class) PotionEffect> = listOf(), + @EncodeDefault(NEVER) val enchantments: SerializableDataTypes.Enchantments? = null, + @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, + @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, @EncodeDefault(NEVER) val knowledgeBookRecipes: List? = null, - @EncodeDefault(NEVER) val color: @Serializable(with = ColorSerializer::class) Color? = null, - @EncodeDefault(NEVER) val food: FoodComponentSurrogate? = null, + @EncodeDefault(NEVER) val color: SerializableDataTypes.DyedColor? = null, + @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, @EncodeDefault(NEVER) val tool: @Serializable(with = ToolComponentSerializer::class) ToolComponent? = null, @EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null, @EncodeDefault(NEVER) val hideTooltip: Boolean? = null, @@ -70,15 +69,24 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val maxStackSize: Int? = null, @EncodeDefault(NEVER) val rarity: ItemRarity? = null, - // Custom recipes + @EncodeDefault(NEVER) val prefab: String? = null, @EncodeDefault(NEVER) val tag: String? = null, @EncodeDefault(NEVER) val recipeOptions: List = listOf(), + // Unvalued DataTypes + @EncodeDefault(NEVER) val fireResistant: SerializableDataTypes.FireResistant? = null, + @EncodeDefault(NEVER) val hideTooltip: SerializableDataTypes.HideToolTip? = null, + @EncodeDefault(NEVER) val hideAdditionalTooltip: SerializableDataTypes.HideAdditionalTooltip? = null, + @EncodeDefault(NEVER) val creativeSlotLock: SerializableDataTypes.CreativeSlotLock? = null, + @EncodeDefault(NEVER) val intangibleProjectile: SerializableDataTypes.IntangibleProjectile? = null, + // Third-party plugins @EncodeDefault(NEVER) val crucibleItem: String? = null, @EncodeDefault(NEVER) val oraxenItem: String? = null, @EncodeDefault(NEVER) val itemsadderItem: String? = null, ) { + private fun Component.removeItalics() = + Component.text().decoration(TextDecoration.ITALIC, false).build().append(this) @Transient val itemName = _itemName?.miniMsg() @@ -91,7 +99,9 @@ data class BaseSerializableItemStack( * Converts this serialized item's data to an [ItemStack], optionally applying the changes to an * [existing item][applyTo]. */ - fun toItemStack(applyTo: ItemStack = ItemStack(type ?: Material.AIR)): ItemStack { + fun toItemStack( + applyTo: ItemStack = ItemStack(type ?: Material.AIR), + ): ItemStack { // Import ItemStack from Crucible crucibleItem?.let { id -> if (Plugins.isEnabled()) { @@ -129,53 +139,45 @@ data class BaseSerializableItemStack( } // Support for our prefab system in geary. - prefab?.let { encodePrefab.invoke(applyTo, it) } + prefab?.let { encodePrefab.invoke(applyTo, it) } ?: applyTo // Modify item - amount?.let(applyTo::setAmount) - type?.let(applyTo::setType) + amount?.let { applyTo.amount = it } + type?.let { applyTo.type = type } // Modify meta - applyTo.editMeta { meta -> - itemName?.let(meta::itemName) - customName?.let(meta::displayName) - customModelData?.let(meta::setCustomModelData) - lore?.let { - meta.lore(it.map { line -> - line.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE) - }) - } + val meta = applyTo.itemMeta ?: return applyTo + if (itemFlags?.isNotEmpty() == true) meta.addItemFlags(*itemFlags.toTypedArray()) + if (knowledgeBookRecipes != null) (meta as? KnowledgeBookMeta)?.recipes = knowledgeBookRecipes.map { it.getSubRecipeIDs() }.flatten() + applyTo.itemMeta = meta - unbreakable?.let(meta::setUnbreakable) - damage?.let { (meta as? Damageable)?.damage = damage } - durability?.let { (meta as? Damageable)?.setMaxDamage(it) } - itemFlags?.let { meta.addItemFlags(*itemFlags.toTypedArray()) } - color?.let { meta.asColorable()?.color = color } - basePotionType?.let { (meta as? PotionMeta)?.basePotionType = basePotionType } - customPotionEffects.forEach { (meta as? PotionMeta)?.addCustomEffect(it, true) } - enchantments?.forEach { meta.addEnchant(it.enchant, it.level, true) } - attributeModifiers?.forEach { meta.addAttributeModifier(it.attribute, it.modifier) } - - knowledgeBookRecipes?.let { - (meta as? KnowledgeBookMeta)?.recipes = knowledgeBookRecipes.map { it.getSubRecipeIDs() }.flatten() - } + SerializableDataTypes.setData(applyTo, DataComponentTypes.ITEM_NAME, itemName) + SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_NAME, customName) + SerializableDataTypes.setData(applyTo, DataComponentTypes.LORE, lore?.let { ItemLore.lore(lore) }) + customModelData?.setDataType(applyTo) - enchantmentGlintOverride?.let(meta::setEnchantmentGlintOverride) - food?.foodComponent?.let(meta::setFood) - tool?.let(meta::setTool) - jukeboxPlayable?.let(meta::setJukeboxPlayable) - maxStackSize?.let(meta::setMaxStackSize) - rarity?.let(meta::setRarity) - isFireResistant?.let(meta::setFireResistant) - hideTooltip?.let(meta::setHideTooltip) - } + enchantments?.setDataType(applyTo) + potionType?.setDataType(applyTo) + attributeModifiers?.setDataType(applyTo) - applyTo.hideAttributeTooltipWithItemFlagSet() - return applyTo + SerializableDataTypes.setData(applyTo, DataComponentTypes.DAMAGE, damage) + SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) + SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) + SerializableDataTypes.setData(applyTo, DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride) + unbreakable?.setDataType(applyTo) + food?.setDataType(applyTo) + + fireResistant?.setDataType(applyTo) + hideTooltip?.setDataType(applyTo) + hideAdditionalTooltip?.setDataType(applyTo) + creativeSlotLock?.setDataType(applyTo) + intangibleProjectile?.setDataType(applyTo) + + return applyTo.hideAttributeTooltipWithItemFlagSet() } fun toItemStackOrNull(applyTo: ItemStack = ItemStack(type ?: Material.AIR)) = - toItemStack(applyTo).takeIf { it.type != Material.AIR } + toItemStack().takeUnless { it.isEmpty } /** @return whether applying this [SerializableItemStack] to [item] would keep [item] identical. */ fun matches(item: ItemStack): Boolean { @@ -199,28 +201,32 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { SerializableItemStack( type = type, amount = amount.takeIf { it != 1 }, - customModelData = if (hasCustomModelData()) customModelData else null, - _itemName = if (hasItemName()) itemName().serialize() else null, - _customName = if (hasDisplayName()) displayName()!!.serialize() else null, - unbreakable = isUnbreakable.takeIf { it }, - _lore = if (this.hasLore()) this.lore()?.map { it.serialize() } else null, - damage = (this as? Damageable)?.takeIf { it.hasDamage() }?.damage, - durability = (this as? Damageable)?.takeIf { it.hasMaxDamage() }?.maxDamage, - enchantments = enchants.takeIf { it.isNotEmpty() }?.map { SerializableEnchantment(it.key, it.value) }, + itemName = getData(DataComponentTypes.ITEM_NAME), + customName = getData(DataComponentTypes.CUSTOM_NAME), + customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA)?.let(SerializableDataTypes::CustomModelData), + unbreakable = getData(DataComponentTypes.UNBREAKABLE)?.let(SerializableDataTypes::Unbreakable), + lore = getData(DataComponentTypes.LORE)?.lines(), + damage = getData(DataComponentTypes.DAMAGE), + maxDamage = getData(DataComponentTypes.MAX_DAMAGE), + maxStackSize = getData(DataComponentTypes.MAX_STACK_SIZE), + rarity = getData(DataComponentTypes.RARITY), + enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), + + enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), + attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), + potionType = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), + color = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), + food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), + + fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, + hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, + hideAdditionalTooltip = SerializableDataTypes.HideAdditionalTooltip.takeIf { hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) }, + creativeSlotLock = SerializableDataTypes.CreativeSlotLock.takeIf { hasData(DataComponentTypes.CREATIVE_SLOT_LOCK) }, + intangibleProjectile = SerializableDataTypes.IntangibleProjectile.takeIf { hasData(DataComponentTypes.INTANGIBLE_PROJECTILE) }, + knowledgeBookRecipes = ((this as? KnowledgeBookMeta)?.recipes?.map { it.getItemPrefabFromRecipe() }?.flatten() ?: emptyList()).takeIf { it.isNotEmpty() }, itemFlags = (this?.itemFlags?.toList() ?: listOf()).takeIf { it.isNotEmpty() }, - attributeModifiers = attributeList.takeIf { it.isNotEmpty() }, - basePotionType = (this as? PotionMeta)?.basePotionType, - color = (this as? PotionMeta)?.color ?: (this as? LeatherArmorMeta)?.color, - food = if (hasFood()) FoodComponentSurrogate(food) else null, - tool = if (hasTool()) tool else null, - jukeboxPlayable = if (hasJukeboxPlayable()) jukeboxPlayable else null, - enchantmentGlintOverride = if (hasEnchantmentGlintOverride()) enchantmentGlintOverride else null, - maxStackSize = if (hasMaxStackSize()) maxStackSize else null, - rarity = if (hasRarity()) rarity else null, - hideTooltip = isHideTooltip.takeIf { it }, - isFireResistant = isFireResistant.takeIf { it }, ) //TODO perhaps this should encode prefab too? } From fb047b5a6a4263cfb9dcb68fa9a6d5cc4d792a5c Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 15:29:39 +0200 Subject: [PATCH 02/15] feat: add TOOL component --- .../serialization/SerializableDataTypes.kt | 42 ++++++++++++++++++- .../serialization/SerializableItemStack.kt | 9 ++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 0779799..85c38e4 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -2,7 +2,12 @@ package com.mineinabyss.idofront.serialization import io.papermc.paper.component.DataComponentType import io.papermc.paper.component.DataComponentTypes -import io.papermc.paper.component.item.* +import io.papermc.paper.component.item.DyedItemColor +import io.papermc.paper.component.item.ItemAttributeModifiers +import io.papermc.paper.component.item.ItemEnchantments +import io.papermc.paper.component.item.Tool.Rule +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.set.RegistrySet import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.PrimitiveKind @@ -10,9 +15,11 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import net.kyori.adventure.key.Key +import net.kyori.adventure.util.TriState import org.bukkit.Color +import org.bukkit.Registry import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.ItemMeta import org.bukkit.potion.PotionEffect object SerializableDataTypes { @@ -72,6 +79,37 @@ object SerializableDataTypes { } } + @Serializable + data class Tool( + val rules: List, + val defaultMiningSpeed: Float, + val damagePerBlock: Int + ) : DataType { + constructor(tool: io.papermc.paper.component.item.Tool) : this(tool.rules().map(::Rule), tool.defaultMiningSpeed(), tool.damagePerBlock()) + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.TOOL, io.papermc.paper.component.item.Tool.tool() + .damagePerBlock(damagePerBlock) + .defaultMiningSpeed(defaultMiningSpeed) + .addRules(rules.map(Rule::paperRule)) + .build() + ) + } + + @Serializable + data class Rule( + val blockTypes: List<@Serializable(KeySerializer::class) Key>, + val speed: Float? = null, + val correctForDrops: TriState + ) { + constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this(rule.blockTypes().map { it.key() }, rule.speed(), rule.correctForDrops()) + val paperRule: io.papermc.paper.component.item.Tool.Rule by lazy { + val blockTypes = blockTypes.mapNotNull { Registry.BLOCK.get(it) } + val keySet = RegistrySet.keySetFromValues(RegistryKey.BLOCK, blockTypes) + return@lazy io.papermc.paper.component.item.Tool.Rule.of(keySet, speed, correctForDrops) + } + } + } + @Serializable data class FoodProperties( val nutrition: Int, diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 1cccf0f..0947b7e 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -22,7 +22,6 @@ import org.bukkit.* import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemRarity import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.Damageable import org.bukkit.inventory.meta.KnowledgeBookMeta import org.bukkit.inventory.meta.LeatherArmorMeta import org.bukkit.inventory.meta.PotionMeta @@ -59,9 +58,9 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, @EncodeDefault(NEVER) val knowledgeBookRecipes: List? = null, - @EncodeDefault(NEVER) val color: SerializableDataTypes.DyedColor? = null, + @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, - @EncodeDefault(NEVER) val tool: @Serializable(with = ToolComponentSerializer::class) ToolComponent? = null, + @EncodeDefault(NEVER) val tool: SerializableDataTypes.Tool? = null, @EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null, @EncodeDefault(NEVER) val hideTooltip: Boolean? = null, @EncodeDefault(NEVER) val isFireResistant: Boolean? = null, @@ -166,6 +165,7 @@ data class BaseSerializableItemStack( SerializableDataTypes.setData(applyTo, DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride) unbreakable?.setDataType(applyTo) food?.setDataType(applyTo) + tool?.setDataType(applyTo) fireResistant?.setDataType(applyTo) hideTooltip?.setDataType(applyTo) @@ -215,8 +215,9 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), potionType = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), - color = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), + dyedColor = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), + tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, From ca0da065c2b1e931e9bebf4949ff63e4a94e39d7 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 16:34:22 +0200 Subject: [PATCH 03/15] refactor: change logic for nonvalue components --- .../serialization/SerializableDataTypes.kt | 84 ++++++++----------- .../serialization/SerializableItemStack.kt | 21 ++--- 2 files changed, 46 insertions(+), 59 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 85c38e4..3deaf9f 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -193,64 +193,50 @@ object SerializableDataTypes { } } - @Serializable(with = FireResistantSerializer::class) - object FireResistant : UnvaluedDataType() { - override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.FIRE_RESISTANT) - } - } - - @Serializable(with = HideToolTipSerializer::class) - object HideToolTip : UnvaluedDataType() { - override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.HIDE_TOOLTIP) + @Serializable @JvmInline + value class FireResistant(private val state: Boolean) { + fun setDataType(itemStack: ItemStack) { + when (state) { + true -> itemStack.setData(DataComponentTypes.FIRE_RESISTANT) + false -> itemStack.resetData(DataComponentTypes.FIRE_RESISTANT) + } } } - - @Serializable(with = HideAdditionalTooltipSerializer::class) - object HideAdditionalTooltip : UnvaluedDataType() { - override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) + @Serializable @JvmInline + value class HideToolTip(private val state: Boolean) { + fun setDataType(itemStack: ItemStack) { + when (state) { + true -> itemStack.setData(DataComponentTypes.HIDE_TOOLTIP) + false -> itemStack.resetData(DataComponentTypes.HIDE_TOOLTIP) + } } } - - @Serializable(with = CreativeSlotLockSerializer::class) - object CreativeSlotLock : UnvaluedDataType() { - override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.CREATIVE_SLOT_LOCK) + @Serializable @JvmInline + value class HideAdditionalTooltip(private val state: Boolean) { + fun setDataType(itemStack: ItemStack) { + when (state) { + true -> itemStack.setData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) + false -> itemStack.resetData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) + } } } - - @Serializable(with = IntangibleProjectileSerializer::class) - object IntangibleProjectile : UnvaluedDataType() { - override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.INTANGIBLE_PROJECTILE) + @Serializable @JvmInline + value class CreativeSlotLock(private val state: Boolean) { + fun setDataType(itemStack: ItemStack) { + when (state) { + true -> itemStack.setData(DataComponentTypes.CREATIVE_SLOT_LOCK) + false -> itemStack.resetData(DataComponentTypes.CREATIVE_SLOT_LOCK) + } } } - - object FireResistantSerializer : KSerializer by UnvaluedDataTypeSerializer("fireResistant") - object HideToolTipSerializer : KSerializer by UnvaluedDataTypeSerializer("hideTooltip") - object HideAdditionalTooltipSerializer : - KSerializer by UnvaluedDataTypeSerializer("hideAdditionalTooltip") - - object CreativeSlotLockSerializer : KSerializer by UnvaluedDataTypeSerializer("creativeSlotLock") - object IntangibleProjectileSerializer : - KSerializer by UnvaluedDataTypeSerializer("intangibleProjectile") - - abstract class UnvaluedDataType : DataType - - class UnvaluedDataTypeSerializer(private val serialName: String) : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.BOOLEAN) - - override fun serialize(encoder: Encoder, value: T) { - encoder.encodeBoolean(true) - } - - override fun deserialize(decoder: Decoder): T { - decoder.decodeBoolean() // just to match the encoding process - throw UnsupportedOperationException("Deserialization of $serialName is not supported") + @Serializable @JvmInline + value class IntangibleProjectile(private val state: Boolean) { + fun setDataType(itemStack: ItemStack) { + when (state) { + true -> itemStack.setData(DataComponentTypes.INTANGIBLE_PROJECTILE) + false -> itemStack.resetData(DataComponentTypes.INTANGIBLE_PROJECTILE) + } } } - } \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 0947b7e..ddd5547 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -15,6 +15,7 @@ import io.papermc.paper.component.DataComponentTypes import io.papermc.paper.component.item.ItemLore import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems +import kotlinx.serialization.Contextual import kotlinx.serialization.* import kotlinx.serialization.EncodeDefault.Mode.NEVER import net.kyori.adventure.text.format.TextDecoration @@ -73,11 +74,11 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val recipeOptions: List = listOf(), // Unvalued DataTypes - @EncodeDefault(NEVER) val fireResistant: SerializableDataTypes.FireResistant? = null, - @EncodeDefault(NEVER) val hideTooltip: SerializableDataTypes.HideToolTip? = null, - @EncodeDefault(NEVER) val hideAdditionalTooltip: SerializableDataTypes.HideAdditionalTooltip? = null, - @EncodeDefault(NEVER) val creativeSlotLock: SerializableDataTypes.CreativeSlotLock? = null, - @EncodeDefault(NEVER) val intangibleProjectile: SerializableDataTypes.IntangibleProjectile? = null, + @EncodeDefault(NEVER) @Contextual val fireResistant: SerializableDataTypes.FireResistant? = null, + @EncodeDefault(NEVER) @Contextual val hideTooltip: SerializableDataTypes.HideToolTip? = null, + @EncodeDefault(NEVER) @Contextual val hideAdditionalTooltip: SerializableDataTypes.HideAdditionalTooltip? = null, + @EncodeDefault(NEVER) @Contextual val creativeSlotLock: SerializableDataTypes.CreativeSlotLock? = null, + @EncodeDefault(NEVER) @Contextual val intangibleProjectile: SerializableDataTypes.IntangibleProjectile? = null, // Third-party plugins @EncodeDefault(NEVER) val crucibleItem: String? = null, @@ -219,11 +220,11 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), - fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, - hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, - hideAdditionalTooltip = SerializableDataTypes.HideAdditionalTooltip.takeIf { hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) }, - creativeSlotLock = SerializableDataTypes.CreativeSlotLock.takeIf { hasData(DataComponentTypes.CREATIVE_SLOT_LOCK) }, - intangibleProjectile = SerializableDataTypes.IntangibleProjectile.takeIf { hasData(DataComponentTypes.INTANGIBLE_PROJECTILE) }, + fireResistant = hasData(DataComponentTypes.FIRE_RESISTANT).takeIf { it }?.let { SerializableDataTypes.FireResistant(true) }, + hideTooltip = hasData(DataComponentTypes.HIDE_TOOLTIP).takeIf { it }?.let { SerializableDataTypes.HideToolTip(true) }, + hideAdditionalTooltip = hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP).takeIf { it }?.let { SerializableDataTypes.HideAdditionalTooltip(true) }, + creativeSlotLock = hasData(DataComponentTypes.CREATIVE_SLOT_LOCK).takeIf { it }?.let { SerializableDataTypes.CreativeSlotLock(true) }, + intangibleProjectile = hasData(DataComponentTypes.INTANGIBLE_PROJECTILE).takeIf { it }?.let { SerializableDataTypes.IntangibleProjectile(true) }, knowledgeBookRecipes = ((this as? KnowledgeBookMeta)?.recipes?.map { it.getItemPrefabFromRecipe() }?.flatten() ?: emptyList()).takeIf { it.isNotEmpty() }, From e927d2ddfce9ce6b777d61b3b67f3299b6ab8be6 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 16:48:29 +0200 Subject: [PATCH 04/15] refactor: remove itemflags --- .../idofront/serialization/SerializableItemStack.kt | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index ddd5547..6435f5f 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -54,7 +54,6 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val unbreakable: SerializableDataTypes.Unbreakable? = null, @EncodeDefault(NEVER) val damage: Int? = null, @EncodeDefault(NEVER) val maxDamage: Int? = null, - @EncodeDefault(NEVER) val itemFlags: List? = null, @EncodeDefault(NEVER) val enchantments: SerializableDataTypes.Enchantments? = null, @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, @@ -145,12 +144,6 @@ data class BaseSerializableItemStack( amount?.let { applyTo.amount = it } type?.let { applyTo.type = type } - // Modify meta - val meta = applyTo.itemMeta ?: return applyTo - if (itemFlags?.isNotEmpty() == true) meta.addItemFlags(*itemFlags.toTypedArray()) - if (knowledgeBookRecipes != null) (meta as? KnowledgeBookMeta)?.recipes = knowledgeBookRecipes.map { it.getSubRecipeIDs() }.flatten() - applyTo.itemMeta = meta - SerializableDataTypes.setData(applyTo, DataComponentTypes.ITEM_NAME, itemName) SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_NAME, customName) SerializableDataTypes.setData(applyTo, DataComponentTypes.LORE, lore?.let { ItemLore.lore(lore) }) @@ -226,11 +219,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { creativeSlotLock = hasData(DataComponentTypes.CREATIVE_SLOT_LOCK).takeIf { it }?.let { SerializableDataTypes.CreativeSlotLock(true) }, intangibleProjectile = hasData(DataComponentTypes.INTANGIBLE_PROJECTILE).takeIf { it }?.let { SerializableDataTypes.IntangibleProjectile(true) }, - knowledgeBookRecipes = ((this as? KnowledgeBookMeta)?.recipes?.map { it.getItemPrefabFromRecipe() }?.flatten() - ?: emptyList()).takeIf { it.isNotEmpty() }, - itemFlags = (this?.itemFlags?.toList() ?: listOf()).takeIf { it.isNotEmpty() }, - - ) //TODO perhaps this should encode prefab too? + ) //TODO perhaps this should encode prefab too? } private fun String.getSubRecipeIDs(): MutableList { From 6aa55065794f88c1eceeeec719ce91e43573d3c5 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 16:49:23 +0200 Subject: [PATCH 05/15] refactor: fix recipes component --- .../serialization/SerializableItemStack.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 6435f5f..1f58ee4 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -18,9 +18,15 @@ import io.th0rgal.oraxen.api.OraxenItems import kotlinx.serialization.Contextual import kotlinx.serialization.* import kotlinx.serialization.EncodeDefault.Mode.NEVER +import kotlinx.serialization.Serializable +import kotlinx.serialization.UseSerializers +import net.kyori.adventure.key.Key +import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.* -import org.bukkit.inventory.ItemFlag +import org.bukkit.Bukkit +import org.bukkit.Keyed +import org.bukkit.Material +import org.bukkit.NamespacedKey import org.bukkit.inventory.ItemRarity import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.KnowledgeBookMeta @@ -57,7 +63,7 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val enchantments: SerializableDataTypes.Enchantments? = null, @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, - @EncodeDefault(NEVER) val knowledgeBookRecipes: List? = null, + @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, @EncodeDefault(NEVER) val tool: SerializableDataTypes.Tool? = null, @@ -157,6 +163,7 @@ data class BaseSerializableItemStack( SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) SerializableDataTypes.setData(applyTo, DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride) + //SerializableDataTypes.setData(applyTo, DataComponentTypes.RECIPES, recipes) unbreakable?.setDataType(applyTo) food?.setDataType(applyTo) tool?.setDataType(applyTo) @@ -205,6 +212,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { maxStackSize = getData(DataComponentTypes.MAX_STACK_SIZE), rarity = getData(DataComponentTypes.RARITY), enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), + //recipes = getData(DataComponentTypes.RECIPES), enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), From ea3faae94f3a24cca26b8338e037478185e327a9 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 17:55:52 +0200 Subject: [PATCH 06/15] fix: properly handle adding rules to tool-component --- .../serialization/SerializableDataTypes.kt | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 3deaf9f..5bf1213 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -7,14 +7,10 @@ import io.papermc.paper.component.item.ItemAttributeModifiers import io.papermc.paper.component.item.ItemEnchantments import io.papermc.paper.component.item.Tool.Rule import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey import io.papermc.paper.registry.set.RegistrySet -import kotlinx.serialization.KSerializer +import io.papermc.paper.registry.tag.TagKey import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder import net.kyori.adventure.key.Key import net.kyori.adventure.util.TriState import org.bukkit.Color @@ -81,32 +77,53 @@ object SerializableDataTypes { @Serializable data class Tool( - val rules: List, + val rules: List = emptyList(), val defaultMiningSpeed: Float, val damagePerBlock: Int ) : DataType { - constructor(tool: io.papermc.paper.component.item.Tool) : this(tool.rules().map(::Rule), tool.defaultMiningSpeed(), tool.damagePerBlock()) + constructor(tool: io.papermc.paper.component.item.Tool) : this( + tool.rules().map(::Rule), + tool.defaultMiningSpeed(), + tool.damagePerBlock() + ) + override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.TOOL, io.papermc.paper.component.item.Tool.tool() - .damagePerBlock(damagePerBlock) - .defaultMiningSpeed(defaultMiningSpeed) - .addRules(rules.map(Rule::paperRule)) - .build() + itemStack.setData( + DataComponentTypes.TOOL, io.papermc.paper.component.item.Tool.tool() + .damagePerBlock(damagePerBlock) + .defaultMiningSpeed(defaultMiningSpeed) + .addRules(rules.toPaperRules()) + .build() ) } + private fun List.toPaperRules(): List { + val rules = mutableListOf() + + this.forEach { rule -> + val blockTagKeys = rule.blockTypes.map { TagKey.create(RegistryKey.BLOCK, it) }.filter(Registry.BLOCK::hasTag) + blockTagKeys.map(Registry.BLOCK::getTag).forEach { blockTag -> + rules += io.papermc.paper.component.item.Tool.Rule.of(blockTag, rule.speed, rule.correctForDrops) + } + val blockKeys = rule.blockTypes.filter { Registry.BLOCK.get(it) != null }.map { TypedKey.create(RegistryKey.BLOCK, it.key()) } + val keySet = RegistrySet.keySet(RegistryKey.BLOCK, blockKeys) + rules += io.papermc.paper.component.item.Tool.Rule.of(keySet, rule.speed, rule.correctForDrops) + } + + return rules + } + @Serializable data class Rule( val blockTypes: List<@Serializable(KeySerializer::class) Key>, val speed: Float? = null, val correctForDrops: TriState ) { - constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this(rule.blockTypes().map { it.key() }, rule.speed(), rule.correctForDrops()) - val paperRule: io.papermc.paper.component.item.Tool.Rule by lazy { - val blockTypes = blockTypes.mapNotNull { Registry.BLOCK.get(it) } - val keySet = RegistrySet.keySetFromValues(RegistryKey.BLOCK, blockTypes) - return@lazy io.papermc.paper.component.item.Tool.Rule.of(keySet, speed, correctForDrops) - } + constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this( + rule.blockTypes().map { it.key() }, + rule.speed(), + rule.correctForDrops() + ) } } From 491fbe2771292cf5b1c028f90100f8cedfa60260 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 18:08:18 +0200 Subject: [PATCH 07/15] refactor: change nonvalue components to x: {} --- .../serialization/SerializableDataTypes.kt | 54 ++++--------------- .../serialization/SerializableItemStack.kt | 22 ++++---- 2 files changed, 20 insertions(+), 56 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 5bf1213..5333bd4 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -24,6 +24,10 @@ object SerializableDataTypes { any?.let { itemStack.setData(dataComponent, any) } } + fun setData(itemStack: ItemStack, dataComponent: DataComponentType.NonValued, any: T?) { + any?.let { itemStack.setData(dataComponent) } + } + interface DataType { fun setDataType(itemStack: ItemStack) } @@ -210,50 +214,10 @@ object SerializableDataTypes { } } - @Serializable @JvmInline - value class FireResistant(private val state: Boolean) { - fun setDataType(itemStack: ItemStack) { - when (state) { - true -> itemStack.setData(DataComponentTypes.FIRE_RESISTANT) - false -> itemStack.resetData(DataComponentTypes.FIRE_RESISTANT) - } - } - } - @Serializable @JvmInline - value class HideToolTip(private val state: Boolean) { - fun setDataType(itemStack: ItemStack) { - when (state) { - true -> itemStack.setData(DataComponentTypes.HIDE_TOOLTIP) - false -> itemStack.resetData(DataComponentTypes.HIDE_TOOLTIP) - } - } - } - @Serializable @JvmInline - value class HideAdditionalTooltip(private val state: Boolean) { - fun setDataType(itemStack: ItemStack) { - when (state) { - true -> itemStack.setData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) - false -> itemStack.resetData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) - } - } - } - @Serializable @JvmInline - value class CreativeSlotLock(private val state: Boolean) { - fun setDataType(itemStack: ItemStack) { - when (state) { - true -> itemStack.setData(DataComponentTypes.CREATIVE_SLOT_LOCK) - false -> itemStack.resetData(DataComponentTypes.CREATIVE_SLOT_LOCK) - } - } - } - @Serializable @JvmInline - value class IntangibleProjectile(private val state: Boolean) { - fun setDataType(itemStack: ItemStack) { - when (state) { - true -> itemStack.setData(DataComponentTypes.INTANGIBLE_PROJECTILE) - false -> itemStack.resetData(DataComponentTypes.INTANGIBLE_PROJECTILE) - } - } - } + @Serializable object FireResistant + @Serializable object HideToolTip + @Serializable object HideAdditionalTooltip + @Serializable object CreativeSlotLock + @Serializable object IntangibleProjectile } \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 1f58ee4..3a25685 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -168,13 +168,13 @@ data class BaseSerializableItemStack( food?.setDataType(applyTo) tool?.setDataType(applyTo) - fireResistant?.setDataType(applyTo) - hideTooltip?.setDataType(applyTo) - hideAdditionalTooltip?.setDataType(applyTo) - creativeSlotLock?.setDataType(applyTo) - intangibleProjectile?.setDataType(applyTo) + SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) + SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) + SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, hideAdditionalTooltip) + SerializableDataTypes.setData(applyTo, DataComponentTypes.CREATIVE_SLOT_LOCK, creativeSlotLock) + SerializableDataTypes.setData(applyTo, DataComponentTypes.INTANGIBLE_PROJECTILE, intangibleProjectile) - return applyTo.hideAttributeTooltipWithItemFlagSet() + return applyTo } fun toItemStackOrNull(applyTo: ItemStack = ItemStack(type ?: Material.AIR)) = @@ -221,11 +221,11 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), - fireResistant = hasData(DataComponentTypes.FIRE_RESISTANT).takeIf { it }?.let { SerializableDataTypes.FireResistant(true) }, - hideTooltip = hasData(DataComponentTypes.HIDE_TOOLTIP).takeIf { it }?.let { SerializableDataTypes.HideToolTip(true) }, - hideAdditionalTooltip = hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP).takeIf { it }?.let { SerializableDataTypes.HideAdditionalTooltip(true) }, - creativeSlotLock = hasData(DataComponentTypes.CREATIVE_SLOT_LOCK).takeIf { it }?.let { SerializableDataTypes.CreativeSlotLock(true) }, - intangibleProjectile = hasData(DataComponentTypes.INTANGIBLE_PROJECTILE).takeIf { it }?.let { SerializableDataTypes.IntangibleProjectile(true) }, + fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, + hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, + hideAdditionalTooltip = SerializableDataTypes.HideAdditionalTooltip.takeIf { hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) }, + creativeSlotLock = SerializableDataTypes.CreativeSlotLock.takeIf { hasData(DataComponentTypes.CREATIVE_SLOT_LOCK) }, + intangibleProjectile = SerializableDataTypes.IntangibleProjectile.takeIf { hasData(DataComponentTypes.INTANGIBLE_PROJECTILE) }, ) //TODO perhaps this should encode prefab too? } From 3dbd00fdff39cdf0c03488d100c2a9bbbf1efac5 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 18:48:21 +0200 Subject: [PATCH 08/15] feat: add few more components --- .../serialization/SerializableDataTypes.kt | 162 +++++++++++++++--- .../serialization/SerializableItemStack.kt | 14 ++ 2 files changed, 150 insertions(+), 26 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 5333bd4..b0a301b 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -1,10 +1,9 @@ package com.mineinabyss.idofront.serialization +import io.papermc.paper.block.BlockPredicate import io.papermc.paper.component.DataComponentType import io.papermc.paper.component.DataComponentTypes -import io.papermc.paper.component.item.DyedItemColor -import io.papermc.paper.component.item.ItemAttributeModifiers -import io.papermc.paper.component.item.ItemEnchantments +import io.papermc.paper.component.item.* import io.papermc.paper.component.item.Tool.Rule import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey @@ -35,6 +34,7 @@ object SerializableDataTypes { @Serializable data class Unbreakable(val shownInTooltip: Boolean = true) : DataType { constructor(unbreakable: io.papermc.paper.component.item.Unbreakable) : this(unbreakable.showInTooltip()) + override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.UNBREAKABLE, @@ -70,7 +70,10 @@ object SerializableDataTypes { val enchantments: List, val showInToolTip: Boolean = true ) : DataType { - constructor(itemEnchantments: ItemEnchantments) : this(itemEnchantments.enchantments().map(::SerializableEnchantment), itemEnchantments.showInTooltip()) + constructor(itemEnchantments: ItemEnchantments) : this( + itemEnchantments.enchantments().map(::SerializableEnchantment), itemEnchantments.showInTooltip() + ) + override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.ENCHANTMENTS, @@ -79,12 +82,29 @@ object SerializableDataTypes { } } + @Serializable + data class StoredEnchantments( + val enchantments: List, + val showInToolTip: Boolean = true + ) : DataType { + constructor(itemEnchantments: ItemEnchantments) : this( + itemEnchantments.enchantments().map(::SerializableEnchantment), itemEnchantments.showInTooltip() + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.STORED_ENCHANTMENTS, + ItemEnchantments.itemEnchantments(enchantments.associate { it.enchant to it.level }, showInToolTip) + ) + } + } + @Serializable data class Tool( val rules: List = emptyList(), val defaultMiningSpeed: Float, val damagePerBlock: Int - ) : DataType { + ) : BlockTags(), DataType { constructor(tool: io.papermc.paper.component.item.Tool) : this( tool.rules().map(::Rule), tool.defaultMiningSpeed(), @@ -101,33 +121,110 @@ object SerializableDataTypes { ) } - private fun List.toPaperRules(): List { - val rules = mutableListOf() + @Serializable + data class Rule( + val blockTypes: List<@Serializable(KeySerializer::class) Key>, + val speed: Float? = null, + val correctForDrops: TriState + ) { + constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this( + rule.blockTypes().map { it.key() }, + rule.speed(), + rule.correctForDrops() + ) + } + } + + @Serializable + data class CanPlaceOn( + val showInToolTip: Boolean = true, + val modifiers: List + ) : BlockTags(), DataType { + constructor(adventurePredicate: ItemAdventurePredicate) : + this(adventurePredicate.showInTooltip(), adventurePredicate.modifiers().map(::BlockPredicate)) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CAN_PLACE_ON, ItemAdventurePredicate.itemAdventurePredicate() + .showInTooltip(showInToolTip).apply { + modifiers.toPaperBlockPredicate().forEach { blockPredicate -> + addPredicate(blockPredicate) + } + } + .build() + ) + } + } + + @Serializable + data class CanBreak( + val showInToolTip: Boolean = true, + val modifiers: List + ) : BlockTags(), DataType { + constructor(adventurePredicate: ItemAdventurePredicate) : + this(adventurePredicate.showInTooltip(), adventurePredicate.modifiers().map(::BlockPredicate)) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CAN_BREAK, ItemAdventurePredicate.itemAdventurePredicate() + .showInTooltip(showInToolTip).apply { + modifiers.toPaperBlockPredicate().forEach { blockPredicate -> + addPredicate(blockPredicate) + } + } + .build() + ) + } + } + + @Serializable + sealed class BlockTags { + fun List.toPaperRules(): List { + val rules = mutableListOf() this.forEach { rule -> - val blockTagKeys = rule.blockTypes.map { TagKey.create(RegistryKey.BLOCK, it) }.filter(Registry.BLOCK::hasTag) + val blockTagKeys = + rule.blockTypes.map { TagKey.create(RegistryKey.BLOCK, it) }.filter(Registry.BLOCK::hasTag) blockTagKeys.map(Registry.BLOCK::getTag).forEach { blockTag -> - rules += io.papermc.paper.component.item.Tool.Rule.of(blockTag, rule.speed, rule.correctForDrops) + rules += Rule.of(blockTag, rule.speed, rule.correctForDrops) } - val blockKeys = rule.blockTypes.filter { Registry.BLOCK.get(it) != null }.map { TypedKey.create(RegistryKey.BLOCK, it.key()) } + val blockKeys = rule.blockTypes.filter { Registry.BLOCK.get(it) != null } + .map { TypedKey.create(RegistryKey.BLOCK, it.key()) } val keySet = RegistrySet.keySet(RegistryKey.BLOCK, blockKeys) - rules += io.papermc.paper.component.item.Tool.Rule.of(keySet, rule.speed, rule.correctForDrops) + rules += Rule.of(keySet, rule.speed, rule.correctForDrops) } return rules } + fun List.toPaperBlockPredicate(): List { + val blockPredicates = mutableListOf() + + this.forEach { blockPredicate -> + blockPredicate.blocks + ?.map { TagKey.create(RegistryKey.BLOCK, it) } + ?.filter(Registry.BLOCK::hasTag)?.map(Registry.BLOCK::getTag) + ?.forEach { blockTag -> + blockPredicates += io.papermc.paper.block.BlockPredicate.predicate().blocks(blockTag).build() + } + + blockPredicate.blocks?.filter { Registry.BLOCK.get(it) != null } + ?.map { TypedKey.create(RegistryKey.BLOCK, it.key()) } + ?.let { blockKeys -> + val keySet = RegistrySet.keySet(RegistryKey.BLOCK, blockKeys) + blockPredicates += io.papermc.paper.block.BlockPredicate.predicate().blocks(keySet).build() + } + } + + return blockPredicates + } + @Serializable - data class Rule( - val blockTypes: List<@Serializable(KeySerializer::class) Key>, - val speed: Float? = null, - val correctForDrops: TriState + data class BlockPredicate( + val blocks: List<@Serializable(KeySerializer::class) Key>? ) { - constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this( - rule.blockTypes().map { it.key() }, - rule.speed(), - rule.correctForDrops() - ) + constructor(blockPredicate: io.papermc.paper.block.BlockPredicate) : this( + blockPredicate.blocks()?.map { it.key() }) } } @@ -179,6 +276,7 @@ object SerializableDataTypes { @JvmInline value class CustomModelData(private val customModelData: Int) : DataType { constructor(customModelData: io.papermc.paper.component.item.CustomModelData) : this(customModelData.data()) + override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.CUSTOM_MODEL_DATA, @@ -206,7 +304,10 @@ object SerializableDataTypes { val showInToolTip: Boolean = true ) : DataType { - constructor(attributeModifiers: ItemAttributeModifiers) : this(attributeModifiers.modifiers().map(::SerializableAttribute), attributeModifiers.showInTooltip()) + constructor(attributeModifiers: ItemAttributeModifiers) : this( + attributeModifiers.modifiers().map(::SerializableAttribute), attributeModifiers.showInTooltip() + ) + override fun setDataType(itemStack: ItemStack) { itemStack.setData(DataComponentTypes.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.itemAttributes().apply { attributes.forEach { addModifier(it.attribute, it.modifier) } @@ -214,10 +315,19 @@ object SerializableDataTypes { } } - @Serializable object FireResistant - @Serializable object HideToolTip - @Serializable object HideAdditionalTooltip - @Serializable object CreativeSlotLock - @Serializable object IntangibleProjectile + @Serializable + object FireResistant + + @Serializable + object HideToolTip + + @Serializable + object HideAdditionalTooltip + + @Serializable + object CreativeSlotLock + + @Serializable + object IntangibleProjectile } \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 3a25685..703ea6c 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -61,6 +61,7 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val damage: Int? = null, @EncodeDefault(NEVER) val maxDamage: Int? = null, @EncodeDefault(NEVER) val enchantments: SerializableDataTypes.Enchantments? = null, + @EncodeDefault(NEVER) val storedEnchantments: SerializableDataTypes.StoredEnchantments? = null, @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, @@ -70,9 +71,13 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null, @EncodeDefault(NEVER) val hideTooltip: Boolean? = null, @EncodeDefault(NEVER) val isFireResistant: Boolean? = null, + @EncodeDefault(NEVER) val canPlaceOn: SerializableDataTypes.CanPlaceOn? = null, + @EncodeDefault(NEVER) val canBreak: SerializableDataTypes.CanBreak? = null, + @EncodeDefault(NEVER) val enchantmentGlintOverride: Boolean? = null, @EncodeDefault(NEVER) val maxStackSize: Int? = null, @EncodeDefault(NEVER) val rarity: ItemRarity? = null, + @EncodeDefault(NEVER) val repaircost: Int? = null, @EncodeDefault(NEVER) val prefab: String? = null, @EncodeDefault(NEVER) val tag: String? = null, @@ -156,9 +161,11 @@ data class BaseSerializableItemStack( customModelData?.setDataType(applyTo) enchantments?.setDataType(applyTo) + storedEnchantments?.setDataType(applyTo) potionType?.setDataType(applyTo) attributeModifiers?.setDataType(applyTo) + SerializableDataTypes.setData(applyTo, DataComponentTypes.REPAIR_COST, repaircost) SerializableDataTypes.setData(applyTo, DataComponentTypes.DAMAGE, damage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) @@ -167,6 +174,8 @@ data class BaseSerializableItemStack( unbreakable?.setDataType(applyTo) food?.setDataType(applyTo) tool?.setDataType(applyTo) + canPlaceOn?.setDataType(applyTo) + canBreak?.setDataType(applyTo) SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) @@ -205,6 +214,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { itemName = getData(DataComponentTypes.ITEM_NAME), customName = getData(DataComponentTypes.CUSTOM_NAME), customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA)?.let(SerializableDataTypes::CustomModelData), + unbreakable = getData(DataComponentTypes.UNBREAKABLE)?.let(SerializableDataTypes::Unbreakable), lore = getData(DataComponentTypes.LORE)?.lines(), damage = getData(DataComponentTypes.DAMAGE), @@ -212,14 +222,18 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { maxStackSize = getData(DataComponentTypes.MAX_STACK_SIZE), rarity = getData(DataComponentTypes.RARITY), enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), + repaircost = getData(DataComponentTypes.REPAIR_COST), //recipes = getData(DataComponentTypes.RECIPES), enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), + storedEnchantments = getData(DataComponentTypes.STORED_ENCHANTMENTS)?.let(SerializableDataTypes::StoredEnchantments), attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), potionType = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), dyedColor = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), + canPlaceOn = getData(DataComponentTypes.CAN_PLACE_ON)?.let(SerializableDataTypes::CanPlaceOn), + canBreak = getData(DataComponentTypes.CAN_BREAK)?.let(SerializableDataTypes::CanBreak), fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, From 89183a35d9f783b80368427f03be276e7fe96c73 Mon Sep 17 00:00:00 2001 From: Boy Date: Tue, 18 Jun 2024 20:43:59 +0200 Subject: [PATCH 09/15] feat: add few more components again --- .../serialization/SerializableDataTypes.kt | 32 +++++++++++++++++++ .../serialization/SerializableItemStack.kt | 28 ++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index b0a301b..2424361 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -5,6 +5,7 @@ import io.papermc.paper.component.DataComponentType import io.papermc.paper.component.DataComponentTypes import io.papermc.paper.component.item.* import io.papermc.paper.component.item.Tool.Rule +import io.papermc.paper.registry.RegistryAccess import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey import io.papermc.paper.registry.set.RegistrySet @@ -15,6 +16,9 @@ import net.kyori.adventure.util.TriState import org.bukkit.Color import org.bukkit.Registry import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.trim.ArmorTrim +import org.bukkit.inventory.meta.trim.TrimMaterial +import org.bukkit.inventory.meta.trim.TrimPattern import org.bukkit.potion.PotionEffect object SerializableDataTypes { @@ -298,6 +302,34 @@ object SerializableDataTypes { } } + @Serializable + data class MapColor( + val color: @Serializable(ColorSerializer::class) Color, + ) : DataType { + constructor(mapItemColor: MapItemColor) : this(mapItemColor.mapColor()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.MAP_COLOR, MapItemColor.mapItemColor().mapColor(color).build()) + } + + } + + @Serializable + class Trim( + val material: @Serializable(KeySerializer::class) Key, + val pattern: @Serializable(KeySerializer::class) Key, + val showInToolTip: Boolean = true + ) : DataType { + constructor(trim: ItemArmorTrim) : this(trim.armorTrim().material.key(), trim.armorTrim().pattern.key(), trim.showInTooltip()) + + override fun setDataType(itemStack: ItemStack) { + val trimMaterial = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_MATERIAL).get(material) ?: error("Invalid TrimMaterial: " + material.asString()) + val trimPattern = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_PATTERN).get(pattern) ?: error("Invalid TrimPattern: " + pattern.asString()) + itemStack.setData(DataComponentTypes.TRIM, ItemArmorTrim.itemArmorTrim(ArmorTrim(trimMaterial, trimPattern), showInToolTip)) + } + + } + @Serializable data class AttributeModifiers( val attributes: List, diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 703ea6c..c41dc58 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -4,7 +4,6 @@ package com.mineinabyss.idofront.serialization import com.mineinabyss.idofront.di.DI import com.mineinabyss.idofront.messaging.idofrontLogger -import com.mineinabyss.idofront.nms.hideAttributeTooltipWithItemFlagSet import com.mineinabyss.idofront.plugin.Plugins import com.mineinabyss.idofront.serialization.recipes.options.IngredientOption import com.mineinabyss.idofront.textcomponents.miniMsg @@ -12,7 +11,9 @@ import com.mineinabyss.idofront.textcomponents.serialize import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible import io.papermc.paper.component.DataComponentTypes +import io.papermc.paper.component.item.BundleContents import io.papermc.paper.component.item.ItemLore +import io.papermc.paper.component.item.MapID import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems import kotlinx.serialization.Contextual @@ -64,8 +65,6 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val storedEnchantments: SerializableDataTypes.StoredEnchantments? = null, @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, - @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, - @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, @EncodeDefault(NEVER) val tool: SerializableDataTypes.Tool? = null, @EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null, @@ -73,11 +72,18 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val isFireResistant: Boolean? = null, @EncodeDefault(NEVER) val canPlaceOn: SerializableDataTypes.CanPlaceOn? = null, @EncodeDefault(NEVER) val canBreak: SerializableDataTypes.CanBreak? = null, + @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, + @EncodeDefault(NEVER) val mapColor: SerializableDataTypes.MapColor? = null, + @EncodeDefault(NEVER) val trim: SerializableDataTypes.Trim? = null, + @EncodeDefault(NEVER) val bundleContents: List? = null, + @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, @EncodeDefault(NEVER) val enchantmentGlintOverride: Boolean? = null, @EncodeDefault(NEVER) val maxStackSize: Int? = null, @EncodeDefault(NEVER) val rarity: ItemRarity? = null, - @EncodeDefault(NEVER) val repaircost: Int? = null, + @EncodeDefault(NEVER) val repairCost: Int? = null, + @EncodeDefault(NEVER) val mapId: Int? = null, + @EncodeDefault(NEVER) val prefab: String? = null, @EncodeDefault(NEVER) val tag: String? = null, @@ -165,7 +171,7 @@ data class BaseSerializableItemStack( potionType?.setDataType(applyTo) attributeModifiers?.setDataType(applyTo) - SerializableDataTypes.setData(applyTo, DataComponentTypes.REPAIR_COST, repaircost) + SerializableDataTypes.setData(applyTo, DataComponentTypes.REPAIR_COST, repairCost) SerializableDataTypes.setData(applyTo, DataComponentTypes.DAMAGE, damage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) @@ -176,6 +182,11 @@ data class BaseSerializableItemStack( tool?.setDataType(applyTo) canPlaceOn?.setDataType(applyTo) canBreak?.setDataType(applyTo) + trim?.setDataType(applyTo) + + bundleContents?.let { applyTo.setData(DataComponentTypes.BUNDLE_CONTENTS, BundleContents.bundleContents(bundleContents.map { it.toItemStack() })) } + mapId?.let { applyTo.setData(DataComponentTypes.MAP_ID, MapID.mapId().mapId(mapId).build()) } + mapColor?.setDataType(applyTo) SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) @@ -222,7 +233,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { maxStackSize = getData(DataComponentTypes.MAX_STACK_SIZE), rarity = getData(DataComponentTypes.RARITY), enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), - repaircost = getData(DataComponentTypes.REPAIR_COST), + repairCost = getData(DataComponentTypes.REPAIR_COST), //recipes = getData(DataComponentTypes.RECIPES), enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), @@ -234,6 +245,11 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), canPlaceOn = getData(DataComponentTypes.CAN_PLACE_ON)?.let(SerializableDataTypes::CanPlaceOn), canBreak = getData(DataComponentTypes.CAN_BREAK)?.let(SerializableDataTypes::CanBreak), + bundleContents = getData(DataComponentTypes.BUNDLE_CONTENTS)?.contents()?.map { it.toSerializable() }, + trim = getData(DataComponentTypes.TRIM)?.let(SerializableDataTypes::Trim), + + mapId = getData(DataComponentTypes.MAP_ID)?.id(), + mapColor = getData(DataComponentTypes.MAP_COLOR)?.let(SerializableDataTypes::MapColor), fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, From d5a5fb3b5cd851b6b07f6207636eb07777f2c38d Mon Sep 17 00:00:00 2001 From: Boy Date: Thu, 20 Jun 2024 20:39:37 +0200 Subject: [PATCH 10/15] feat: add even more components --- .../serialization/SerializableDataTypes.kt | 123 ++++++++++++++++-- .../serialization/SerializableItemStack.kt | 32 ++++- 2 files changed, 143 insertions(+), 12 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 2424361..9d6026e 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -4,6 +4,7 @@ import io.papermc.paper.block.BlockPredicate import io.papermc.paper.component.DataComponentType import io.papermc.paper.component.DataComponentTypes import io.papermc.paper.component.item.* +import io.papermc.paper.component.item.MapDecorations.DecorationEntry import io.papermc.paper.component.item.Tool.Rule import io.papermc.paper.registry.RegistryAccess import io.papermc.paper.registry.RegistryKey @@ -12,13 +13,13 @@ import io.papermc.paper.registry.set.RegistrySet import io.papermc.paper.registry.tag.TagKey import kotlinx.serialization.Serializable import net.kyori.adventure.key.Key +import net.kyori.adventure.text.Component import net.kyori.adventure.util.TriState import org.bukkit.Color import org.bukkit.Registry import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.trim.ArmorTrim -import org.bukkit.inventory.meta.trim.TrimMaterial -import org.bukkit.inventory.meta.trim.TrimPattern +import org.bukkit.map.MapCursor import org.bukkit.potion.PotionEffect object SerializableDataTypes { @@ -103,6 +104,83 @@ object SerializableDataTypes { } } + @Serializable + @JvmInline + value class ChargedProjectiles(private val projectiles: List) : DataType { + constructor(vararg projectiles: ItemStack) : this(projectiles.map { it.toSerializable() }) + constructor(projectiles: io.papermc.paper.component.item.ChargedProjectiles) : this( + projectiles.projectiles().map { it.toSerializable() }) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CHARGED_PROJECTILES, + io.papermc.paper.component.item.ChargedProjectiles.chargedProjectiles(projectiles.mapNotNull { it.toItemStackOrNull() }) + ) + } + } + + @Serializable + @JvmInline + value class BundleContent(private val contents: List) : DataType { + constructor(vararg contents: ItemStack) : this(contents.map { it.toSerializable() }) + constructor(contents: BundleContents) : this(contents.contents().map { it.toSerializable() }) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.BUNDLE_CONTENTS, + BundleContents.bundleContents(contents.mapNotNull { it.toItemStackOrNull() }) + ) + } + } + + @Serializable + data class WrittenBook( + val title: String, + val author: String, + val generation: Int, + val resolved: Boolean, + val pages: List<@Serializable(MiniMessageSerializer::class) Component> = emptyList() + ) : DataType { + constructor(written: WrittenBookContent) : this( + written.title().raw(), + written.author(), + written.generation(), + written.resolved(), + written.pages().map { it.raw() } + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.WRITTEN_BOOK_CONTENT, + WrittenBookContent.writtenBookContent(title, author).resolved(resolved).generation(generation) + .addPages(pages).build() + ) + } + } + + @Serializable + data class WritableBook(val pages: List) : DataType { + constructor(writable: WritableBookContent) : this(writable.pages().map { it.raw() }) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.WRITABLE_BOOK_CONTENT, + WritableBookContent.writeableBookContent().addPages(pages).build() + ) + } + } + + @Serializable + data class MapDecoration(val type: MapCursor.Type, val x: Double, val z: Double, val rotation: Float) { + constructor(entry: DecorationEntry) : this(entry.type(), entry.x(), entry.z(), entry.rotation()) + val paperDecoration: DecorationEntry = DecorationEntry.of(type, x, z, rotation) + + companion object { + fun toPaperDecorations(decorations: List) = + decorations.mapIndexed { i, mapDecoration -> i.toString() to mapDecoration.paperDecoration }.toMap() + } + } + @Serializable data class Tool( val rules: List = emptyList(), @@ -303,8 +381,9 @@ object SerializableDataTypes { } @Serializable - data class MapColor( - val color: @Serializable(ColorSerializer::class) Color, + @JvmInline + value class MapColor( + private val color: @Serializable(ColorSerializer::class) Color, ) : DataType { constructor(mapItemColor: MapItemColor) : this(mapItemColor.mapColor()) @@ -320,16 +399,44 @@ object SerializableDataTypes { val pattern: @Serializable(KeySerializer::class) Key, val showInToolTip: Boolean = true ) : DataType { - constructor(trim: ItemArmorTrim) : this(trim.armorTrim().material.key(), trim.armorTrim().pattern.key(), trim.showInTooltip()) + constructor(trim: ItemArmorTrim) : this( + trim.armorTrim().material.key(), + trim.armorTrim().pattern.key(), + trim.showInTooltip() + ) override fun setDataType(itemStack: ItemStack) { - val trimMaterial = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_MATERIAL).get(material) ?: error("Invalid TrimMaterial: " + material.asString()) - val trimPattern = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_PATTERN).get(pattern) ?: error("Invalid TrimPattern: " + pattern.asString()) - itemStack.setData(DataComponentTypes.TRIM, ItemArmorTrim.itemArmorTrim(ArmorTrim(trimMaterial, trimPattern), showInToolTip)) + val trimMaterial = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_MATERIAL).get(material) + ?: error("Invalid TrimMaterial: " + material.asString()) + val trimPattern = RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_PATTERN).get(pattern) + ?: error("Invalid TrimPattern: " + pattern.asString()) + itemStack.setData( + DataComponentTypes.TRIM, + ItemArmorTrim.itemArmorTrim(ArmorTrim(trimMaterial, trimPattern), showInToolTip) + ) } } + @Serializable + data class JukeboxPlayable( + val jukeboxSong: @Serializable(KeySerializer::class) Key, + val showInToolTip: Boolean = true + ) : DataType { + constructor(jukeboxPlayable: io.papermc.paper.component.item.JukeboxPlayable) : + this(jukeboxPlayable.jukeboxSong().key(), jukeboxPlayable.showInTooltip()) + + override fun setDataType(itemStack: ItemStack) { + val jukeboxRegistry = RegistryAccess.registryAccess().getRegistry(RegistryKey.JUKEBOX_SONG) + val jukeboxSong = jukeboxRegistry.get(jukeboxSong) ?: return + itemStack.setData( + DataComponentTypes.JUKEBOX_PLAYABLE, + io.papermc.paper.component.item.JukeboxPlayable.jukeboxPlayable().showInTooltip(showInToolTip) + .jukeboxSong(jukeboxSong) + ) + } + } + @Serializable data class AttributeModifiers( val attributes: List, diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index c41dc58..f4b003a 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -11,9 +11,10 @@ import com.mineinabyss.idofront.textcomponents.serialize import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible import io.papermc.paper.component.DataComponentTypes -import io.papermc.paper.component.item.BundleContents import io.papermc.paper.component.item.ItemLore +import io.papermc.paper.component.item.MapDecorations import io.papermc.paper.component.item.MapID +import io.papermc.paper.component.item.MapPostProcessing import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems import kotlinx.serialization.Contextual @@ -74,15 +75,21 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val canBreak: SerializableDataTypes.CanBreak? = null, @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, @EncodeDefault(NEVER) val mapColor: SerializableDataTypes.MapColor? = null, + @EncodeDefault(NEVER) val mapDecorations: List? = null, @EncodeDefault(NEVER) val trim: SerializableDataTypes.Trim? = null, + @EncodeDefault(NEVER) val jukeboxPlayable: SerializableDataTypes.JukeboxPlayable? = null, + @EncodeDefault(NEVER) val chargedProjectiles: SerializableDataTypes.ChargedProjectiles? = null, + @EncodeDefault(NEVER) val bundleContents: SerializableDataTypes.BundleContent? = null, + @EncodeDefault(NEVER) val writableBook: SerializableDataTypes.WritableBook? = null, + @EncodeDefault(NEVER) val writtenBook: SerializableDataTypes.WrittenBook? = null, - @EncodeDefault(NEVER) val bundleContents: List? = null, @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, @EncodeDefault(NEVER) val enchantmentGlintOverride: Boolean? = null, @EncodeDefault(NEVER) val maxStackSize: Int? = null, @EncodeDefault(NEVER) val rarity: ItemRarity? = null, @EncodeDefault(NEVER) val repairCost: Int? = null, @EncodeDefault(NEVER) val mapId: Int? = null, + @EncodeDefault(NEVER) val mapPostProcessing: MapPostProcessing? = null, @EncodeDefault(NEVER) val prefab: String? = null, @@ -183,10 +190,21 @@ data class BaseSerializableItemStack( canPlaceOn?.setDataType(applyTo) canBreak?.setDataType(applyTo) trim?.setDataType(applyTo) + jukeboxPlayable?.setDataType(applyTo) + chargedProjectiles?.setDataType(applyTo) + bundleContents?.setDataType(applyTo) + writableBook?.setDataType(applyTo) + writtenBook?.setDataType(applyTo) - bundleContents?.let { applyTo.setData(DataComponentTypes.BUNDLE_CONTENTS, BundleContents.bundleContents(bundleContents.map { it.toItemStack() })) } mapId?.let { applyTo.setData(DataComponentTypes.MAP_ID, MapID.mapId().mapId(mapId).build()) } + mapPostProcessing?.let { applyTo.setData(DataComponentTypes.MAP_POST_PROCESSING, it) } mapColor?.setDataType(applyTo) + mapDecorations?.let { + applyTo.setData( + DataComponentTypes.MAP_DECORATIONS, + MapDecorations.mapDecorations(SerializableDataTypes.MapDecoration.toPaperDecorations(mapDecorations)) + ) + } SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) @@ -245,11 +263,17 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), canPlaceOn = getData(DataComponentTypes.CAN_PLACE_ON)?.let(SerializableDataTypes::CanPlaceOn), canBreak = getData(DataComponentTypes.CAN_BREAK)?.let(SerializableDataTypes::CanBreak), - bundleContents = getData(DataComponentTypes.BUNDLE_CONTENTS)?.contents()?.map { it.toSerializable() }, trim = getData(DataComponentTypes.TRIM)?.let(SerializableDataTypes::Trim), + jukeboxPlayable = getData(DataComponentTypes.JUKEBOX_PLAYABLE)?.let(SerializableDataTypes::JukeboxPlayable), + chargedProjectiles = getData(DataComponentTypes.CHARGED_PROJECTILES)?.let(SerializableDataTypes::ChargedProjectiles), + bundleContents = getData(DataComponentTypes.BUNDLE_CONTENTS)?.let(SerializableDataTypes::BundleContent), + writableBook = getData(DataComponentTypes.WRITABLE_BOOK_CONTENT)?.let(SerializableDataTypes::WritableBook), + writtenBook = getData(DataComponentTypes.WRITTEN_BOOK_CONTENT)?.let(SerializableDataTypes::WrittenBook), mapId = getData(DataComponentTypes.MAP_ID)?.id(), mapColor = getData(DataComponentTypes.MAP_COLOR)?.let(SerializableDataTypes::MapColor), + mapPostProcessing = getData(DataComponentTypes.MAP_POST_PROCESSING), + mapDecorations = getData(DataComponentTypes.MAP_DECORATIONS)?.let { it.decorations.map { e -> SerializableDataTypes.MapDecoration(e.value) } }, fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, From 0873822965090f3ee25d412fd4db4c924319d7aa Mon Sep 17 00:00:00 2001 From: Boy Date: Sat, 10 Aug 2024 19:25:52 +0200 Subject: [PATCH 11/15] feat: add potdecorations, noteblock-sound & lock --- .../serialization/AttributeSerializer.kt | 4 +- .../serialization/SerializableDataTypes.kt | 94 ++++++++++--------- .../serialization/SerializableItemStack.kt | 58 +++++++----- 3 files changed, 83 insertions(+), 73 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt index 24656f1..b39fe4e 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/AttributeSerializer.kt @@ -1,6 +1,6 @@ package com.mineinabyss.idofront.serialization -import io.papermc.paper.component.item.ItemAttributeModifiers +import io.papermc.paper.datacomponent.item.ItemAttributeModifiers import kotlinx.serialization.EncodeDefault import kotlinx.serialization.EncodeDefault.Mode.NEVER import kotlinx.serialization.KSerializer @@ -9,12 +9,10 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import net.kyori.adventure.key.Key import org.bukkit.NamespacedKey import org.bukkit.attribute.Attribute import org.bukkit.attribute.AttributeModifier import org.bukkit.inventory.EquipmentSlotGroup -import java.util.* @Serializable @SerialName("SerializableAttribute") diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 9d6026e..d9cf971 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -1,11 +1,12 @@ package com.mineinabyss.idofront.serialization +import com.destroystokyo.paper.profile.PlayerProfile import io.papermc.paper.block.BlockPredicate -import io.papermc.paper.component.DataComponentType -import io.papermc.paper.component.DataComponentTypes -import io.papermc.paper.component.item.* -import io.papermc.paper.component.item.MapDecorations.DecorationEntry -import io.papermc.paper.component.item.Tool.Rule +import io.papermc.paper.datacomponent.item.MapDecorations.DecorationEntry +import io.papermc.paper.datacomponent.item.Tool.Rule +import io.papermc.paper.datacomponent.DataComponentType +import io.papermc.paper.datacomponent.DataComponentTypes +import io.papermc.paper.datacomponent.item.* import io.papermc.paper.registry.RegistryAccess import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey @@ -18,6 +19,7 @@ import net.kyori.adventure.util.TriState import org.bukkit.Color import org.bukkit.Registry import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.ItemType import org.bukkit.inventory.meta.trim.ArmorTrim import org.bukkit.map.MapCursor import org.bukkit.potion.PotionEffect @@ -38,12 +40,12 @@ object SerializableDataTypes { @Serializable data class Unbreakable(val shownInTooltip: Boolean = true) : DataType { - constructor(unbreakable: io.papermc.paper.component.item.Unbreakable) : this(unbreakable.showInTooltip()) + constructor(unbreakable: io.papermc.paper.datacomponent.item.Unbreakable) : this(unbreakable.showInTooltip()) override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.UNBREAKABLE, - io.papermc.paper.component.item.Unbreakable.unbreakable(shownInTooltip) + io.papermc.paper.datacomponent.item.Unbreakable.unbreakable(shownInTooltip) ) } } @@ -55,7 +57,7 @@ object SerializableDataTypes { val customEffects: List<@Serializable(PotionEffectSerializer::class) PotionEffect> = emptyList() ) : DataType { - constructor(potionContents: io.papermc.paper.component.item.PotionContents) : this( + constructor(potionContents: io.papermc.paper.datacomponent.item.PotionContents) : this( potionContents.potion(), potionContents.customColor(), potionContents.customEffects() @@ -64,8 +66,8 @@ object SerializableDataTypes { override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.POTION_CONTENTS, - io.papermc.paper.component.item.PotionContents.potionContents().potion(potionType).customColor(color) - .addAll(customEffects).build() + io.papermc.paper.datacomponent.item.PotionContents.potionContents().potion(potionType).customColor(color) + .addCustomEffects(customEffects).build() ) } } @@ -108,13 +110,13 @@ object SerializableDataTypes { @JvmInline value class ChargedProjectiles(private val projectiles: List) : DataType { constructor(vararg projectiles: ItemStack) : this(projectiles.map { it.toSerializable() }) - constructor(projectiles: io.papermc.paper.component.item.ChargedProjectiles) : this( + constructor(projectiles: io.papermc.paper.datacomponent.item.ChargedProjectiles) : this( projectiles.projectiles().map { it.toSerializable() }) override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.CHARGED_PROJECTILES, - io.papermc.paper.component.item.ChargedProjectiles.chargedProjectiles(projectiles.mapNotNull { it.toItemStackOrNull() }) + io.papermc.paper.datacomponent.item.ChargedProjectiles.chargedProjectiles(projectiles.mapNotNull { it.toItemStackOrNull() }) ) } } @@ -172,7 +174,7 @@ object SerializableDataTypes { @Serializable data class MapDecoration(val type: MapCursor.Type, val x: Double, val z: Double, val rotation: Float) { - constructor(entry: DecorationEntry) : this(entry.type(), entry.x(), entry.z(), entry.rotation()) + constructor(entry: MapDecorations.DecorationEntry) : this(entry.type(), entry.x(), entry.z(), entry.rotation()) val paperDecoration: DecorationEntry = DecorationEntry.of(type, x, z, rotation) companion object { @@ -187,7 +189,7 @@ object SerializableDataTypes { val defaultMiningSpeed: Float, val damagePerBlock: Int ) : BlockTags(), DataType { - constructor(tool: io.papermc.paper.component.item.Tool) : this( + constructor(tool: io.papermc.paper.datacomponent.item.Tool) : this( tool.rules().map(::Rule), tool.defaultMiningSpeed(), tool.damagePerBlock() @@ -195,7 +197,7 @@ object SerializableDataTypes { override fun setDataType(itemStack: ItemStack) { itemStack.setData( - DataComponentTypes.TOOL, io.papermc.paper.component.item.Tool.tool() + DataComponentTypes.TOOL, io.papermc.paper.datacomponent.item.Tool.tool() .damagePerBlock(damagePerBlock) .defaultMiningSpeed(defaultMiningSpeed) .addRules(rules.toPaperRules()) @@ -209,8 +211,8 @@ object SerializableDataTypes { val speed: Float? = null, val correctForDrops: TriState ) { - constructor(rule: io.papermc.paper.component.item.Tool.Rule) : this( - rule.blockTypes().map { it.key() }, + constructor(rule: io.papermc.paper.datacomponent.item.Tool.Rule) : this( + rule.blocks().map { it.key() }, rule.speed(), rule.correctForDrops() ) @@ -222,8 +224,7 @@ object SerializableDataTypes { val showInToolTip: Boolean = true, val modifiers: List ) : BlockTags(), DataType { - constructor(adventurePredicate: ItemAdventurePredicate) : - this(adventurePredicate.showInTooltip(), adventurePredicate.modifiers().map(::BlockPredicate)) + constructor(predicate: ItemAdventurePredicate) : this(predicate.showInTooltip(), predicate.predicates().map(::BlockPredicate)) override fun setDataType(itemStack: ItemStack) { itemStack.setData( @@ -243,8 +244,7 @@ object SerializableDataTypes { val showInToolTip: Boolean = true, val modifiers: List ) : BlockTags(), DataType { - constructor(adventurePredicate: ItemAdventurePredicate) : - this(adventurePredicate.showInTooltip(), adventurePredicate.modifiers().map(::BlockPredicate)) + constructor(predicate: ItemAdventurePredicate) : this(predicate.showInTooltip(), predicate.predicates().map(::BlockPredicate)) override fun setDataType(itemStack: ItemStack) { itemStack.setData( @@ -320,7 +320,7 @@ object SerializableDataTypes { val usingConvertsTo: SerializableItemStack? = null ) : DataType { - constructor(foodProperties: io.papermc.paper.component.item.FoodProperties) : this( + constructor(foodProperties: io.papermc.paper.datacomponent.item.FoodProperties) : this( foodProperties.nutrition(), foodProperties.saturation(), foodProperties.eatSeconds(), @@ -331,9 +331,9 @@ object SerializableDataTypes { override fun setDataType(itemStack: ItemStack) { itemStack.setData( - DataComponentTypes.FOOD, io.papermc.paper.component.item.FoodProperties.food() + DataComponentTypes.FOOD, io.papermc.paper.datacomponent.item.FoodProperties.food() .nutrition(nutrition).saturation(saturation).eatSeconds(eatSeconds).canAlwaysEat(canAlwaysEat) - .addAllEffects(effects.map { it.paperPossibleEffect }) + .addEffects(effects.map { it.paperPossibleEffect }) .usingConvertsTo(usingConvertsTo?.toItemStackOrNull()) ) } @@ -344,30 +344,16 @@ object SerializableDataTypes { val probability: Float = 1.0f ) { - val paperPossibleEffect: io.papermc.paper.component.item.FoodProperties.PossibleEffect = - io.papermc.paper.component.item.FoodProperties.PossibleEffect.of(effect, probability) + val paperPossibleEffect: io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect = + io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect.of(effect, probability) - constructor(possibleEffect: io.papermc.paper.component.item.FoodProperties.PossibleEffect) : this( + constructor(possibleEffect: io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect) : this( possibleEffect.effect(), possibleEffect.probability() ) } } - @Serializable - @JvmInline - value class CustomModelData(private val customModelData: Int) : DataType { - constructor(customModelData: io.papermc.paper.component.item.CustomModelData) : this(customModelData.data()) - - override fun setDataType(itemStack: ItemStack) { - itemStack.setData( - DataComponentTypes.CUSTOM_MODEL_DATA, - io.papermc.paper.component.item.CustomModelData.customModelData().customModelData(customModelData) - .build() - ) - } - } - @Serializable data class DyedColor( val color: @Serializable(ColorSerializer::class) Color, @@ -385,10 +371,10 @@ object SerializableDataTypes { value class MapColor( private val color: @Serializable(ColorSerializer::class) Color, ) : DataType { - constructor(mapItemColor: MapItemColor) : this(mapItemColor.mapColor()) + constructor(mapItemColor: MapItemColor) : this(mapItemColor.color()) override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.MAP_COLOR, MapItemColor.mapItemColor().mapColor(color).build()) + itemStack.setData(DataComponentTypes.MAP_COLOR, MapItemColor.mapItemColor().color(color).build()) } } @@ -423,7 +409,7 @@ object SerializableDataTypes { val jukeboxSong: @Serializable(KeySerializer::class) Key, val showInToolTip: Boolean = true ) : DataType { - constructor(jukeboxPlayable: io.papermc.paper.component.item.JukeboxPlayable) : + constructor(jukeboxPlayable: io.papermc.paper.datacomponent.item.JukeboxPlayable) : this(jukeboxPlayable.jukeboxSong().key(), jukeboxPlayable.showInTooltip()) override fun setDataType(itemStack: ItemStack) { @@ -431,8 +417,7 @@ object SerializableDataTypes { val jukeboxSong = jukeboxRegistry.get(jukeboxSong) ?: return itemStack.setData( DataComponentTypes.JUKEBOX_PLAYABLE, - io.papermc.paper.component.item.JukeboxPlayable.jukeboxPlayable().showInTooltip(showInToolTip) - .jukeboxSong(jukeboxSong) + io.papermc.paper.datacomponent.item.JukeboxPlayable.jukeboxPlayable(jukeboxSong).showInTooltip(showInToolTip) ) } } @@ -454,6 +439,23 @@ object SerializableDataTypes { } } + + @Serializable + data class PotDecorations( + val backItem: ItemType? = null, + val frontItem: ItemType? = null, + val leftItem: ItemType? = null, + val rightItem: ItemType? = null, + ) : DataType { + constructor(potDecorations: io.papermc.paper.datacomponent.item.PotDecorations) : + this(potDecorations.back(), potDecorations.front(), potDecorations.left(), potDecorations.right()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.POT_DECORATIONS, io.papermc.paper.datacomponent.item.PotDecorations.potDecorations(backItem, leftItem, rightItem, frontItem)) + } + } + + @Serializable object FireResistant diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index f4b003a..c8761fd 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -10,11 +10,10 @@ import com.mineinabyss.idofront.textcomponents.miniMsg import com.mineinabyss.idofront.textcomponents.serialize import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible -import io.papermc.paper.component.DataComponentTypes -import io.papermc.paper.component.item.ItemLore -import io.papermc.paper.component.item.MapDecorations -import io.papermc.paper.component.item.MapID -import io.papermc.paper.component.item.MapPostProcessing +import io.papermc.paper.datacomponent.DataComponentTypes +import io.papermc.paper.datacomponent.item.ItemLore +import io.papermc.paper.datacomponent.item.MapDecorations +import io.papermc.paper.item.MapPostProcessing import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems import kotlinx.serialization.Contextual @@ -45,16 +44,12 @@ typealias SerializableItemStack = @Serializable(with = SerializableItemStackSeri /** * A wrapper for [ItemStack] that uses [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization). * Allows for easy-to-use serialization to JSON (or YAML with kaml). - * - * Currently missing many things spigot's item serialization contains, but way cleaner to use! - * - * See [MiniMessage docs](https://docs.adventure.kyori.net/minimessage/format.html) for formatting info! */ @Serializable data class BaseSerializableItemStack( @EncodeDefault(NEVER) val type: @Serializable(with = MaterialByNameSerializer::class) Material? = null, @EncodeDefault(NEVER) val amount: Int? = null, - @EncodeDefault(NEVER) val customModelData: SerializableDataTypes.CustomModelData? = null, + @EncodeDefault(NEVER) val customModelData: Int? = null, @EncodeDefault(NEVER) @SerialName("itemName") private val _itemName: String? = null, // This is private as we only want to use itemName in configs @EncodeDefault(NEVER) @SerialName("customName") private val _customName: String? = null, @@ -64,7 +59,7 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val maxDamage: Int? = null, @EncodeDefault(NEVER) val enchantments: SerializableDataTypes.Enchantments? = null, @EncodeDefault(NEVER) val storedEnchantments: SerializableDataTypes.StoredEnchantments? = null, - @EncodeDefault(NEVER) val potionType: SerializableDataTypes.PotionContents? = null, + @EncodeDefault(NEVER) val potionContents: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, @EncodeDefault(NEVER) val tool: SerializableDataTypes.Tool? = null, @@ -91,6 +86,12 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val mapId: Int? = null, @EncodeDefault(NEVER) val mapPostProcessing: MapPostProcessing? = null, + // Block-specific DataTypes + @EncodeDefault(NEVER) val lock: String? = null, + @EncodeDefault(NEVER) val noteBlockSound: @Serializable(KeySerializer::class) Key? = null, + @EncodeDefault(NEVER) val profile: SerializableDataTypes.PotDecorations? = null, + @EncodeDefault(NEVER) val potDecorations: SerializableDataTypes.PotDecorations? = null, + @EncodeDefault(NEVER) val prefab: String? = null, @EncodeDefault(NEVER) val tag: String? = null, @@ -171,19 +172,21 @@ data class BaseSerializableItemStack( SerializableDataTypes.setData(applyTo, DataComponentTypes.ITEM_NAME, itemName) SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_NAME, customName) SerializableDataTypes.setData(applyTo, DataComponentTypes.LORE, lore?.let { ItemLore.lore(lore) }) - customModelData?.setDataType(applyTo) enchantments?.setDataType(applyTo) storedEnchantments?.setDataType(applyTo) - potionType?.setDataType(applyTo) + potionContents?.setDataType(applyTo) attributeModifiers?.setDataType(applyTo) + SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_MODEL_DATA, customModelData) SerializableDataTypes.setData(applyTo, DataComponentTypes.REPAIR_COST, repairCost) SerializableDataTypes.setData(applyTo, DataComponentTypes.DAMAGE, damage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) SerializableDataTypes.setData(applyTo, DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride) - //SerializableDataTypes.setData(applyTo, DataComponentTypes.RECIPES, recipes) + SerializableDataTypes.setData(applyTo, DataComponentTypes.MAP_ID, mapId) + SerializableDataTypes.setData(applyTo, DataComponentTypes.RECIPES, recipes) + unbreakable?.setDataType(applyTo) food?.setDataType(applyTo) tool?.setDataType(applyTo) @@ -195,10 +198,9 @@ data class BaseSerializableItemStack( bundleContents?.setDataType(applyTo) writableBook?.setDataType(applyTo) writtenBook?.setDataType(applyTo) + mapColor?.setDataType(applyTo) - mapId?.let { applyTo.setData(DataComponentTypes.MAP_ID, MapID.mapId().mapId(mapId).build()) } mapPostProcessing?.let { applyTo.setData(DataComponentTypes.MAP_POST_PROCESSING, it) } - mapColor?.setDataType(applyTo) mapDecorations?.let { applyTo.setData( DataComponentTypes.MAP_DECORATIONS, @@ -206,6 +208,10 @@ data class BaseSerializableItemStack( ) } + SerializableDataTypes.setData(applyTo, DataComponentTypes.LOCK, lock) + SerializableDataTypes.setData(applyTo, DataComponentTypes.NOTE_BLOCK_SOUND, noteBlockSound) + potDecorations?.setDataType(applyTo) + SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, hideAdditionalTooltip) @@ -242,9 +248,8 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { amount = amount.takeIf { it != 1 }, itemName = getData(DataComponentTypes.ITEM_NAME), customName = getData(DataComponentTypes.CUSTOM_NAME), - customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA)?.let(SerializableDataTypes::CustomModelData), + customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA), - unbreakable = getData(DataComponentTypes.UNBREAKABLE)?.let(SerializableDataTypes::Unbreakable), lore = getData(DataComponentTypes.LORE)?.lines(), damage = getData(DataComponentTypes.DAMAGE), maxDamage = getData(DataComponentTypes.MAX_DAMAGE), @@ -252,12 +257,14 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { rarity = getData(DataComponentTypes.RARITY), enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), repairCost = getData(DataComponentTypes.REPAIR_COST), - //recipes = getData(DataComponentTypes.RECIPES), + mapId = getData(DataComponentTypes.MAP_ID), + recipes = getData(DataComponentTypes.RECIPES), + unbreakable = getData(DataComponentTypes.UNBREAKABLE)?.let(SerializableDataTypes::Unbreakable), enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), storedEnchantments = getData(DataComponentTypes.STORED_ENCHANTMENTS)?.let(SerializableDataTypes::StoredEnchantments), attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), - potionType = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), + potionContents = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), dyedColor = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), @@ -269,11 +276,14 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { bundleContents = getData(DataComponentTypes.BUNDLE_CONTENTS)?.let(SerializableDataTypes::BundleContent), writableBook = getData(DataComponentTypes.WRITABLE_BOOK_CONTENT)?.let(SerializableDataTypes::WritableBook), writtenBook = getData(DataComponentTypes.WRITTEN_BOOK_CONTENT)?.let(SerializableDataTypes::WrittenBook), - - mapId = getData(DataComponentTypes.MAP_ID)?.id(), mapColor = getData(DataComponentTypes.MAP_COLOR)?.let(SerializableDataTypes::MapColor), + mapPostProcessing = getData(DataComponentTypes.MAP_POST_PROCESSING), - mapDecorations = getData(DataComponentTypes.MAP_DECORATIONS)?.let { it.decorations.map { e -> SerializableDataTypes.MapDecoration(e.value) } }, + mapDecorations = getData(DataComponentTypes.MAP_DECORATIONS)?.let { it.decorations.map { e -> SerializableDataTypes.MapDecoration(e.value) } }, + + lock = getData(DataComponentTypes.LOCK), + noteBlockSound = getData(DataComponentTypes.NOTE_BLOCK_SOUND), + potDecorations = getData(DataComponentTypes.POT_DECORATIONS)?.let(SerializableDataTypes::PotDecorations), fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, @@ -281,7 +291,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { creativeSlotLock = SerializableDataTypes.CreativeSlotLock.takeIf { hasData(DataComponentTypes.CREATIVE_SLOT_LOCK) }, intangibleProjectile = SerializableDataTypes.IntangibleProjectile.takeIf { hasData(DataComponentTypes.INTANGIBLE_PROJECTILE) }, - ) //TODO perhaps this should encode prefab too? + ) } private fun String.getSubRecipeIDs(): MutableList { From 64779fd16afbdb51092a2eabc053c76f3abc5b39 Mon Sep 17 00:00:00 2001 From: Boy Date: Fri, 1 Nov 2024 15:02:56 +0100 Subject: [PATCH 12/15] feat: bump to 1.21.3, add useCooldown, useRemainder, consumable, equippable, itemModel, tooltipStyle, repairable, enchantable, damageResistant, deathProtection & glider components --- build.gradle.kts | 1 + gradle/libs.versions.toml | 4 +- ...neinabyss.conventions.cartridge.gradle.kts | 2 +- ...mineinabyss.conventions.papermc.gradle.kts | 1 + idofront-serializers/build.gradle.kts | 2 +- .../serialization/SerializableDataTypes.kt | 253 +++++++++++++++--- .../serialization/SerializableItemStack.kt | 82 +++--- 7 files changed, 277 insertions(+), 68 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 43086c2..3552cb6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,7 @@ subprojects { maven("https://repo.mineinabyss.com/releases") maven("https://repo.mineinabyss.com/snapshots") maven("https://erethon.de/repo/") + mavenLocal() maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.spaceio.xyz/repository/maven-snapshots/") maven("https://jitpack.io") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a147a1c..ff820e1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ ktor = "2.3.11" logback = "1.5.9" mccoroutine = "2.20.0" # @pin -minecraft = "1.21.1-R0.1-SNAPSHOT" +minecraft = "1.21.3-R0.1-SNAPSHOT" mockbukkit = "3.133.0" mockk = "1.13.13" modelengine = "R4.0.7" @@ -78,7 +78,7 @@ minecraft-mccoroutine = { module = "com.github.shynixn.mccoroutine:mccoroutine-b minecraft-mccoroutine-core = { module = "com.github.shynixn.mccoroutine:mccoroutine-bukkit-core", version.ref = "mccoroutine" } minecraft-mockbukkit = { module = "com.github.seeseemelk:MockBukkit-v1.21", version.ref = "mockbukkit" } minecraft-papermc = { module = "io.papermc.paper:paper-api", version.ref = "minecraft" } -minecraft-cartridge = { module = "com.mineinabyss.cartridge:cartridge-api", version.ref = "minecraft" } +#minecraft-cartridge = { module = "com.mineinabyss.cartridge:cartridge-api", version.ref = "minecraft" } minecraft-plugin-fawe-bukkit = { module = "com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit", version.ref = "fawe" } minecraft-plugin-fawe-core = { module = "com.fastasyncworldedit:FastAsyncWorldEdit-Core", version.ref = "fawe" } minecraft-plugin-itemsadder = { module = "com.github.LoneDev6:api-itemsadder", version.ref = "itemsadder" } diff --git a/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts index 4805414..97de082 100644 --- a/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts +++ b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.cartridge.gradle.kts @@ -10,7 +10,7 @@ repositories { } dependencies { - compileOnly(libs.findLibrary("minecraft-cartridge").get()) + compileOnly(libs.findLibrary("minecraft-papermc").get()) } tasks { diff --git a/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.papermc.gradle.kts b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.papermc.gradle.kts index 8f9482b..6f10883 100644 --- a/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.papermc.gradle.kts +++ b/idofront-gradle/src/main/kotlin/com.mineinabyss.conventions.papermc.gradle.kts @@ -5,6 +5,7 @@ plugins { val libs = idofrontLibsRef repositories { + mavenLocal() maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven("https://repo.papermc.io/repository/maven-public/") } diff --git a/idofront-serializers/build.gradle.kts b/idofront-serializers/build.gradle.kts index 1779659..d4bb818 100644 --- a/idofront-serializers/build.gradle.kts +++ b/idofront-serializers/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") - id("com.mineinabyss.conventions.cartridge") + id("com.mineinabyss.conventions.papermc") id("com.mineinabyss.conventions.publication") id("com.mineinabyss.conventions.testing") alias(libs.plugins.kotlinx.serialization) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index d9cf971..5c99a2c 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -1,15 +1,17 @@ package com.mineinabyss.idofront.serialization -import com.destroystokyo.paper.profile.PlayerProfile +import com.mineinabyss.idofront.serialization.SerializableDataTypes.ConsumeEffect.ClearAllEffectsConsumeEffect.toSerializable import io.papermc.paper.block.BlockPredicate -import io.papermc.paper.datacomponent.item.MapDecorations.DecorationEntry -import io.papermc.paper.datacomponent.item.Tool.Rule import io.papermc.paper.datacomponent.DataComponentType import io.papermc.paper.datacomponent.DataComponentTypes import io.papermc.paper.datacomponent.item.* +import io.papermc.paper.datacomponent.item.MapDecorations.DecorationEntry +import io.papermc.paper.datacomponent.item.Tool.Rule +import io.papermc.paper.datacomponent.item.consumable.* import io.papermc.paper.registry.RegistryAccess import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.set.RegistryKeySet import io.papermc.paper.registry.set.RegistrySet import io.papermc.paper.registry.tag.TagKey import kotlinx.serialization.Serializable @@ -18,11 +20,14 @@ import net.kyori.adventure.text.Component import net.kyori.adventure.util.TriState import org.bukkit.Color import org.bukkit.Registry +import org.bukkit.entity.EntityType +import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemType import org.bukkit.inventory.meta.trim.ArmorTrim import org.bukkit.map.MapCursor import org.bukkit.potion.PotionEffect +import org.bukkit.potion.PotionEffectType object SerializableDataTypes { @@ -50,6 +55,32 @@ object SerializableDataTypes { } } + @Serializable + @JvmInline + value class CustomModelData(val customModelData: Int) : DataType { + constructor(customModelData: io.papermc.paper.datacomponent.item.CustomModelData) : this(customModelData.id()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CUSTOM_MODEL_DATA, + io.papermc.paper.datacomponent.item.CustomModelData.customModelData(customModelData) + ) + } + } + + /*@Serializable + @JvmInline + value class LockCode(val lockCode: Int) : DataType { + constructor(customModelData: io.papermc.paper.datacomponent.item.CustomModelData) : this(customModelData.id()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CUSTOM_MODEL_DATA, + io.papermc.paper.datacomponent.item.LockCode (customModelData) + ) + } + }*/ + @Serializable data class PotionContents( val potionType: @Serializable(PotionTypeSerializer::class) org.bukkit.potion.PotionType?, @@ -183,6 +214,26 @@ object SerializableDataTypes { } } + @Serializable + @JvmInline + value class Enchantable(val enchantable: Int) : DataType { + constructor(enchantable: io.papermc.paper.datacomponent.item.Enchantable) : this(enchantable.value()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.ENCHANTABLE, io.papermc.paper.datacomponent.item.Enchantable.enchantable(enchantable)) + } + } + + @Serializable + @JvmInline + value class Repairable(val repairable: List) : DataType { + constructor(repairable: io.papermc.paper.datacomponent.item.Repairable) : this(repairable.types().resolve(Registry.ITEM).toList()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.REPAIRABLE, io.papermc.paper.datacomponent.item.Repairable.repairable(RegistrySet.keySetFromValues(RegistryKey.ITEM, repairable))) + } + } + @Serializable data class Tool( val rules: List = emptyList(), @@ -268,12 +319,12 @@ object SerializableDataTypes { val blockTagKeys = rule.blockTypes.map { TagKey.create(RegistryKey.BLOCK, it) }.filter(Registry.BLOCK::hasTag) blockTagKeys.map(Registry.BLOCK::getTag).forEach { blockTag -> - rules += Rule.of(blockTag, rule.speed, rule.correctForDrops) + rules += Rule.rule(blockTag, rule.speed, rule.correctForDrops) } val blockKeys = rule.blockTypes.filter { Registry.BLOCK.get(it) != null } .map { TypedKey.create(RegistryKey.BLOCK, it.key()) } val keySet = RegistrySet.keySet(RegistryKey.BLOCK, blockKeys) - rules += Rule.of(keySet, rule.speed, rule.correctForDrops) + rules += Rule.rule(keySet, rule.speed, rule.correctForDrops) } return rules @@ -310,46 +361,127 @@ object SerializableDataTypes { } } + @Serializable + sealed interface ConsumeEffect { + + fun io.papermc.paper.datacomponent.item.consumable.ConsumeEffect.toSerializable() = when (this) { + is ApplyStatusEffectsConsumeEffect -> ApplyEffectsConsumeEffect(effects(), probability()) + is RemoveStatusEffectsConsumeEffect -> RemoveEffectsConsumeEffect(removeEffects().resolve(Registry.POTION_EFFECT_TYPE).toList()) + is TeleportRandomlyConsumeEffect -> TeleportConsumeEffect(diameter()) + is io.papermc.paper.datacomponent.item.consumable.PlaySoundConsumeEffect -> PlaySoundConsumeEffect(sound()) + is ClearAllStatusEffectsConsumeEffect -> ClearAllEffectsConsumeEffect + else -> ApplyEffectsConsumeEffect(emptyList(), 0f) + } + + fun toPaperEffect() : io.papermc.paper.datacomponent.item.consumable.ConsumeEffect { + return when (this) { + is ApplyEffectsConsumeEffect -> ApplyStatusEffectsConsumeEffect.applyStatusEffects(effects, probability) + is RemoveEffectsConsumeEffect -> RemoveStatusEffectsConsumeEffect.removeEffects(RegistrySet.keySetFromValues(RegistryKey.MOB_EFFECT, effects)) + is TeleportConsumeEffect -> TeleportRandomlyConsumeEffect.teleportRandomlyEffect(diameter) + is PlaySoundConsumeEffect -> io.papermc.paper.datacomponent.item.consumable.PlaySoundConsumeEffect.playSoundConsumeEffect(key) + is ClearAllEffectsConsumeEffect -> ClearAllStatusEffectsConsumeEffect.clearAllStatusEffects() + } + } + + @Serializable + data class ApplyEffectsConsumeEffect( + val effects: List<@Serializable(PotionEffectSerializer::class) PotionEffect>, + val probability: Float = 1.0f + ): ConsumeEffect + + @Serializable + data class RemoveEffectsConsumeEffect(val effects: List<@Serializable(PotionEffectTypeSerializer::class) PotionEffectType>): ConsumeEffect + + @Serializable + data class TeleportConsumeEffect(val diameter: Float = 16.0f): ConsumeEffect + + @Serializable + data class PlaySoundConsumeEffect(val key: @Serializable(KeySerializer::class) Key) : ConsumeEffect + + @Serializable + object ClearAllEffectsConsumeEffect : ConsumeEffect, ClearAllStatusEffectsConsumeEffect + } + + @Serializable + @JvmInline + value class UseRemainder(val useRemainder: SerializableItemStack) : DataType { + constructor(useRemainder: io.papermc.paper.datacomponent.item.UseRemainder) : this(useRemainder.transformInto().toSerializable()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.USE_REMAINDER, + io.papermc.paper.datacomponent.item.UseRemainder.useRemainder(useRemainder.toItemStack()) + ) + } + } + + @Serializable + @JvmInline + value class DamageResistant(val damageResistant: @Serializable(KeySerializer::class) Key) : DataType { + constructor(damageResistant: io.papermc.paper.datacomponent.item.DamageResistant) : this(damageResistant.types().key()) + + private val damageTypeRegistry get() = RegistryAccess.registryAccess().getRegistry(RegistryKey.DAMAGE_TYPE) + + init { + require(damageTypeRegistry.get(damageResistant) != null) { "${damageResistant.asString()} was not a valid DamageType"} + } + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.DAMAGE_RESISTANT, io.papermc.paper.datacomponent.item.DamageResistant.damageResistant(TagKey.create(RegistryKey.DAMAGE_TYPE, damageResistant))) + } + } + + @Serializable + class DeathProtection(val consumeEffects: List) : DataType { + constructor(deathProtection: io.papermc.paper.datacomponent.item.DeathProtection) : this(deathProtection.deathEffects().map { it.toSerializable() }) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.DEATH_PROTECTION, io.papermc.paper.datacomponent.item.DeathProtection.deathProtection(consumeEffects.map { it.toPaperEffect() })) + } + } + + @Serializable + data class Consumable( + val seconds: Float, + val sound: @Serializable(KeySerializer::class) Key?, + val animation: ItemUseAnimation, + val particles: Boolean, + val consumeEffects: List + ) : DataType { + constructor(consumable: io.papermc.paper.datacomponent.item.Consumable) : this( + consumable.consumeSeconds(), + consumable.sound(), + consumable.animation(), + consumable.hasConsumeParticles(), + consumable.consumeEffects().map { it.toSerializable() } + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.CONSUMABLE, io.papermc.paper.datacomponent.item.Consumable.consumable() + .consumeSeconds(seconds).sound(sound).animation(animation).hasConsumeParticles(particles) + .addEffects(consumeEffects.map { it.toPaperEffect() }) + ) + } + } + @Serializable data class FoodProperties( val nutrition: Int, val saturation: Float, - val eatSeconds: Float = 1.6f, - val canAlwaysEat: Boolean = false, - val effects: List = emptyList(), - val usingConvertsTo: SerializableItemStack? = null + val canAlwaysEat: Boolean = false ) : DataType { constructor(foodProperties: io.papermc.paper.datacomponent.item.FoodProperties) : this( foodProperties.nutrition(), foodProperties.saturation(), - foodProperties.eatSeconds(), - foodProperties.canAlwaysEat(), - foodProperties.effects().map(::PossibleEffect), - foodProperties.usingConvertsTo()?.toSerializable() + foodProperties.canAlwaysEat() ) override fun setDataType(itemStack: ItemStack) { itemStack.setData( DataComponentTypes.FOOD, io.papermc.paper.datacomponent.item.FoodProperties.food() - .nutrition(nutrition).saturation(saturation).eatSeconds(eatSeconds).canAlwaysEat(canAlwaysEat) - .addEffects(effects.map { it.paperPossibleEffect }) - .usingConvertsTo(usingConvertsTo?.toItemStackOrNull()) - ) - } - - @Serializable - data class PossibleEffect( - val effect: @Serializable(PotionEffectSerializer::class) PotionEffect, - val probability: Float = 1.0f - ) { - - val paperPossibleEffect: io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect = - io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect.of(effect, probability) - - constructor(possibleEffect: io.papermc.paper.datacomponent.item.FoodProperties.PossibleEffect) : this( - possibleEffect.effect(), - possibleEffect.probability() + .nutrition(nutrition).saturation(saturation).canAlwaysEat(canAlwaysEat) ) } } @@ -379,6 +511,34 @@ object SerializableDataTypes { } + @Serializable + data class Equippable( + val slot: EquipmentSlot, + val model: @Serializable(KeySerializer::class) Key? = null, + val cameraOverlay: @Serializable(KeySerializer::class) Key? = null, + val equipSound: @Serializable(KeySerializer::class) Key? = null, + val allowedEntities: List? = EntityType.entries, + val damageOnHurt: Boolean = true, + val swappable: Boolean = true, + val dispensable: Boolean = true, + + ) : DataType { + constructor(equippable: io.papermc.paper.datacomponent.item.Equippable) : this( + equippable.slot(), equippable.model(), equippable.cameraOverlay(), equippable.equipSound(), + equippable.allowedEntities()?.resolve(Registry.ENTITY_TYPE)?.toList(), + equippable.damageOnHurt(), equippable.swappable(), equippable.dispensable() + ) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData( + DataComponentTypes.EQUIPPABLE, + io.papermc.paper.datacomponent.item.Equippable.equippable(slot).model(model).cameraOverlay(cameraOverlay) + .equipSound(equipSound).allowedEntities(allowedEntities?.let { RegistrySet.keySetFromValues(RegistryKey.ENTITY_TYPE, it) }) + .damageOnHurt(damageOnHurt).swappable(swappable).dispensable(dispensable) + ) + } + } + @Serializable class Trim( val material: @Serializable(KeySerializer::class) Key, @@ -439,6 +599,24 @@ object SerializableDataTypes { } } + @Serializable + data class UseCooldown( + val seconds: Float, + val group: @Serializable(KeySerializer::class) Key? = null + ) : DataType { + + init { + require(seconds <= 0) { "Seconds cannot be below 0" } + } + + constructor(cooldown: io.papermc.paper.datacomponent.item.UseCooldown) : this(cooldown.seconds(), cooldown.cooldownGroup()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.USE_COOLDOWN, io.papermc.paper.datacomponent.item.UseCooldown.useCooldown(seconds).cooldownGroup(group).build()) + } + } + + @Serializable data class PotDecorations( @@ -455,9 +633,15 @@ object SerializableDataTypes { } } - @Serializable - object FireResistant + @JvmInline + value class MapId(val mapId: Int) : DataType { + constructor(mapId: io.papermc.paper.datacomponent.item.MapId) : this(mapId.id()) + + override fun setDataType(itemStack: ItemStack) { + itemStack.setData(DataComponentTypes.MAP_ID, io.papermc.paper.datacomponent.item.MapId.mapId(mapId)) + } + } @Serializable object HideToolTip @@ -471,4 +655,7 @@ object SerializableDataTypes { @Serializable object IntangibleProjectile + @Serializable + object Glider + } \ No newline at end of file diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index c8761fd..4578426 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -11,8 +11,7 @@ import com.mineinabyss.idofront.textcomponents.serialize import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible import io.papermc.paper.datacomponent.DataComponentTypes -import io.papermc.paper.datacomponent.item.ItemLore -import io.papermc.paper.datacomponent.item.MapDecorations +import io.papermc.paper.datacomponent.item.* import io.papermc.paper.item.MapPostProcessing import io.th0rgal.oraxen.OraxenPlugin import io.th0rgal.oraxen.api.OraxenItems @@ -38,6 +37,7 @@ import org.bukkit.inventory.meta.components.JukeboxPlayableComponent import org.bukkit.inventory.meta.components.ToolComponent import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionType +import sun.font.Decoration typealias SerializableItemStack = @Serializable(with = SerializableItemStackSerializer::class) BaseSerializableItemStack @@ -49,11 +49,15 @@ typealias SerializableItemStack = @Serializable(with = SerializableItemStackSeri data class BaseSerializableItemStack( @EncodeDefault(NEVER) val type: @Serializable(with = MaterialByNameSerializer::class) Material? = null, @EncodeDefault(NEVER) val amount: Int? = null, - @EncodeDefault(NEVER) val customModelData: Int? = null, + @EncodeDefault(NEVER) val customModelData: SerializableDataTypes.CustomModelData? = null, + @EncodeDefault(NEVER) val itemModel: @Serializable(KeySerializer::class) Key? = null, + @EncodeDefault(NEVER) val tooltipStyle: @Serializable(KeySerializer::class) Key? = null, + @EncodeDefault(NEVER) @SerialName("itemName") private val _itemName: String? = null, // This is private as we only want to use itemName in configs @EncodeDefault(NEVER) @SerialName("customName") private val _customName: String? = null, @EncodeDefault(NEVER) @SerialName("lore") private val _lore: List? = null, + @EncodeDefault(NEVER) val unbreakable: SerializableDataTypes.Unbreakable? = null, @EncodeDefault(NEVER) val damage: Int? = null, @EncodeDefault(NEVER) val maxDamage: Int? = null, @@ -61,33 +65,38 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val storedEnchantments: SerializableDataTypes.StoredEnchantments? = null, @EncodeDefault(NEVER) val potionContents: SerializableDataTypes.PotionContents? = null, @EncodeDefault(NEVER) val attributeModifiers: SerializableDataTypes.AttributeModifiers? = null, + @EncodeDefault(NEVER) val useCooldown: SerializableDataTypes.UseCooldown? = null, + @EncodeDefault(NEVER) val useRemainder: SerializableDataTypes.UseRemainder? = null, + @EncodeDefault(NEVER) val consumable: SerializableDataTypes.Consumable? = null, @EncodeDefault(NEVER) val food: SerializableDataTypes.FoodProperties? = null, @EncodeDefault(NEVER) val tool: SerializableDataTypes.Tool? = null, - @EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null, - @EncodeDefault(NEVER) val hideTooltip: Boolean? = null, - @EncodeDefault(NEVER) val isFireResistant: Boolean? = null, + @EncodeDefault(NEVER) val enchantable: SerializableDataTypes.Enchantable? = null, + @EncodeDefault(NEVER) val repairable: SerializableDataTypes.Repairable? = null, @EncodeDefault(NEVER) val canPlaceOn: SerializableDataTypes.CanPlaceOn? = null, @EncodeDefault(NEVER) val canBreak: SerializableDataTypes.CanBreak? = null, @EncodeDefault(NEVER) val dyedColor: SerializableDataTypes.DyedColor? = null, @EncodeDefault(NEVER) val mapColor: SerializableDataTypes.MapColor? = null, @EncodeDefault(NEVER) val mapDecorations: List? = null, + @EncodeDefault(NEVER) val equippable: SerializableDataTypes.Equippable? = null, @EncodeDefault(NEVER) val trim: SerializableDataTypes.Trim? = null, @EncodeDefault(NEVER) val jukeboxPlayable: SerializableDataTypes.JukeboxPlayable? = null, @EncodeDefault(NEVER) val chargedProjectiles: SerializableDataTypes.ChargedProjectiles? = null, @EncodeDefault(NEVER) val bundleContents: SerializableDataTypes.BundleContent? = null, @EncodeDefault(NEVER) val writableBook: SerializableDataTypes.WritableBook? = null, @EncodeDefault(NEVER) val writtenBook: SerializableDataTypes.WrittenBook? = null, + @EncodeDefault(NEVER) val damageResistant: SerializableDataTypes.DamageResistant? = null, + @EncodeDefault(NEVER) val deathProtection: SerializableDataTypes.DeathProtection? = null, @EncodeDefault(NEVER) val recipes: List<@Serializable(KeySerializer::class) Key>? = null, @EncodeDefault(NEVER) val enchantmentGlintOverride: Boolean? = null, @EncodeDefault(NEVER) val maxStackSize: Int? = null, @EncodeDefault(NEVER) val rarity: ItemRarity? = null, @EncodeDefault(NEVER) val repairCost: Int? = null, - @EncodeDefault(NEVER) val mapId: Int? = null, + @EncodeDefault(NEVER) val mapId: SerializableDataTypes.MapId? = null, @EncodeDefault(NEVER) val mapPostProcessing: MapPostProcessing? = null, // Block-specific DataTypes - @EncodeDefault(NEVER) val lock: String? = null, + //@EncodeDefault(NEVER) val lock: String? = null, @EncodeDefault(NEVER) val noteBlockSound: @Serializable(KeySerializer::class) Key? = null, @EncodeDefault(NEVER) val profile: SerializableDataTypes.PotDecorations? = null, @EncodeDefault(NEVER) val potDecorations: SerializableDataTypes.PotDecorations? = null, @@ -98,11 +107,11 @@ data class BaseSerializableItemStack( @EncodeDefault(NEVER) val recipeOptions: List = listOf(), // Unvalued DataTypes - @EncodeDefault(NEVER) @Contextual val fireResistant: SerializableDataTypes.FireResistant? = null, @EncodeDefault(NEVER) @Contextual val hideTooltip: SerializableDataTypes.HideToolTip? = null, @EncodeDefault(NEVER) @Contextual val hideAdditionalTooltip: SerializableDataTypes.HideAdditionalTooltip? = null, @EncodeDefault(NEVER) @Contextual val creativeSlotLock: SerializableDataTypes.CreativeSlotLock? = null, @EncodeDefault(NEVER) @Contextual val intangibleProjectile: SerializableDataTypes.IntangibleProjectile? = null, + @EncodeDefault(NEVER) @Contextual val glider: SerializableDataTypes.Glider? = null, // Third-party plugins @EncodeDefault(NEVER) val crucibleItem: String? = null, @@ -112,20 +121,15 @@ data class BaseSerializableItemStack( private fun Component.removeItalics() = Component.text().decoration(TextDecoration.ITALIC, false).build().append(this) - @Transient - val itemName = _itemName?.miniMsg() - @Transient - val customName = _customName?.miniMsg() - @Transient - val lore = _lore?.map { it.miniMsg() } + @Transient val itemName = _itemName?.miniMsg() + @Transient val customName = _customName?.miniMsg() + @Transient val lore = _lore?.map { it.miniMsg() } /** * Converts this serialized item's data to an [ItemStack], optionally applying the changes to an * [existing item][applyTo]. */ - fun toItemStack( - applyTo: ItemStack = ItemStack(type ?: Material.AIR), - ): ItemStack { + fun toItemStack(applyTo: ItemStack = ItemStack.of(type ?: Material.AIR)): ItemStack { // Import ItemStack from Crucible crucibleItem?.let { id -> if (Plugins.isEnabled()) { @@ -171,34 +175,43 @@ data class BaseSerializableItemStack( SerializableDataTypes.setData(applyTo, DataComponentTypes.ITEM_NAME, itemName) SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_NAME, customName) - SerializableDataTypes.setData(applyTo, DataComponentTypes.LORE, lore?.let { ItemLore.lore(lore) }) + SerializableDataTypes.setData(applyTo, DataComponentTypes.LORE, lore?.let(ItemLore::lore)) + SerializableDataTypes.setData(applyTo, DataComponentTypes.ITEM_MODEL, itemModel) + SerializableDataTypes.setData(applyTo, DataComponentTypes.TOOLTIP_STYLE, tooltipStyle) enchantments?.setDataType(applyTo) storedEnchantments?.setDataType(applyTo) potionContents?.setDataType(applyTo) attributeModifiers?.setDataType(applyTo) + customModelData?.setDataType(applyTo) - SerializableDataTypes.setData(applyTo, DataComponentTypes.CUSTOM_MODEL_DATA, customModelData) SerializableDataTypes.setData(applyTo, DataComponentTypes.REPAIR_COST, repairCost) SerializableDataTypes.setData(applyTo, DataComponentTypes.DAMAGE, damage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_DAMAGE, maxDamage) SerializableDataTypes.setData(applyTo, DataComponentTypes.MAX_STACK_SIZE, maxStackSize) SerializableDataTypes.setData(applyTo, DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride) - SerializableDataTypes.setData(applyTo, DataComponentTypes.MAP_ID, mapId) SerializableDataTypes.setData(applyTo, DataComponentTypes.RECIPES, recipes) unbreakable?.setDataType(applyTo) + useCooldown?.setDataType(applyTo) + useRemainder?.setDataType(applyTo) + consumable?.setDataType(applyTo) food?.setDataType(applyTo) tool?.setDataType(applyTo) + enchantable?.setDataType(applyTo) + repairable?.setDataType(applyTo) canPlaceOn?.setDataType(applyTo) canBreak?.setDataType(applyTo) + equippable?.setDataType(applyTo) trim?.setDataType(applyTo) jukeboxPlayable?.setDataType(applyTo) chargedProjectiles?.setDataType(applyTo) bundleContents?.setDataType(applyTo) writableBook?.setDataType(applyTo) writtenBook?.setDataType(applyTo) + damageResistant?.setDataType(applyTo) mapColor?.setDataType(applyTo) + mapId?.setDataType(applyTo) mapPostProcessing?.let { applyTo.setData(DataComponentTypes.MAP_POST_PROCESSING, it) } mapDecorations?.let { @@ -208,11 +221,10 @@ data class BaseSerializableItemStack( ) } - SerializableDataTypes.setData(applyTo, DataComponentTypes.LOCK, lock) + //SerializableDataTypes.setData(applyTo, DataComponentTypes.LOCK, LockCode) SerializableDataTypes.setData(applyTo, DataComponentTypes.NOTE_BLOCK_SOUND, noteBlockSound) potDecorations?.setDataType(applyTo) - SerializableDataTypes.setData(applyTo, DataComponentTypes.FIRE_RESISTANT, fireResistant) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_TOOLTIP, hideTooltip) SerializableDataTypes.setData(applyTo, DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, hideAdditionalTooltip) SerializableDataTypes.setData(applyTo, DataComponentTypes.CREATIVE_SLOT_LOCK, creativeSlotLock) @@ -246,46 +258,54 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) { SerializableItemStack( type = type, amount = amount.takeIf { it != 1 }, - itemName = getData(DataComponentTypes.ITEM_NAME), - customName = getData(DataComponentTypes.CUSTOM_NAME), - customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA), + _itemName = getData(DataComponentTypes.ITEM_NAME)?.serialize(), + _customName = getData(DataComponentTypes.CUSTOM_NAME)?.serialize(), + _lore = getData(DataComponentTypes.LORE)?.lines()?.map { it.serialize() }, - lore = getData(DataComponentTypes.LORE)?.lines(), + itemModel = getData(DataComponentTypes.ITEM_MODEL), + tooltipStyle = getData(DataComponentTypes.TOOLTIP_STYLE), damage = getData(DataComponentTypes.DAMAGE), maxDamage = getData(DataComponentTypes.MAX_DAMAGE), maxStackSize = getData(DataComponentTypes.MAX_STACK_SIZE), rarity = getData(DataComponentTypes.RARITY), enchantmentGlintOverride = getData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE), repairCost = getData(DataComponentTypes.REPAIR_COST), - mapId = getData(DataComponentTypes.MAP_ID), recipes = getData(DataComponentTypes.RECIPES), + customModelData = getData(DataComponentTypes.CUSTOM_MODEL_DATA)?.let(SerializableDataTypes::CustomModelData), unbreakable = getData(DataComponentTypes.UNBREAKABLE)?.let(SerializableDataTypes::Unbreakable), enchantments = getData(DataComponentTypes.ENCHANTMENTS)?.let(SerializableDataTypes::Enchantments), storedEnchantments = getData(DataComponentTypes.STORED_ENCHANTMENTS)?.let(SerializableDataTypes::StoredEnchantments), attributeModifiers = getData(DataComponentTypes.ATTRIBUTE_MODIFIERS)?.let(SerializableDataTypes::AttributeModifiers), potionContents = getData(DataComponentTypes.POTION_CONTENTS)?.let(SerializableDataTypes::PotionContents), dyedColor = getData(DataComponentTypes.DYED_COLOR)?.let(SerializableDataTypes::DyedColor), + useCooldown = getData(DataComponentTypes.USE_COOLDOWN)?.let(SerializableDataTypes::UseCooldown), + useRemainder = getData(DataComponentTypes.USE_REMAINDER)?.let(SerializableDataTypes::UseRemainder), + consumable = getData(DataComponentTypes.CONSUMABLE)?.let(SerializableDataTypes::Consumable), food = getData(DataComponentTypes.FOOD)?.let(SerializableDataTypes::FoodProperties), tool = getData(DataComponentTypes.TOOL)?.let(SerializableDataTypes::Tool), + enchantable = getData(DataComponentTypes.ENCHANTABLE)?.let(SerializableDataTypes::Enchantable), + repairable = getData(DataComponentTypes.REPAIRABLE)?.let(SerializableDataTypes::Repairable), canPlaceOn = getData(DataComponentTypes.CAN_PLACE_ON)?.let(SerializableDataTypes::CanPlaceOn), canBreak = getData(DataComponentTypes.CAN_BREAK)?.let(SerializableDataTypes::CanBreak), + equippable = getData(DataComponentTypes.EQUIPPABLE)?.let(SerializableDataTypes::Equippable), trim = getData(DataComponentTypes.TRIM)?.let(SerializableDataTypes::Trim), jukeboxPlayable = getData(DataComponentTypes.JUKEBOX_PLAYABLE)?.let(SerializableDataTypes::JukeboxPlayable), chargedProjectiles = getData(DataComponentTypes.CHARGED_PROJECTILES)?.let(SerializableDataTypes::ChargedProjectiles), bundleContents = getData(DataComponentTypes.BUNDLE_CONTENTS)?.let(SerializableDataTypes::BundleContent), writableBook = getData(DataComponentTypes.WRITABLE_BOOK_CONTENT)?.let(SerializableDataTypes::WritableBook), writtenBook = getData(DataComponentTypes.WRITTEN_BOOK_CONTENT)?.let(SerializableDataTypes::WrittenBook), + damageResistant = getData(DataComponentTypes.DAMAGE_RESISTANT)?.let(SerializableDataTypes::DamageResistant), + deathProtection = getData(DataComponentTypes.DEATH_PROTECTION)?.let(SerializableDataTypes::DeathProtection), mapColor = getData(DataComponentTypes.MAP_COLOR)?.let(SerializableDataTypes::MapColor), + mapId = getData(DataComponentTypes.MAP_ID)?.let(SerializableDataTypes::MapId), mapPostProcessing = getData(DataComponentTypes.MAP_POST_PROCESSING), - mapDecorations = getData(DataComponentTypes.MAP_DECORATIONS)?.let { it.decorations.map { e -> SerializableDataTypes.MapDecoration(e.value) } }, + mapDecorations = getData(DataComponentTypes.MAP_DECORATIONS)?.decorations()?.values?.map(SerializableDataTypes::MapDecoration), - lock = getData(DataComponentTypes.LOCK), noteBlockSound = getData(DataComponentTypes.NOTE_BLOCK_SOUND), potDecorations = getData(DataComponentTypes.POT_DECORATIONS)?.let(SerializableDataTypes::PotDecorations), - fireResistant = SerializableDataTypes.FireResistant.takeIf { hasData(DataComponentTypes.FIRE_RESISTANT) }, hideTooltip = SerializableDataTypes.HideToolTip.takeIf { hasData(DataComponentTypes.HIDE_TOOLTIP) }, hideAdditionalTooltip = SerializableDataTypes.HideAdditionalTooltip.takeIf { hasData(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) }, creativeSlotLock = SerializableDataTypes.CreativeSlotLock.takeIf { hasData(DataComponentTypes.CREATIVE_SLOT_LOCK) }, From 4d675700466d0f4cb5b8db14a81930a1bbdb3c7e Mon Sep 17 00:00:00 2001 From: Boy Date: Sat, 2 Nov 2024 14:54:53 +0100 Subject: [PATCH 13/15] fix: swap ItemType for KeySerializer --- .../serialization/SerializableDataTypes.kt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 5c99a2c..3077165 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -11,7 +11,6 @@ import io.papermc.paper.datacomponent.item.consumable.* import io.papermc.paper.registry.RegistryAccess import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey -import io.papermc.paper.registry.set.RegistryKeySet import io.papermc.paper.registry.set.RegistrySet import io.papermc.paper.registry.tag.TagKey import kotlinx.serialization.Serializable @@ -23,7 +22,6 @@ import org.bukkit.Registry import org.bukkit.entity.EntityType import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.ItemType import org.bukkit.inventory.meta.trim.ArmorTrim import org.bukkit.map.MapCursor import org.bukkit.potion.PotionEffect @@ -226,11 +224,11 @@ object SerializableDataTypes { @Serializable @JvmInline - value class Repairable(val repairable: List) : DataType { - constructor(repairable: io.papermc.paper.datacomponent.item.Repairable) : this(repairable.types().resolve(Registry.ITEM).toList()) + value class Repairable(val repairable: List<@Serializable(KeySerializer::class) Key>) : DataType { + constructor(repairable: io.papermc.paper.datacomponent.item.Repairable) : this(repairable.types().resolve(Registry.ITEM).map { it.key() }) override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.REPAIRABLE, io.papermc.paper.datacomponent.item.Repairable.repairable(RegistrySet.keySetFromValues(RegistryKey.ITEM, repairable))) + itemStack.setData(DataComponentTypes.REPAIRABLE, io.papermc.paper.datacomponent.item.Repairable.repairable(RegistrySet.keySetFromValues(RegistryKey.ITEM, repairable.mapNotNull(Registry.ITEM::get)) } } @@ -620,16 +618,18 @@ object SerializableDataTypes { @Serializable data class PotDecorations( - val backItem: ItemType? = null, - val frontItem: ItemType? = null, - val leftItem: ItemType? = null, - val rightItem: ItemType? = null, + val backItem: @Serializable(KeySerializer::class) Key? = null, + val frontItem: @Serializable(KeySerializer::class) Key? = null, + val leftItem: @Serializable(KeySerializer::class) Key? = null, + val rightItem: @Serializable(KeySerializer::class) Key? = null, ) : DataType { constructor(potDecorations: io.papermc.paper.datacomponent.item.PotDecorations) : - this(potDecorations.back(), potDecorations.front(), potDecorations.left(), potDecorations.right()) + this(potDecorations.back()?.key(), potDecorations.front()?.key(), potDecorations.left()?.key(), potDecorations.right()?.key()) override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.POT_DECORATIONS, io.papermc.paper.datacomponent.item.PotDecorations.potDecorations(backItem, leftItem, rightItem, frontItem)) + val (back, front) = backItem?.let { Registry.ITEM.get(it) } to frontItem?.let { Registry.ITEM.get(it) } + val (left, right) = leftItem?.let { Registry.ITEM.get(it) } to rightItem?.let { Registry.ITEM.get(it) } + itemStack.setData(DataComponentTypes.POT_DECORATIONS, io.papermc.paper.datacomponent.item.PotDecorations.potDecorations(back, left, right, front)) } } From 08e338a2aaf2038464715537c31559ba939b4684 Mon Sep 17 00:00:00 2001 From: Boy Date: Sat, 2 Nov 2024 15:19:10 +0100 Subject: [PATCH 14/15] refactor: support tags in repairable --- .../idofront/serialization/SerializableDataTypes.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt index 3077165..0a006f1 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableDataTypes.kt @@ -22,6 +22,7 @@ import org.bukkit.Registry import org.bukkit.entity.EntityType import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.ItemType import org.bukkit.inventory.meta.trim.ArmorTrim import org.bukkit.map.MapCursor import org.bukkit.potion.PotionEffect @@ -225,10 +226,18 @@ object SerializableDataTypes { @Serializable @JvmInline value class Repairable(val repairable: List<@Serializable(KeySerializer::class) Key>) : DataType { - constructor(repairable: io.papermc.paper.datacomponent.item.Repairable) : this(repairable.types().resolve(Registry.ITEM).map { it.key() }) + constructor(repairable: io.papermc.paper.datacomponent.item.Repairable) : + this(repairable.types().resolve(Registry.ITEM).map { it.key() }) override fun setDataType(itemStack: ItemStack) { - itemStack.setData(DataComponentTypes.REPAIRABLE, io.papermc.paper.datacomponent.item.Repairable.repairable(RegistrySet.keySetFromValues(RegistryKey.ITEM, repairable.mapNotNull(Registry.ITEM::get)) + val items = repairable.mapNotNull { Registry.ITEM.get(it)?.key()?.let { TypedKey.create(RegistryKey.ITEM, it) } } + val tags = repairable.mapNotNull { + runCatching { Registry.ITEM.getTag(TagKey.create(RegistryKey.ITEM, it)) }.getOrNull()?.values() + }.flatten() + + itemStack.setData(DataComponentTypes.REPAIRABLE, io.papermc.paper.datacomponent.item.Repairable.repairable( + RegistrySet.keySet(RegistryKey.ITEM, items.plus(tags).filterNotNull().toMutableList()) + )) } } From d13cdc669b88971e9227aed571c6ca0c98f031b5 Mon Sep 17 00:00:00 2001 From: Boy Date: Sat, 30 Nov 2024 23:24:36 +0100 Subject: [PATCH 15/15] chore: bump deps --- build.gradle.kts | 4 +-- gradle.properties | 2 +- gradle/libs.versions.toml | 22 +++++++------- idofront-serializers/build.gradle.kts | 2 +- .../serialization/SerializableItemStack.kt | 29 ++++++------------- 5 files changed, 24 insertions(+), 35 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3552cb6..ebedd96 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,8 +20,8 @@ subprojects { maven("https://jitpack.io") maven("https://mvn.lumine.io/repository/maven-public/") { metadataSources { artifact() } }// MythicMobs maven("https://repo.unnamed.team/repository/unnamed-public/") - maven("https://repo.oraxen.com/releases") - maven("https://repo.oraxen.com/snapshots") + maven("https://repo.nexomc.com/releases") + maven("https://repo.nexomc.com/snapshots") } tasks { diff --git a/gradle.properties b/gradle.properties index c2fb94b..12c64f1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ group=com.mineinabyss -version=0.25 +version=0.26 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ff820e1..105e868 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,13 +1,13 @@ [versions] anvilgui = "1.10.3-SNAPSHOT" -compose = "1.6.11" -coroutines = "1.9.0-RC" +compose = "1.7.1" +coroutines = "1.9.0" creative = "1.7.3" dependencyversions = "0.51.0" dokka = "1.9.20" -exposed = "0.55.0" +exposed = "0.56.0" fastutil = "8.5.14" -fawe = "2.8.4" +fawe = "2.12.2" itemsadder = "3.6.1" junit = "5.11.0" jvm = "21" @@ -23,18 +23,18 @@ logback = "1.5.9" mccoroutine = "2.20.0" # @pin minecraft = "1.21.3-R0.1-SNAPSHOT" -mockbukkit = "3.133.0" +mockbukkit = "3.133.2" mockk = "1.13.13" modelengine = "R4.0.7" -mythic-dist = "5.7.2" -mythiccrucible = "2.0.0" -oraxen = "1.182.0" +mythic-dist = "5.8.0-SNAPSHOT" +mythiccrucible = "2.2.0-SNAPSHOT" +nexo = "0.1.0-dev.52" protocollib = "5.3.0-SNAPSHOT" reflections = "0.10.2" serialization = "1.7.3" -shadowjar = "8.3.0" +shadowjar = "8.3.5" sqlite-jdbc = "3.46.0.0" -userdev = "1.7.3" +userdev = "1.7.5" vault = "1.7" version-catalog-update = "0.8.4" worldguard = "7.1.0-SNAPSHOT" @@ -85,7 +85,7 @@ minecraft-plugin-itemsadder = { module = "com.github.LoneDev6:api-itemsadder", v minecraft-plugin-modelengine = { module = "com.ticxo.modelengine:ModelEngine", version.ref = "modelengine" } minecraft-plugin-mythic-crucible = { module = "io.lumine:MythicCrucible", version.ref = "mythiccrucible" } minecraft-plugin-mythic-dist = { module = "io.lumine:Mythic-Dist", version.ref = "mythic-dist" } -minecraft-plugin-oraxen = { module = "io.th0rgal:oraxen", version.ref = "oraxen" } +minecraft-plugin-nexo = { module = "com.nexomc:nexo", version.ref = "nexo" } minecraft-plugin-protocollib = { module = "com.comphenix.protocol:ProtocolLib", version.ref = "protocollib" } minecraft-plugin-vault = { module = "com.github.MilkBowl:VaultAPI", version.ref = "vault" } minecraft-plugin-worldguard = { module = "com.sk89q.worldguard:worldguard-bukkit", version.ref = "worldguard" } diff --git a/idofront-serializers/build.gradle.kts b/idofront-serializers/build.gradle.kts index d4bb818..e599068 100644 --- a/idofront-serializers/build.gradle.kts +++ b/idofront-serializers/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(libs.kotlinx.serialization.kaml) compileOnly(libs.minecraft.plugin.mythic.dist) compileOnly(libs.minecraft.plugin.mythic.crucible) - compileOnly(libs.minecraft.plugin.oraxen) + compileOnly(libs.minecraft.plugin.nexo) compileOnly(libs.minecraft.plugin.itemsadder) compileOnly(libs.creative.api) implementation(project(":idofront-util")) diff --git a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt index 4578426..ecb4fb7 100644 --- a/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt +++ b/idofront-serializers/src/main/kotlin/com/mineinabyss/idofront/serialization/SerializableItemStack.kt @@ -8,18 +8,16 @@ import com.mineinabyss.idofront.plugin.Plugins import com.mineinabyss.idofront.serialization.recipes.options.IngredientOption import com.mineinabyss.idofront.textcomponents.miniMsg import com.mineinabyss.idofront.textcomponents.serialize +import com.nexomc.nexo.NexoPlugin +import com.nexomc.nexo.api.NexoItems import dev.lone.itemsadder.api.CustomStack import io.lumine.mythiccrucible.MythicCrucible import io.papermc.paper.datacomponent.DataComponentTypes -import io.papermc.paper.datacomponent.item.* +import io.papermc.paper.datacomponent.item.ItemLore +import io.papermc.paper.datacomponent.item.MapDecorations import io.papermc.paper.item.MapPostProcessing -import io.th0rgal.oraxen.OraxenPlugin -import io.th0rgal.oraxen.api.OraxenItems -import kotlinx.serialization.Contextual import kotlinx.serialization.* import kotlinx.serialization.EncodeDefault.Mode.NEVER -import kotlinx.serialization.Serializable -import kotlinx.serialization.UseSerializers import net.kyori.adventure.key.Key import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.TextDecoration @@ -29,15 +27,6 @@ import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.inventory.ItemRarity import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.KnowledgeBookMeta -import org.bukkit.inventory.meta.LeatherArmorMeta -import org.bukkit.inventory.meta.PotionMeta -import org.bukkit.inventory.meta.components.FoodComponent -import org.bukkit.inventory.meta.components.JukeboxPlayableComponent -import org.bukkit.inventory.meta.components.ToolComponent -import org.bukkit.potion.PotionEffect -import org.bukkit.potion.PotionType -import sun.font.Decoration typealias SerializableItemStack = @Serializable(with = SerializableItemStackSerializer::class) BaseSerializableItemStack @@ -142,15 +131,15 @@ data class BaseSerializableItemStack( } } - // Import ItemStack from Oraxen + // Import ItemStack from Nexo oraxenItem?.let { id -> - if (Plugins.isEnabled()) { - OraxenItems.getItemById(id)?.build()?.let { + if (Plugins.isEnabled()) { + NexoItems.itemFromId(id)?.build()?.let { applyTo.type = it.type applyTo.itemMeta = it.itemMeta - } ?: idofrontLogger.w("No Oraxen item found with id $id") + } ?: idofrontLogger.w("No Nexo item found with id $id") } else { - idofrontLogger.w("Tried to import Oraxen item, but Oraxen was not enabled") + idofrontLogger.w("Tried to import Nexo item, but Nexo was not enabled") } }