aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/notenoughupdates/repo/ItemCache.kt
blob: 8deb4c337389dccdd93d7c87118944bd083b2ede (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package moe.nea.notenoughupdates.repo

import com.mojang.serialization.Dynamic
import io.github.moulberry.repo.IReloadable
import io.github.moulberry.repo.NEURepository
import io.github.moulberry.repo.data.NEUItem
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import moe.nea.notenoughupdates.NotEnoughUpdates
import moe.nea.notenoughupdates.util.LegacyTagParser
import moe.nea.notenoughupdates.util.appendLore
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.datafix.DataFixers
import net.minecraft.util.datafix.fixes.References
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import java.util.concurrent.ConcurrentHashMap

object ItemCache : IReloadable {
    val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
    val df = DataFixers.getDataFixer()
    var isFlawless = true

    private fun NEUItem.get10809CompoundTag(): CompoundTag = CompoundTag().apply {
        put("tag", LegacyTagParser.parse(nbttag))
        putString("id", minecraftItemId)
        putByte("Count", 1)
        putShort("Damage", damage.toShort())
    }

    private fun CompoundTag.transformFrom10809ToModern(): CompoundTag? =
        try {
            df.update(
                References.ITEM_STACK,
                Dynamic(NbtOps.INSTANCE, this),
                -1,
                2975
            ).value as CompoundTag
        } catch (e: Exception) {
            NotEnoughUpdates.logger.error("Failed to datafixer an item", e)
            isFlawless = false
            null
        }

    private fun NEUItem.asItemStackNow(): ItemStack {
        val oldItemTag = get10809CompoundTag()
        val modernItemTag = oldItemTag.transformFrom10809ToModern()
            ?: return ItemStack(Items.PAINTING).apply {
                hoverName = Component.literal(this@asItemStackNow.displayName)
                appendLore(listOf(Component.literal("Exception rendering item: $skyblockItemId")))
            }
        val itemInstance = ItemStack.of(modernItemTag)
        if (itemInstance.tag?.contains("Enchantments") == true) {
            itemInstance.enchantmentTags.add(CompoundTag())
        }
        return itemInstance
    }

    fun NEUItem.asItemStack(): ItemStack {
        var s = cache[this.skyblockItemId]
        if (s == null) {
            s = asItemStackNow()
            cache[this.skyblockItemId] = s
        }
        return s
    }

    fun NEUItem.getResourceLocation() =
        ResourceLocation("skyblockitem", skyblockItemId.lowercase().replace(";", "__"))


    var job: Job? = null

    override fun reload(repository: NEURepository) {
        cache.clear()
        val j = job
        if (j != null && j.isActive) {
            j.cancel()
            job = NotEnoughUpdates.coroutineScope.launch {
                repository.items?.items?.values?.forEach {
                    it.asItemStack() // Rebuild cache
                }
            }
        }
    }
}