diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt')
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt b/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt new file mode 100644 index 0000000..bd624b6 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt @@ -0,0 +1,123 @@ +package moe.nea.firmament.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.SharedConstants +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 moe.nea.firmament.Firmament +import moe.nea.firmament.util.LegacyTagParser +import moe.nea.firmament.util.appendLore +import moe.nea.firmament.util.skyblockId + +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, + SharedConstants.getGameVersion().saveVersion.id + ).value as NbtCompound + } catch (e: Exception) { + if (isFlawless) + Firmament.logger.error("Failed to run data fixer an item. Check ${dfuLog.absolutePathString()} for more information") + isFlawless = false + e.printStackTrace(dfuHandle) + null + } + + fun brokenItemStack(neuItem: NEUItem?): ItemStack { + return ItemStack(Items.PAINTING).apply { + setCustomName(Text.literal(neuItem?.displayName ?: "null")) + appendLore(listOf(Text.translatable("firmament.repo.brokenitem", neuItem?.skyblockItemId))) + } + } + + private fun NEUItem.asItemStackNow(): ItemStack { + try { + val oldItemTag = get10809CompoundTag() + val modernItemTag = oldItemTag.transformFrom10809ToModern() + ?: return brokenItemStack(this) + val itemInstance = ItemStack.fromNbt(modernItemTag) + if (itemInstance.nbt?.contains("Enchantments") == true) { + itemInstance.enchantments.add(NbtCompound()) + } + return itemInstance + } catch (e: Exception) { + e.printStackTrace() + return brokenItemStack(this) + } + } + + fun NEUItem?.asItemStack(): ItemStack { + if (this == null) return brokenItemStack(null) + var s = cache[this.skyblockItemId] + if (s == null) { + s = asItemStackNow() + cache[this.skyblockItemId] = s + } + return s + } + + fun NEUItem.getIdentifier() = skyblockId.identifier + + + var job: Job? = null + + override fun reload(repository: NEURepository) { + val j = job + if (j != null && j.isActive) { + j.cancel() + } + cache.clear() + isFlawless = true + + job = Firmament.coroutineScope.launch { + val items = repository.items?.items + if (items == null) { + CottonHud.remove(RepoManager.progressBar) + return@launch + } + val recacheItems = I18n.translate("firmament.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) + } + } +} |