22
33package com.mineinabyss.idofront.serialization
44
5- import com.mineinabyss.idofront.di.DI
65import com.mineinabyss.idofront.messaging.idofrontLogger
7- import com.mineinabyss.idofront.plugin.Plugins
6+ import com.mineinabyss.idofront.plugin.Services
87import com.mineinabyss.idofront.serialization.recipes.options.IngredientOption
8+ import com.mineinabyss.idofront.services.SerializableItemStackService
99import com.mineinabyss.idofront.textcomponents.miniMsg
1010import com.mineinabyss.idofront.textcomponents.serialize
11- import com.nexomc.nexo.NexoPlugin
12- import com.nexomc.nexo.api.NexoItems
13- import dev.lone.itemsadder.api.CustomStack
14- import io.lumine.mythiccrucible.MythicCrucible
1511import io.papermc.paper.datacomponent.DataComponentType
1612import io.papermc.paper.datacomponent.DataComponentTypes
1713import io.papermc.paper.datacomponent.item.ItemLore
1814import io.papermc.paper.datacomponent.item.MapDecorations
1915import io.papermc.paper.item.MapPostProcessing
2016import io.papermc.paper.registry.RegistryAccess
2117import io.papermc.paper.registry.RegistryKey
22- import kotlinx.serialization.Contextual
2318import kotlinx.serialization.*
2419import kotlinx.serialization.EncodeDefault.Mode.NEVER
2520import net.kyori.adventure.key.Key
26- import net.kyori.adventure.text.Component
27- import net.kyori.adventure.text.format.TextDecoration
28- import org.bukkit.Art
29- import org.bukkit.Bukkit
30- import org.bukkit.Keyed
31- import org.bukkit.Material
32- import org.bukkit.NamespacedKey
33- import org.bukkit.Registry
21+ import org.bukkit.*
3422import org.bukkit.inventory.ItemRarity
3523import org.bukkit.inventory.ItemStack
3624import org.bukkit.inventory.RecipeChoice
@@ -40,11 +28,14 @@ typealias SerializableItemStack = @Serializable(with = SerializableItemStackSeri
4028/* *
4129 * A wrapper for [ItemStack] that uses [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization).
4230 * Allows for easy-to-use serialization to JSON (or YAML with kaml).
31+ *
32+ * @param type The item type to inherit a baseline configuration from, other plugins may register extra providers for this.
4333 */
4434@Suppress(" UnstableApiUsage" )
4535@Serializable
4636data class BaseSerializableItemStack (
47- @EncodeDefault(NEVER ) val type : @Serializable(with = MaterialByNameSerializer ::class ) Material ? = null ,
37+ @EncodeDefault(NEVER ) val material : @Serializable(with = MaterialByNameSerializer ::class ) Material ? = null ,
38+ @EncodeDefault(NEVER ) val type : String? = null ,
4839 @EncodeDefault(NEVER ) val amount : Int? = null ,
4940 @EncodeDefault(NEVER ) val customModelData : SerializableDataTypes .CustomModelData ? = null ,
5041 @EncodeDefault(NEVER ) val itemModel : @Serializable(KeySerializer ::class ) Key ? = null ,
@@ -103,75 +94,46 @@ data class BaseSerializableItemStack(
10394 @EncodeDefault(NEVER ) val noteBlockSound : @Serializable(KeySerializer ::class ) Key ? = null ,
10495 @EncodeDefault(NEVER ) val potDecorations : SerializableDataTypes .PotDecorations ? = null ,
10596
106-
107- @EncodeDefault(NEVER ) val prefab : String? = null ,
10897 @EncodeDefault(NEVER ) val tag : @Serializable(NamespacedKeySerializer ::class ) NamespacedKey ? = null ,
10998 @EncodeDefault(NEVER ) val recipeOptions : List <IngredientOption > = listOf(),
11099
111100 // Unvalued DataTypes
112101 @EncodeDefault(NEVER ) @Contextual val intangibleProjectile : SerializableDataTypes .IntangibleProjectile ? = null ,
113102 @EncodeDefault(NEVER ) @Contextual val glider : SerializableDataTypes .Glider ? = null ,
114103 @EncodeDefault(NEVER ) val unbreakable : SerializableDataTypes .Unbreakable ? = null ,
115-
116- // Third-party plugins
117- @EncodeDefault(NEVER ) val crucibleItem : String? = null ,
118- @EncodeDefault(NEVER ) val nexoItem : String? = null ,
119- @EncodeDefault(NEVER ) val itemsadderItem : String? = null ,
120104) {
121- private fun Component.removeItalics () =
122- Component .text().decoration(TextDecoration .ITALIC , false ).build().append(this )
123-
124- @Transient val itemName = _itemName ?.miniMsg()
125- @Transient val customName = _customName ?.miniMsg()
126- @Transient val lore = _lore ?.map { it.miniMsg() }
105+ @Transient
106+ val itemName = _itemName ?.miniMsg()
107+
108+ @Transient
109+ val customName = _customName ?.miniMsg()
110+
111+ @Transient
112+ val lore = _lore ?.map { it.miniMsg() }
113+
114+ @Transient
115+ val itemProvider = type?.let {
116+ val provider = Services
117+ .getOrNull<SerializableItemStackService >()
118+ ?.getProvider(it.substringBefore(' ' , missingDelimiterValue = " " ))
119+ if (provider == null ) idofrontLogger.w { " Item provider for '$type ' could not be found." }
120+ provider
121+ }
127122
128123 /* *
129124 * Converts this serialized item's data to an [ItemStack], optionally applying the changes to an
130125 * [existing item][applyTo].
131126 */
132- fun toItemStack (applyTo : ItemStack = ItemStack .of(type ? : Material .AIR )): ItemStack {
133- // Import ItemStack from Crucible
134- crucibleItem?.let { id ->
135- if (Plugins .isEnabled<MythicCrucible >()) {
136- MythicCrucible .core().itemManager.getItemStack(id)?.let {
137- applyTo.type = it.type
138- applyTo.itemMeta = it.itemMeta
139- } ? : idofrontLogger.w(" No Crucible item found with id $id " )
140- } else {
141- idofrontLogger.w(" Tried to import Crucible item, but MythicCrucible was not enabled" )
142- }
143- }
144-
145- // Import ItemStack from Nexo
146- nexoItem?.let { id ->
147- if (Plugins .isEnabled<NexoPlugin >()) {
148- NexoItems .itemFromId(id)?.build()?.let {
149- applyTo.type = it.type
150- applyTo.itemMeta = it.itemMeta
151- } ? : idofrontLogger.w(" No Nexo item found with id $id " )
152- } else {
153- idofrontLogger.w(" Tried to import Nexo item, but Nexo was not enabled" )
154- }
127+ fun toItemStack (applyTo : ItemStack = ItemStack .of(material ? : Material .AIR )): ItemStack {
128+ if (type != null && itemProvider != null ) {
129+ val definition = type.substringAfter(' ' )
130+ val success = itemProvider.invoke(applyTo, definition)
131+ if (! success) idofrontLogger.w { " Item provider for '$type ' could not find such item." }
155132 }
156133
157- // Import ItemStack from ItemsAdder
158- itemsadderItem?.let { id ->
159- if (Plugins .isEnabled(" ItemsAdder" )) {
160- CustomStack .getInstance(id)?.itemStack?.let {
161- applyTo.type = it.type
162- applyTo.itemMeta = it.itemMeta
163- } ? : idofrontLogger.w(" No ItemsAdder item found with id $id " )
164- } else {
165- idofrontLogger.w(" Tried to import ItemsAdder item, but ItemsAdder was not enabled" )
166- }
167- }
168-
169- // Support for our prefab system in geary.
170- prefab?.let { encodePrefab.invoke(applyTo, it) } ? : applyTo
171-
172134 // Modify item
173135 amount?.let { applyTo.amount = it }
174- type ?.let { applyTo.type = type }
136+ material ?.let { applyTo.type = material }
175137
176138 SerializableDataTypes .setData(applyTo, DataComponentTypes .ITEM_NAME , itemName)
177139 SerializableDataTypes .setData(applyTo, DataComponentTypes .CUSTOM_NAME , customName)
@@ -237,7 +199,7 @@ data class BaseSerializableItemStack(
237199 return applyTo
238200 }
239201
240- fun toItemStackOrNull (applyTo : ItemStack = ItemStack (type ? : Material .AIR )) =
202+ fun toItemStackOrNull (applyTo : ItemStack = ItemStack (material ? : Material .AIR )) =
241203 toItemStack(applyTo).takeUnless { it.isEmpty }
242204
243205 fun toRecipeChoice (): RecipeChoice = toItemStackOrNull()?.let (RecipeChoice ::ExactChoice ) ? : RecipeChoice .empty()
@@ -246,11 +208,6 @@ data class BaseSerializableItemStack(
246208 fun matches (item : ItemStack ): Boolean {
247209 return item == toItemStack(applyTo = item.clone())
248210 }
249-
250- companion object {
251- @Suppress(" UNCHECKED_CAST" )
252- private val encodePrefab by DI .observe<SerializablePrefabItemService >()
253- }
254211}
255212
256213/* *
@@ -260,7 +217,7 @@ data class BaseSerializableItemStack(
260217 */
261218fun ItemStack.toSerializable (): SerializableItemStack = with (itemMeta) {
262219 SerializableItemStack (
263- type = type,
220+ material = type,
264221 amount = amount.takeIf { it != 1 },
265222 _itemName = dataIfOverriden(DataComponentTypes .ITEM_NAME )?.serialize(),
266223 _customName = dataIfOverriden(DataComponentTypes .CUSTOM_NAME )?.serialize(),
@@ -319,7 +276,6 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) {
319276
320277 intangibleProjectile = SerializableDataTypes .IntangibleProjectile .takeIf { hasData(DataComponentTypes .INTANGIBLE_PROJECTILE ) },
321278 unbreakable = SerializableDataTypes .Unbreakable .takeIf { hasData(DataComponentTypes .UNBREAKABLE ) },
322-
323279 )
324280}
325281
0 commit comments