diff options
Diffstat (limited to 'src/main/kotlin')
| -rw-r--r-- | src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt | 4 | ||||
| -rw-r--r-- | src/main/kotlin/features/inventory/CraftingOverlay.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/features/inventory/ItemHotkeys.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/features/inventory/buttons/InventoryButton.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/gui/entity/ModifyEquipment.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/repo/ExpensiveItemCacheApi.kt | 8 | ||||
| -rw-r--r-- | src/main/kotlin/repo/ItemCache.kt | 56 | ||||
| -rw-r--r-- | src/main/kotlin/repo/MiningRepoData.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/repo/RepoManager.kt | 18 | ||||
| -rw-r--r-- | src/main/kotlin/repo/SBItemStack.kt | 8 | ||||
| -rw-r--r-- | src/main/kotlin/repo/recipes/SBEssenceUpgradeRecipeRenderer.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/util/SkyblockId.kt | 2 |
13 files changed, 94 insertions, 16 deletions
diff --git a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt index 2332e2d..c0f48ca 100644 --- a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt +++ b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt @@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.util.Identifier import moe.nea.firmament.Firmament +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.ItemCache import moe.nea.firmament.util.MC @@ -57,6 +58,7 @@ object LegacyItemData { val enchantmentLut = enchantmentData.associateBy { Identifier.ofVanilla(it.name) } val itemDat = getLegacyData<List<ItemData>>("items") + @OptIn(ExpensiveItemCacheApi::class) // This is fine, we get loaded in a thread. val itemLut = itemDat.flatMap { item -> item.allVariants().map { legacyItemType -> val nbt = ItemCache.convert189ToModern(NbtCompound().apply { diff --git a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt index 5151862..0cfaeba 100644 --- a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt +++ b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt @@ -15,6 +15,7 @@ import moe.nea.firmament.events.WorldReadyEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.hud.MoulConfigHud +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.ItemNameLookup import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.MC @@ -202,7 +203,8 @@ object AnniversaryFeatures : FirmamentFeature { SBItemStack(SkyblockId.NULL) } - @Bind + @OptIn(ExpensiveItemCacheApi::class) + @Bind fun name(): String { return when (backedBy) { is Reward.Coins -> "Coins" diff --git a/src/main/kotlin/features/inventory/CraftingOverlay.kt b/src/main/kotlin/features/inventory/CraftingOverlay.kt index d2c79fd..f823086 100644 --- a/src/main/kotlin/features/inventory/CraftingOverlay.kt +++ b/src/main/kotlin/features/inventory/CraftingOverlay.kt @@ -8,6 +8,7 @@ import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.ScreenChangeEvent import moe.nea.firmament.events.SlotRenderEvents import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.MC import moe.nea.firmament.util.skyblockId @@ -45,6 +46,7 @@ object CraftingOverlay : FirmamentFeature { override val identifier: String get() = "crafting-overlay" + @OptIn(ExpensiveItemCacheApi::class) @Subscribe fun onSlotRender(event: SlotRenderEvents.After) { val slot = event.slot diff --git a/src/main/kotlin/features/inventory/ItemHotkeys.kt b/src/main/kotlin/features/inventory/ItemHotkeys.kt index 4aa8202..0dc8a2a 100644 --- a/src/main/kotlin/features/inventory/ItemHotkeys.kt +++ b/src/main/kotlin/features/inventory/ItemHotkeys.kt @@ -3,6 +3,7 @@ package moe.nea.firmament.features.inventory import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.HandledScreenKeyPressedEvent import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.ItemCache import moe.nea.firmament.repo.ItemCache.asItemStack @@ -18,6 +19,7 @@ object ItemHotkeys { val openGlobalTradeInterface by keyBindingWithDefaultUnbound("global-trade-interface") } + @OptIn(ExpensiveItemCacheApi::class) @Subscribe fun onHandledInventoryPress(event: HandledScreenKeyPressedEvent) { if (!event.matches(TConfig.openGlobalTradeInterface)) { diff --git a/src/main/kotlin/features/inventory/buttons/InventoryButton.kt b/src/main/kotlin/features/inventory/buttons/InventoryButton.kt index 39feecf..955ae88 100644 --- a/src/main/kotlin/features/inventory/buttons/InventoryButton.kt +++ b/src/main/kotlin/features/inventory/buttons/InventoryButton.kt @@ -11,6 +11,7 @@ import net.minecraft.command.argument.ItemStackArgumentType import net.minecraft.item.ItemStack import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.Identifier +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.MC @@ -40,6 +41,7 @@ data class InventoryButton( } val dimensions = Dimension(18, 18) val getItemForName = ::getItemForName0.memoize(1024) + @OptIn(ExpensiveItemCacheApi::class) fun getItemForName0(icon: String): ItemStack { val repoItem = RepoManager.getNEUItem(SkyblockId(icon)) var itemStack = repoItem.asItemStack(idHint = SkyblockId(icon)) diff --git a/src/main/kotlin/gui/entity/ModifyEquipment.kt b/src/main/kotlin/gui/entity/ModifyEquipment.kt index 3ce63f5..2ef5007 100644 --- a/src/main/kotlin/gui/entity/ModifyEquipment.kt +++ b/src/main/kotlin/gui/entity/ModifyEquipment.kt @@ -8,6 +8,7 @@ import net.minecraft.entity.LivingEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.item.Items +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.mc.setEncodedSkullOwner @@ -31,6 +32,7 @@ object ModifyEquipment : EntityModifier { return entity } + @OptIn(ExpensiveItemCacheApi::class) private fun createItem(item: String): ItemStack { val split = item.split("#") if (split.size != 2) return SBItemStack(SkyblockId(item)).asImmutableItemStack() diff --git a/src/main/kotlin/repo/ExpensiveItemCacheApi.kt b/src/main/kotlin/repo/ExpensiveItemCacheApi.kt new file mode 100644 index 0000000..eef95a6 --- /dev/null +++ b/src/main/kotlin/repo/ExpensiveItemCacheApi.kt @@ -0,0 +1,8 @@ +package moe.nea.firmament.repo + +/** + * Marker for functions that could potentially invoke DFU. Please do not call on a lot of objects at once, or try to make sure the item is cached and fall back to a more gentle function call using [SBItemStack.isWarm] and similar functions. + */ +@RequiresOptIn +@Retention(AnnotationRetention.BINARY) +annotation class ExpensiveItemCacheApi diff --git a/src/main/kotlin/repo/ItemCache.kt b/src/main/kotlin/repo/ItemCache.kt index 5e05dba..705180a 100644 --- a/src/main/kotlin/repo/ItemCache.kt +++ b/src/main/kotlin/repo/ItemCache.kt @@ -8,8 +8,14 @@ import java.text.NumberFormat import java.util.UUID import java.util.concurrent.ConcurrentHashMap import org.apache.logging.log4j.LogManager -import kotlinx.coroutines.Job +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.cancel import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import kotlin.jvm.optionals.getOrNull import net.minecraft.SharedConstants import net.minecraft.component.DataComponentTypes @@ -30,6 +36,7 @@ import moe.nea.firmament.repo.RepoManager.initialize import moe.nea.firmament.util.LegacyFormattingCode import moe.nea.firmament.util.LegacyTagParser import moe.nea.firmament.util.MC +import moe.nea.firmament.util.MinecraftDispatcher import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.TestUtil import moe.nea.firmament.util.directLiteralStringContent @@ -40,6 +47,7 @@ import moe.nea.firmament.util.mc.loreAccordingToNbt import moe.nea.firmament.util.mc.modifyLore import moe.nea.firmament.util.mc.setCustomName import moe.nea.firmament.util.mc.setSkullOwner +import moe.nea.firmament.util.skyblockId import moe.nea.firmament.util.transformEachRecursively object ItemCache : IReloadable { @@ -56,7 +64,10 @@ object ItemCache : IReloadable { putShort("Damage", damage.toShort()) } + @ExpensiveItemCacheApi private fun NbtCompound.transformFrom10809ToModern() = convert189ToModern(this@transformFrom10809ToModern) + + @ExpensiveItemCacheApi fun convert189ToModern(nbtComponent: NbtCompound): NbtCompound? = try { df.update( @@ -126,6 +137,7 @@ object ItemCache : IReloadable { return base } + @ExpensiveItemCacheApi private fun NEUItem.asItemStackNow(): ItemStack { try { val oldItemTag = get10809CompoundTag() @@ -150,6 +162,7 @@ object ItemCache : IReloadable { return skyblockId.neuItem in cache } + @ExpensiveItemCacheApi fun NEUItem?.asItemStack(idHint: SkyblockId? = null, loreReplacements: Map<String, String>? = null): ItemStack { if (this == null) return brokenItemStack(null, idHint) var s = cache[this.skyblockItemId] @@ -183,22 +196,43 @@ object ItemCache : IReloadable { } } - var job: Job? = null + var itemRecacheScope: CoroutineScope? = null - override fun reload(repository: NEURepository) { - val j = job - if (j != null && j.isActive) { - j.cancel() + private var recacheSoonSubmitted = mutableSetOf<SkyblockId>() + + @OptIn(ExpensiveItemCacheApi::class) + fun recacheSoon(neuItem: NEUItem) { + itemRecacheScope?.launch { + if (!withContext(MinecraftDispatcher) { + recacheSoonSubmitted.add(neuItem.skyblockId) + }) { + return@launch + } + neuItem.asItemStack() } + } + + @OptIn(ExpensiveItemCacheApi::class) + override fun reload(repository: NEURepository) { + val j = itemRecacheScope + j?.cancel("New reload invoked") cache.clear() isFlawless = true if (TestUtil.isInTest) return - job = Firmament.coroutineScope.launch { - val items = repository.items?.items ?: return@launch - items.values.forEach { - it.asItemStack() // Rebuild cache - } + val newScope = + CoroutineScope(Firmament.coroutineScope.coroutineContext + SupervisorJob(Firmament.globalJob) + Dispatchers.Default) + val items = repository.items?.items + newScope.launch { + val items = items ?: return@launch + items.values.chunked(500).map { chunk -> + async { + chunk.forEach { + it.asItemStack() // Rebuild cache + } + } + }.awaitAll() } + itemRecacheScope = newScope } fun coinItem(coinAmount: Int): ItemStack { diff --git a/src/main/kotlin/repo/MiningRepoData.kt b/src/main/kotlin/repo/MiningRepoData.kt index e40292d..e96a241 100644 --- a/src/main/kotlin/repo/MiningRepoData.kt +++ b/src/main/kotlin/repo/MiningRepoData.kt @@ -81,6 +81,7 @@ class MiningRepoData : IReloadable { ) { @Transient val dropItem = baseDrop?.let(::SBItemStack) + @OptIn(ExpensiveItemCacheApi::class) private val labeledStack by lazy { dropItem?.asCopiedItemStack()?.also(::markItemStack) } @@ -110,6 +111,7 @@ class MiningRepoData : IReloadable { fun isActiveIn(location: SkyBlockIsland) = onlyIn == null || location in onlyIn + @OptIn(ExpensiveItemCacheApi::class) private fun convertToModernBlock(): Block? { // TODO: this should be in a shared util, really val newCompound = ItemCache.convert189ToModern(NbtCompound().apply { diff --git a/src/main/kotlin/repo/RepoManager.kt b/src/main/kotlin/repo/RepoManager.kt index 115dd54..f4146e0 100644 --- a/src/main/kotlin/repo/RepoManager.kt +++ b/src/main/kotlin/repo/RepoManager.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.launch import net.minecraft.client.MinecraftClient import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket import net.minecraft.recipe.display.CuttingRecipeDisplay +import net.minecraft.util.StringIdentifiable import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament.logger import moe.nea.firmament.events.ReloadRegistrationEvent @@ -46,7 +47,16 @@ object RepoManager { } val alwaysSuperCraft by toggle("enable-super-craft") { true } var warnForMissingItemListMod by toggle("warn-for-missing-item-list-mod") { true } - val perfectTooltips by toggle("perfect-tooltips") { false } + val perfectRenders by choice("perfect-renders") { PerfectRender.RENDER } + } + + enum class PerfectRender(val label: String) : StringIdentifiable { + NOTHING("nothing"), + RENDER("render"), + RENDER_AND_TEXT("text"), + ; + + override fun asString(): String? = label } val currentDownloadedSha by RepoDownloadManager::latestSavedVersionHash @@ -136,8 +146,10 @@ object RepoManager { } catch (exc: NEURepositoryException) { ErrorUtil.softError("Failed to reload repository", exc) MC.sendChat( - tr("firmament.repo.reloadfail", - "Failed to reload repository. This will result in some mod features not working.") + tr( + "firmament.repo.reloadfail", + "Failed to reload repository. This will result in some mod features not working." + ) ) } } diff --git a/src/main/kotlin/repo/SBItemStack.kt b/src/main/kotlin/repo/SBItemStack.kt index 0026e03..537bd81 100644 --- a/src/main/kotlin/repo/SBItemStack.kt +++ b/src/main/kotlin/repo/SBItemStack.kt @@ -353,7 +353,9 @@ data class SBItemStack constructor( } // TODO: avoid instantiating the item stack here + @ExpensiveItemCacheApi val itemType: ItemType? get() = ItemType.fromItemStack(asImmutableItemStack()) + @ExpensiveItemCacheApi val rarity: Rarity? get() = Rarity.fromItem(asImmutableItemStack()) private var itemStack_: ItemStack? = null @@ -364,6 +366,7 @@ data class SBItemStack constructor( group("power").toInt() } ?: 0 + @ExpensiveItemCacheApi private val itemStack: ItemStack get() { val itemStack = itemStack_ ?: run { @@ -437,15 +440,18 @@ data class SBItemStack constructor( return false } + @OptIn(ExpensiveItemCacheApi::class) fun asLazyImmutableItemStack(): ItemStack? { if (isWarm()) return asImmutableItemStack() return null } - fun asImmutableItemStack(): ItemStack { + @ExpensiveItemCacheApi + fun asImmutableItemStack(): ItemStack { // TODO: add a "or fallback to painting" option to asLazyImmutableItemStack to be used in more places. return itemStack } + @ExpensiveItemCacheApi fun asCopiedItemStack(): ItemStack { return itemStack.copy() } diff --git a/src/main/kotlin/repo/recipes/SBEssenceUpgradeRecipeRenderer.kt b/src/main/kotlin/repo/recipes/SBEssenceUpgradeRecipeRenderer.kt index 0f5271f..d358e6a 100644 --- a/src/main/kotlin/repo/recipes/SBEssenceUpgradeRecipeRenderer.kt +++ b/src/main/kotlin/repo/recipes/SBEssenceUpgradeRecipeRenderer.kt @@ -9,6 +9,7 @@ import net.minecraft.text.Text import net.minecraft.util.Identifier import moe.nea.firmament.Firmament import moe.nea.firmament.repo.EssenceRecipeProvider +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.SkyblockId @@ -62,6 +63,7 @@ object SBEssenceUpgradeRecipeRenderer : GenericRecipeRenderer<EssenceRecipeProvi return listOfNotNull(SBItemStack(recipe.itemId)) } + @OptIn(ExpensiveItemCacheApi::class) override val icon: ItemStack get() = SBItemStack(SkyblockId("ESSENCE_WITHER")).asImmutableItemStack() override val title: Text = tr("firmament.category.essence", "Essence Upgrades") override val identifier: Identifier = Firmament.identifier("essence_upgrade") diff --git a/src/main/kotlin/util/SkyblockId.kt b/src/main/kotlin/util/SkyblockId.kt index 58aa24c..af767f8 100644 --- a/src/main/kotlin/util/SkyblockId.kt +++ b/src/main/kotlin/util/SkyblockId.kt @@ -22,6 +22,7 @@ import net.minecraft.network.codec.PacketCodec import net.minecraft.network.codec.PacketCodecs import net.minecraft.util.Identifier import moe.nea.firmament.repo.ExpLadders +import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.set import moe.nea.firmament.util.collections.WeakCache @@ -86,6 +87,7 @@ value class SkyblockId(val neuItem: String) : Comparable<SkyblockId> { val NEUItem.skyblockId get() = SkyblockId(skyblockItemId) val NEUIngredient.skyblockId get() = SkyblockId(itemId) +@ExpensiveItemCacheApi fun NEUItem.guessRecipeId(): String? { if (!skyblockItemId.contains(";")) return skyblockItemId val item = this.asItemStack() |
