Skip to content

First main objective #1

@RsMan-Dev

Description

@RsMan-Dev

Objectif arriver à ca:
(ItemStack|Entity|Block|Chunk|World).(get|set|remove)NbtMeta<NBTMeta>()…..

Si trop difficile à envisager, rester sur ceci, ces fonctions doivent absolument exister, que la solution en haut soit possible ou non:
(ItemStack|Entity|Block|Chunk|World).setNbtMetaKey(Str key, T value)
(ItemStack|Entity|Block|Chunk|World).getNbtMetaKey<T>(Str key)
(ItemStack|Entity|Block|Chunk|World).deleteNbtMetaKey(Str key)

ATTENTION: Penser a nommer les fichiers d'extension dans le format (ItemStack|Entity|Block|Chunk|World)NBT pour les devs JAVA.

Contraintes: Utiliser persistentDataContainer pour les versions 1.12.2<1.20, trouver une solution de persistentDataContainer ou équivalent, (des fonctions NBT moins permissives ont l’air d’exister.) pour les versions 1.8.8<1.12.2

Voici une ancienne version implémentée dans un de mes anciens plugin :

val ItemStack.isCustom : Boolean
    get() = hasMainData(this.itemMeta)

inline fun <reified T: Any> ItemStack.setNbt(name: String, value: T)
{
    when (T::class) {
        String::class -> set(this, name, PersistentDataType.STRING, value as String)

        Boolean::class -> set(this, name, PersistentDataType.BYTE, if (value as Boolean) 1.toByte() else 0.toByte())

        Byte::class -> set(this, name, PersistentDataType.BYTE, value as Byte)
        Short::class -> set(this, name, PersistentDataType.SHORT, value as Short)
        Int::class -> set(this, name, PersistentDataType.INTEGER, value as Int)
        Long::class -> set(this, name, PersistentDataType.LONG, value as Long)
        Float::class -> set(this, name, PersistentDataType.FLOAT, value as Float)
        Double::class -> set(this, name, PersistentDataType.DOUBLE, value as Double)

        PersistentDataContainer::class -> set(this, name, PersistentDataType.TAG_CONTAINER, value as PersistentDataContainer)
    }
}

inline fun <reified T: Any> ItemStack.setNbtList(name: String, value: List<T>)
{
    when (T::class) {
        Byte::class -> set(this, name, PersistentDataType.BYTE_ARRAY, value.filterIsInstance<Byte>().toByteArray())
        Int::class -> set(this, name, PersistentDataType.INTEGER_ARRAY, value.filterIsInstance<Int>().toIntArray())
        Long::class -> set(this, name, PersistentDataType.LONG_ARRAY, value.filterIsInstance<Long>().toLongArray())

        PersistentDataContainer::class -> set(this, name, PersistentDataType.TAG_CONTAINER_ARRAY, value.filterIsInstance<PersistentDataContainer>().toTypedArray())
    }
}

inline fun <reified T: Any> ItemStack.getNbt(name: String) : T?
{
    return when (T::class) {
        String::class -> get(this, name, PersistentDataType.STRING) as T?

        Boolean::class -> (get(this, name, PersistentDataType.BYTE) == 1.toByte()) as T?

        Byte::class -> get(this, name, PersistentDataType.BYTE) as T?
        Short::class -> get(this, name, PersistentDataType.SHORT) as T?
        Int::class -> get(this, name, PersistentDataType.INTEGER) as T?
        Long::class -> get(this, name, PersistentDataType.LONG) as T?
        Float::class -> get(this, name, PersistentDataType.FLOAT) as T?
        Double::class -> get(this, name, PersistentDataType.DOUBLE) as T?

        PersistentDataContainer::class -> get(this, name, PersistentDataType.TAG_CONTAINER) as T?

        else -> null
    }
}

inline fun <reified T: Any> ItemStack.getNbtList(name: String) : List<T>?
{
    return when (T::class) {
        Byte::class -> get(this, name, PersistentDataType.BYTE_ARRAY)?.toList()?.filterIsInstance<T>()
        Int::class -> get(this, name, PersistentDataType.INTEGER_ARRAY)?.toList()?.filterIsInstance<T>()
        Long::class -> get(this, name, PersistentDataType.LONG_ARRAY)?.toList()?.filterIsInstance<T>()

        PersistentDataContainer::class -> get(this, name, PersistentDataType.TAG_CONTAINER_ARRAY)?.toList()?.filterIsInstance<T>()

        else -> null
    }
}

@Suppress("BooleanMethodIsAlwaysInverted")
fun ItemStack.removeNbt(name: String): Boolean {
    return remove(this, name)
}

private fun getMainData(itemMeta: ItemMeta?): PersistentDataContainer? {
    val namespacedKeyGlobal = NamespacedKey(instance, "mainItemData")
    var data = itemMeta!!.persistentDataContainer.get(namespacedKeyGlobal, PersistentDataType.TAG_CONTAINER)
    val dataContext = itemMeta.persistentDataContainer.adapterContext
    if (data == null) {
        itemMeta.persistentDataContainer.set(namespacedKeyGlobal, PersistentDataType.TAG_CONTAINER, dataContext.newPersistentDataContainer())
        data = itemMeta.persistentDataContainer.get(namespacedKeyGlobal, PersistentDataType.TAG_CONTAINER)
    }
    return data
}

fun hasMainData(itemMeta: ItemMeta?): Boolean{
    val namespacedKeyGlobal = NamespacedKey(instance, "mainItemData")
    return itemMeta!!.persistentDataContainer.get(namespacedKeyGlobal, PersistentDataType.TAG_CONTAINER) != null
}

private fun setMainData(itemMeta: ItemMeta, ctn: PersistentDataContainer): ItemMeta {
    val namespacedKeyGlobal = NamespacedKey(instance, "mainItemData")
    itemMeta.persistentDataContainer.set(namespacedKeyGlobal, PersistentDataType.TAG_CONTAINER, ctn)
    return itemMeta
}

fun <T : Any> set(item: ItemStack, key: String?, type: PersistentDataType<T, T>, value: T): ItemStack {
    val namespacedKey = NamespacedKey(instance, key!!)
    var itemMeta = item.itemMeta
    val itemData = getMainData(itemMeta)
    if (itemData == null) {
        Bukkit.getLogger().warning("Cannot get item global data")
        return item
    }
    itemData.set(namespacedKey, type, value)
    itemMeta = setMainData(itemMeta!!, itemData)
    item.itemMeta = itemMeta
    return item
}

fun <T> get(item: ItemStack, key: String?, type: PersistentDataType<T, T>): T? {
    val namespacedKey = NamespacedKey(instance, key!!)
    val itemMeta = item.itemMeta ?: return null
    val itemData = getMainData(itemMeta)
            ?: //Bukkit.getLogger().warning("Cannot get item global data");
            return null
    return itemData.get(namespacedKey, type)
}

fun remove(item: ItemStack, key: String?): Boolean {
    val namespacedKey = NamespacedKey(instance, key!!)
    var itemMeta = item.itemMeta ?: return false
    val itemData = getMainData(itemMeta)
    if (itemData == null) {
        Bukkit.getLogger().warning("Cannot get item global data")
        return false
    }
    itemData.remove(namespacedKey)
    itemMeta = setMainData(itemMeta, itemData)
    item.itemMeta = itemMeta
    return true
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions