From 8024af3c90343899ace8060f2ddda427e6c7dc10 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sat, 20 Jan 2024 10:08:30 +0100 Subject: Backend: ItemCategory + better LorenzeRarity (#811) Categorizes every item using the rarity lore line. Also a better way of getting the item rarity Rarity #811 --- src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 2 + .../skyhanni/config/features/dev/DebugConfig.java | 5 + .../skyhanni/test/SkyHanniDebugsAndTests.kt | 29 ++++-- .../at/hannibal2/skyhanni/utils/CachedItemData.kt | 2 + .../at/hannibal2/skyhanni/utils/ItemCategory.kt | 51 +++++++++++ .../java/at/hannibal2/skyhanni/utils/ItemUtils.kt | 102 ++++++++++++++++----- .../at/hannibal2/skyhanni/utils/LorenzRarity.kt | 28 +----- .../at/hannibal2/skyhanni/utils/LorenzUtils.kt | 9 +- .../at/hannibal2/skyhanni/utils/UtilsPatterns.kt | 38 ++++++++ 9 files changed, 207 insertions(+), 59 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ItemCategory.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/UtilsPatterns.kt (limited to 'src/main/java/at/hannibal2') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 31816f28c..2935c8222 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -349,6 +349,7 @@ import at.hannibal2.skyhanni.utils.MinecraftConsoleFilter.Companion.initLogging import at.hannibal2.skyhanni.utils.NEUVersionCheck.checkIfNeuIsLoaded import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils import at.hannibal2.skyhanni.utils.TabListData +import at.hannibal2.skyhanni.utils.UtilsPatterns import at.hannibal2.skyhanni.utils.repopatterns.RepoPatternManager import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope @@ -432,6 +433,7 @@ class SkyHanniMod { loadModule(GardenBestCropTime()) loadModule(TrackerManager) loadModule(SkyBlockItemModifierUtils) + loadModule(UtilsPatterns) // APIs loadModule(BazaarApi()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java index 7aba8033b..9b7db7584 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java @@ -41,6 +41,11 @@ public class DebugConfig { @ConfigEditorBoolean public boolean showItemRarity = false; + @Expose + @ConfigOption(name = "Show Item Category", desc = "Show item categories in item lore.") + @ConfigEditorBoolean + public boolean showItemCategory = false; + @Expose @ConfigOption(name = "Copy Internal Name", desc = "Copies the internal name of an item on key press in the clipboard.") @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt index ec850f5dd..776d0fca1 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt @@ -19,6 +19,7 @@ import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull +import at.hannibal2.skyhanni.utils.ItemUtils.getItemCategoryOrNull import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld @@ -398,10 +399,20 @@ class SkyHanniDebugsAndTests { if (!debugConfig.showItemRarity) return val itemStack = event.itemStack - val rarity = itemStack.getItemRarityOrNull(logError = false) + val rarity = itemStack.getItemRarityOrNull() event.toolTip.add("Item rarity: $rarity") } + @SubscribeEvent + fun showItemCategory(event: LorenzToolTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!debugConfig.showItemCategory) return + val itemStack = event.itemStack + + val category = itemStack.getItemCategoryOrNull()?.name ?: "UNCLASSIFIED" + event.toolTip.add("Item category: $category") + } + @SubscribeEvent fun onSHowNpcPrice(event: LorenzToolTipEvent) { if (!LorenzUtils.inSkyBlock) return @@ -446,7 +457,7 @@ class SkyHanniDebugsAndTests { // val pitch = event.pitch // val volume = event.volume - //background music + // background music // if (soundName == "note.harp") { //// if (distance < 2) { // @@ -481,7 +492,7 @@ class SkyHanniDebugsAndTests { // } // } - //diana ancestral spade + // diana ancestral spade // if (soundName == "note.harp") { // val list = mutableListOf() // list.add(0.52380955f) @@ -556,7 +567,7 @@ class SkyHanniDebugsAndTests { // } // } - //use ancestral spade + // use ancestral spade // if (soundName == "mob.zombie.infect") { // if (pitch == 1.968254f) { // if (volume == 0.3f) { @@ -566,7 +577,7 @@ class SkyHanniDebugsAndTests { // } // } - //wither shield activated + // wither shield activated // if (soundName == "mob.zombie.remedy") { // if (pitch == 0.6984127f) { // if (volume == 1f) { @@ -575,7 +586,7 @@ class SkyHanniDebugsAndTests { // } // } - //wither shield cooldown over + // wither shield cooldown over // if (soundName == "random.levelup") { // if (pitch == 3f) { // if (volume == 1f) { @@ -584,21 +595,21 @@ class SkyHanniDebugsAndTests { // } // } - //teleport (hyp or aote) + // teleport (hyp or aote) // if (soundName == "mob.endermen.portal") { // if (pitch == 1f && volume == 1f) { // return // } // } - //hyp wither impact + // hyp wither impact // if (soundName == "random.explode") { // if (pitch == 1f && volume == 1f) { // return // } // } - //pick coins up + // pick coins up // if (soundName == "random.orb") { // if (pitch == 1.4920635f && volume == 1f) { // return diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt index 9d00958f2..e22f1cba5 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt @@ -21,4 +21,6 @@ data class CachedItemData( // null = not loaded var itemRarity: LorenzRarity? = null, + + var itemCategory: ItemCategory? = null, ) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemCategory.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemCategory.kt new file mode 100644 index 000000000..fa8003ca5 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemCategory.kt @@ -0,0 +1,51 @@ +package at.hannibal2.skyhanni.utils + +enum class ItemCategory { + SWORD, + LONGSWORD, + BOW, + SHORT_BOW, + WAND, + FISHING_WEAPON, + FISHING_ROD, + AXE, + GAUNTLET, + HOE, + PICKAXE, + SHOVEL, + DRILL, + SHEARS, + DEPLOYABLE, + VACUUM, + ABIPHONE, + BELT, + NECKLACE, + CLOAK, + GLOVES, + BRACELET, + HELMET, + CHESTPLATE, + LEGGINGS, + BOOTS, + HATCESSORY, + ACCESSORY, + POWER_STONE, + TRAVEL_SCROLL, + REFORGE_STONE, + BAIT, + PET, + TROPHY_FISH, + ARROW, + ARROW_POISON, + ITEM, + PET_ITEM, + ENCHANTED_BOOK, + POTION, + RIFT_TIMECHARM, + COSMETIC, + MEMENTO, + PORTAL, + + NONE, + ; +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index 38e1c40c0..3bc79dbf2 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.cachedData import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.gson.GsonBuilder @@ -205,42 +206,95 @@ object ItemUtils { fun ItemStack.getItemRarityOrCommon() = getItemRarityOrNull() ?: LorenzRarity.COMMON - fun ItemStack.getItemRarityOrNull(logError: Boolean = true): LorenzRarity? { - val data = cachedData - if (data.itemRarityLastCheck.asTimeMark().passedSince() < 1.seconds) { - return data.itemRarity + private fun ItemStack.readItemCategoryAndRarity(): Pair { + val name = this.name ?: "" + val cleanName = this.cleanName() + + if (isPet(cleanName)) { + return getPetRarity(this) to ItemCategory.PET } - data.itemRarityLastCheck = SimpleTimeMark.now().toMillis() + for (line in this.getLore().reversed()) { + val (category, rarity) = UtilsPatterns.rarityLoreLinePattern.matchMatcher(line) { + group("itemCategory").replace(" ", "_") to + group("rarity").replace(" ", "_") + } ?: continue + + val itemCategory = getItemCategory(category, name, cleanName) + val itemRarity = LorenzRarity.getByName(rarity) + + if (itemCategory == null) { + ErrorManager.logErrorStateWithData( + "Could not read category for item $name", + "Failed to read category from item rarity via item lore", + "internal name" to getInternalName(), + "item name" to name, + "inventory name" to InventoryUtils.openInventoryName(), + "pattern result" to category, + "lore" to getLore(), + ) + } + if (itemRarity == null) { + ErrorManager.logErrorStateWithData( + "Could not read rarity for item $name", + "Failed to read rarity from item rarity via item lore", + "internal name" to getInternalName(), + "item name" to name, + "inventory name" to InventoryUtils.openInventoryName(), + "lore" to getLore(), + ) + } + + return itemRarity to itemCategory + } + return null to null + } + + private fun getItemCategory(itemCategory: String, name: String, cleanName: String = name.removeColor()) = + if (itemCategory.isEmpty()) when { + UtilsPatterns.abiPhonePattern.matches(name) -> ItemCategory.ABIPHONE + isPet(cleanName) -> ItemCategory.PET + UtilsPatterns.enchantedBookPattern.matches(name) -> ItemCategory.ENCHANTED_BOOK + UtilsPatterns.potionPattern.matches(name) -> ItemCategory.POTION + else -> ItemCategory.NONE + } else { + LorenzUtils.enumValueOfOrNull(itemCategory) + } + + private fun ItemStack.updateCategoryAndRarity() { + val data = cachedData + data.itemRarityLastCheck = SimpleTimeMark.now().toMillis() val internalName = getInternalName() if (internalName == NEUInternalName.NONE) { data.itemRarity = null - return null + data.itemCategory = null + return } + val pair = this.readItemCategoryAndRarity() + data.itemRarity = pair.first + data.itemCategory = pair.second + } - - if (isPet(cleanName())) { - val petRarity = getPetRarity(this) - data.itemRarity = petRarity - return petRarity + fun ItemStack.getItemCategoryOrNull(): ItemCategory? { + val data = cachedData + if (itemRarityLastCheck(data)) { + this.updateCategoryAndRarity() } + return data.itemCategory + } - val rarity = LorenzRarity.readItemRarity(this) - data.itemRarity = rarity - if (rarity == null && logError) { - ErrorManager.logErrorStateWithData( - "Could not read rarity for item $name", - "Failed to read rarity from item rarity via item lore", - "internal name" to internalName, - "item name" to name, - "inventory name" to InventoryUtils.openInventoryName(), - "lore" to getLore(), - ) + fun ItemStack.getItemRarityOrNull(): LorenzRarity? { + val data = cachedData + if (itemRarityLastCheck(data)) { + this.updateCategoryAndRarity() } - return rarity + return data.itemRarity } - //extra method for shorter name and kotlin nullability logic + private fun itemRarityLastCheck(data: CachedItemData) = + data.itemRarityLastCheck.asTimeMark().passedSince() > 10.seconds + + // extra method for shorter name and kotlin nullability logic var ItemStack.name: String? get() = this.displayName set(value) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt index 64d5f8538..75412b83f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt @@ -1,12 +1,10 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.test.command.ErrorManager -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import net.minecraft.item.ItemStack - // TODO: replace id with ordinal enum class LorenzRarity(val color: LorenzColor, val id: Int) { + COMMON(LorenzColor.WHITE, 0), UNCOMMON(LorenzColor.GREEN, 1), RARE(LorenzColor.BLUE, 2), @@ -17,15 +15,11 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) { SUPREME(LorenzColor.DARK_RED, 7), SPECIAL(LorenzColor.RED, 8), VERY_SPECIAL(LorenzColor.RED, 9), - ULTIMATE_COSMETIC(LorenzColor.DARK_RED, 10), + ULTIMATE(LorenzColor.DARK_RED, 10), ; val chatColorCode by lazy { color.getChatColor() } - private val rawName by lazy { name.replace("_", " ") } - private val normalName by lazy { "$chatColorCode§l$rawName" } - private val recombName by lazy { "$chatColorCode§l§ka§r $chatColorCode§l$chatColorCode§l$rawName" } - - //§d§l§ka§r §d§l§d§lMYTHIC + val rawName = name.replace("_", " ") fun oneBelow(logError: Boolean = true): LorenzRarity? { val rarityBelow = getById(ordinal - 1) @@ -54,20 +48,8 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) { fun isAtLeast(other: LorenzRarity): Boolean = this.ordinal >= other.ordinal companion object { - fun getById(id: Int) = entries.firstOrNull { it.ordinal == id } - fun getByName(name: String) = entries.firstOrNull { it.name == name } - fun readItemRarity(itemStack: ItemStack): LorenzRarity? { - for (line in itemStack.getLore()) { - val string = line.replace("SHINY ", "") - for (rarity in LorenzRarity.entries) { - if (string.startsWith(rarity.normalName) || string.startsWith(rarity.recombName)) { - return rarity - } - } - } - return null - } + fun getById(id: Int) = if (entries.size > id) entries[id] else null + fun getByName(name: String) = entries.firstOrNull { it.name == name } } - } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 9e8fc6b8e..572aa147f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -265,7 +265,7 @@ object LorenzUtils { fun getSBMonthByName(month: String): Int { var monthNr = 0 - for (i in 1..12) { + for (i in 1 .. 12) { val monthName = SkyBlockTime.monthName(i) if (month == monthName) { monthNr = i @@ -352,7 +352,7 @@ object LorenzUtils { hover: List, command: String? = null, prefix: Boolean = true, - prefixColor: String = "§e" + prefixColor: String = "§e", ) { val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" val text = ChatComponentText(msgPrefix + message) @@ -452,7 +452,7 @@ object LorenzUtils { prefix: String, getName: (T) -> String, isCurrent: (T) -> Boolean, - crossinline onChange: (T) -> Unit + crossinline onChange: (T) -> Unit, ) = buildList { add(prefix) for (entry in enumValues()) { @@ -672,6 +672,9 @@ object LorenzUtils { enumValueOfOrNull(name) ?: kotlin.error("Unknown enum constant for ${enumValues().first().name.javaClass.simpleName}: '$name'") + inline fun > enumJoinToPattern(noinline transform: (T) -> CharSequence = { it.name }) = + enumValues().joinToString("|", transform = transform) + fun isInDevEnviromen() = Launch.blackboard["fml.deobfuscatedEnvironment"] as Boolean fun shutdownMinecraft(reason: String? = null) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/UtilsPatterns.kt b/src/main/java/at/hannibal2/skyhanni/utils/UtilsPatterns.kt new file mode 100644 index 000000000..fdaa65050 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/UtilsPatterns.kt @@ -0,0 +1,38 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.utils.LorenzUtils.enumJoinToPattern +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern + +object UtilsPatterns { + + private val patternGroup = RepoPattern.group("utils") + + /** Examples: + §d§l§ka§r §d§l§d§lMYTHIC ACCESSORY §d§l§ka + §d§l§ka§r §d§l§d§lSHINY MYTHIC DUNGEON CHESTPLATE §d§l§ka + §c§l§ka§r §c§l§c§lVERY SPECIAL HATCESSORY §c§l§ka + §6§lSHINY LEGENDARY DUNGEON BOOTS + §6§lLEGENDARY DUNGEON BOOTS + §5§lEPIC BOOTS + §f§lCOMMON + **/ + val rarityLoreLinePattern by patternGroup.pattern( + "item.lore.rarity.line", + "^(?:§.){2,3}(?:.§. (?:§.){4})?(?:SHINY )?(?${enumJoinToPattern { it.name.replace("_", " ") }}) ?(?:DUNGEON )?(?[^§]*)(?: (?:§.){3}.)?$" + ) + + val abiPhonePattern by patternGroup.pattern( + "item.name.abiphone", + ".{2}Abiphone .*" + ) + + val enchantedBookPattern by patternGroup.pattern( + "item.name.enchanted.book", + ".{2}?Enchanted Book" + ) + + val potionPattern by patternGroup.pattern( + "item.name.potion", + ".*Potion" + ) +} -- cgit