aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/notenoughupdates/repo/ItemCache.kt
blob: 7dbfce3f5b4f5a11430be0b0cdc59589d9dc9588 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package moe.nea.notenoughupdates.repo

import com.mojang.serialization.Dynamic
import io.github.cottonmc.cotton.gui.client.CottonHud
import io.github.moulberry.repo.IReloadable
import io.github.moulberry.repo.NEURepository
import io.github.moulberry.repo.data.NEUItem
import java.io.PrintWriter
import java.nio.file.Path
import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlin.io.path.absolutePathString
import kotlin.io.path.writer
import net.minecraft.client.resource.language.I18n
import net.minecraft.datafixer.Schemas
import net.minecraft.datafixer.TypeReferences
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtOps
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import moe.nea.notenoughupdates.NotEnoughUpdates
import moe.nea.notenoughupdates.util.LegacyTagParser
import moe.nea.notenoughupdates.util.appendLore

object ItemCache : IReloadable {
    val dfuLog = Path.of("logs/dfulog.txt")
    private val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
    private val df = Schemas.getFixer()
    private val dfuHandle = PrintWriter(dfuLog.writer())
    var isFlawless = true
        private set

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

    private fun NbtCompound.transformFrom10809ToModern(): NbtCompound? =
        try {
            df.update(
                TypeReferences.ITEM_STACK,
                Dynamic(NbtOps.INSTANCE, this),
                -1,
                2975
            ).value as NbtCompound
        } catch (e: Exception) {
            if (isFlawless)
                NotEnoughUpdates.logger.error("Failed to run data fixer an item. Check ${dfuLog.absolutePathString()} for more information")
            isFlawless = false
            e.printStackTrace(dfuHandle)
            null
        }

    private fun NEUItem.asItemStackNow(): ItemStack {
        val oldItemTag = get10809CompoundTag()
        val modernItemTag = oldItemTag.transformFrom10809ToModern()
            ?: return ItemStack(Items.PAINTING).apply {
                setCustomName(Text.literal(this@asItemStackNow.displayName))
                appendLore(listOf(Text.translatable("notenoughupdates.repo.brokenitem", skyblockItemId)))
            }
        val itemInstance = ItemStack.fromNbt(modernItemTag)
        if (itemInstance.nbt?.contains("Enchantments") == true) {
            itemInstance.enchantments.add(NbtCompound())
        }
        return itemInstance
    }

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

    fun NEUItem.getIdentifier() =
        Identifier("skyblockitem", skyblockItemId.lowercase().replace(";", "__"))


    var job: Job? = null

    override fun reload(repository: NEURepository) {
        val j = job
        if (j != null && j.isActive) {
            j.cancel()
        }
        cache.clear()
        isFlawless = true

        job = NotEnoughUpdates.coroutineScope.launch {
            val items = repository.items?.items
            if (items == null) {
                CottonHud.remove(RepoManager.progressBar)
                return@launch
            }
            val recacheItems = I18n.translate("notenoughupdates.repo.cache")
            RepoManager.progressBar.reportProgress(recacheItems, 0, items.size)
            CottonHud.add(RepoManager.progressBar)
            var i = 0
            items.values.forEach {
                it.asItemStack() // Rebuild cache
                RepoManager.progressBar.reportProgress(recacheItems, i++, items.size)
            }
            CottonHud.remove(RepoManager.progressBar)
        }
    }
}