From a321287e85fb577745647d12049fc1d24997717c Mon Sep 17 00:00:00 2001 From: nea Date: Sat, 14 Jan 2023 22:59:19 +0100 Subject: Use common utility methods for all museum features --- .../notenoughupdates/options/NEUConfig.java | 7 ++ .../options/seperateSections/MiscOverlays.java | 44 -------- .../options/seperateSections/Museum.java | 64 ++++++++++++ .../notenoughupdates/util/ItemResolutionQuery.java | 74 ++++++++++---- .../inventory/MuseumCheapestItemOverlay.kt | 100 +++++------------- .../inventory/MuseumItemHighlighter.kt | 37 +++---- .../moulberry/notenoughupdates/util/MuseumUtil.kt | 113 +++++++++++++++++++++ 7 files changed, 273 insertions(+), 166 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java create mode 100644 src/main/kotlin/io/github/moulberry/notenoughupdates/util/MuseumUtil.kt diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 6822ab75..4f524c26 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -54,6 +54,7 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.Mining; import io.github.moulberry.notenoughupdates.options.seperateSections.MinionHelper; import io.github.moulberry.notenoughupdates.options.seperateSections.Misc; import io.github.moulberry.notenoughupdates.options.seperateSections.MiscOverlays; +import io.github.moulberry.notenoughupdates.options.seperateSections.Museum; import io.github.moulberry.notenoughupdates.options.seperateSections.NeuAuctionHouse; import io.github.moulberry.notenoughupdates.options.seperateSections.Notifications; import io.github.moulberry.notenoughupdates.options.seperateSections.PetOverlay; @@ -181,6 +182,12 @@ public class NEUConfig extends Config { ) public Misc misc = new Misc(); + @Expose + @Category( + name = "Museum",desc = "Musem overlays" + ) + public Museum museum = new Museum(); + @Expose @Category( name = "GUI Locations", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java index f6710514..064a9304 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java @@ -432,48 +432,4 @@ public class MiscOverlays { @ConfigAccordionId(id = 0) public boolean todoIcons = true; - @ConfigOption( - name = "Museum Overlay", - desc = "" - ) - @ConfigEditorAccordion(id = 1) - public boolean museumAccordion = true; - - @Expose - @ConfigOption( - name = "Show Museum Items", - desc = "Show real items instead of green dye in the museum" - ) - @ConfigAccordionId(id = 1) - @ConfigEditorBoolean - public boolean museumItemShow = true; - - @Expose - @ConfigOption( - name = "Highlight virtual museum items", - desc = "Highlight virtual museum items with a background color" - ) - @ConfigAccordionId(id = 1) - @ConfigEditorColour - public String museumItemColor = "0:255:0:255:0"; - - @Expose - @ConfigOption( - name = "Show Items to donate", - desc = "Show the cheapest items you have not yet donated to the Museum" - ) - @ConfigEditorBoolean - @ConfigAccordionId(id = 1) - public boolean museumCheapestItemOverlay = true; - - @Expose - @ConfigOption( - name = "Value calculation", - desc = "Choose the source for the value calculation" - ) - @ConfigEditorDropdown( - values = {"Lowest BIN", "Craft cost"} - ) - @ConfigAccordionId(id = 1) - public int museumCheapestItemOverlayValueSource = 0; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java new file mode 100644 index 00000000..6f03c2bb --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorColour; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; + +public class Museum { + + @Expose + @ConfigOption( + name = "Show Museum Items", + desc = "Show real items instead of green dye in the museum" + ) + @ConfigEditorBoolean + public boolean museumItemShow = false; + + @Expose + @ConfigOption( + name = "Highlight virtual museum items", + desc = "Highlight virtual museum items with a background color" + ) + @ConfigEditorColour + public String museumItemColor = "0:255:0:255:0"; + + @Expose + @ConfigOption( + name = "Show Items to donate", + desc = "Show the cheapest items you have not yet donated to the Museum" + ) + @ConfigEditorBoolean + public boolean museumCheapestItemOverlay = true; + + @Expose + @ConfigOption( + name = "Value calculation", + desc = "Choose the source for the value calculation" + ) + @ConfigEditorDropdown( + values = {"Lowest BIN", "Craft cost"} + ) + public int museumCheapestItemOverlayValueSource = 0; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java index e5c1b9ad..280a0d3d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java @@ -24,6 +24,7 @@ import com.google.gson.JsonParseException; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import lombok.var; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.inventory.GuiChest; @@ -36,9 +37,10 @@ import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nullable; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -188,31 +190,63 @@ public class ItemResolutionQuery { return null; } + /** + * Search for an item by the display name + * + * @param displayName The display name of the item we are searching + * @param mayBeMangled Whether the item name may be mangled (for example: reforges, stars) + * @return the internal neu item id of that item, or null + */ + public static String findInternalNameByDisplayName(String displayName, boolean mayBeMangled) { + var cleanDisplayName = StringUtils.cleanColour(displayName); + var manager = NotEnoughUpdates.INSTANCE.manager; + String bestMatch = null; + int bestMatchLength = -1; + for (String internalName : findInternalNameCandidatesForDisplayName(cleanDisplayName)) { + var item = manager.createItem(internalName); + if (item.getDisplayName() == null) continue; + var cleanItemDisplayName = StringUtils.cleanColour(item.getDisplayName()); + if (cleanItemDisplayName.length() == 0) continue; + if (mayBeMangled + ? !cleanDisplayName.contains(cleanItemDisplayName) + : !cleanItemDisplayName.equals(cleanDisplayName)) { + continue; + } + if (cleanItemDisplayName.length() > bestMatchLength) { + bestMatchLength = cleanItemDisplayName.length(); + bestMatch = internalName; + } + } + return bestMatch; + } + + /** + * Find potential item ids for a given display name. This function is over eager to give results, + * and may give invalid results, but if there is a matching item in the repository it will return at least + * that item. This should be used as a first filtering pass. Use {@link #findInternalNameByDisplayName} for a more + * user-friendly API. + * + * @param displayName The display name of the item we are searching + * @return a list of internal neu item ids some of which may have a matching display name + */ + public static Set findInternalNameCandidatesForDisplayName(String displayName) { + var cleanDisplayName = NEUManager.cleanForTitleMapSearch(displayName); + var titleWordMap = NotEnoughUpdates.INSTANCE.manager.titleWordMap; + var candidates = new HashSet(); + for (var partialDisplayName : cleanDisplayName.split(" ")) { + if (!titleWordMap.containsKey(partialDisplayName)) continue; + candidates.addAll(titleWordMap.get(partialDisplayName).keySet()); + } + return candidates; + } + private String resolveItemInCatacombsRngMeter() { List lore = ItemUtils.getLore(compound); if (lore.size() > 16) { String s = lore.get(15); if (s.equals("§7Selected Drop")) { String displayName = lore.get(16); - return getInternalNameByDisplayName(displayName); - } - } - - return null; - } - - public static String getInternalNameByDisplayName(String displayName) { - String cleanDisplayName = StringUtils.cleanColour(displayName); - for (Map.Entry entry : NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .entrySet()) { - - JsonObject object = entry.getValue(); - if (object.has("displayname")) { - String name = object.get("displayname").getAsString(); - if (StringUtils.cleanColour(name).equals(cleanDisplayName)) { - return entry.getKey(); - } + return findInternalNameByDisplayName(displayName, false); } } diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt index fe2dd1e1..7485f14d 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt @@ -19,20 +19,18 @@ package io.github.moulberry.notenoughupdates.miscfeatures.inventory -import io.github.moulberry.notenoughupdates.NEUManager import io.github.moulberry.notenoughupdates.NotEnoughUpdates import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer -import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery +import io.github.moulberry.notenoughupdates.util.MuseumUtil +import io.github.moulberry.notenoughupdates.util.MuseumUtil.DonationState.MISSING import io.github.moulberry.notenoughupdates.util.Utils -import io.github.moulberry.notenoughupdates.util.stripControlCodes import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiScreen import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.client.renderer.GlStateManager import net.minecraft.init.Items import net.minecraft.inventory.Slot -import net.minecraft.item.ItemDye import net.minecraft.util.EnumChatFormatting import net.minecraft.util.ResourceLocation import net.minecraftforge.client.event.GuiScreenEvent @@ -52,9 +50,9 @@ object MuseumCheapestItemOverlay { private const val ITEMS_PER_PAGE = 8 - private val backgroundResource: ResourceLocation by lazy { - ResourceLocation("notenoughupdates:dungeon_chest_worth.png") - } + private val backgroundResource: ResourceLocation = ResourceLocation("notenoughupdates:dungeon_chest_worth.png") + + val config get() = NotEnoughUpdates.INSTANCE.config.museum /** * The top left position of the arrows to be drawn, used by [ArrowPagesUtils] @@ -140,7 +138,7 @@ object MuseumCheapestItemOverlay { var totalValue = 0.0 internalNames.forEach { val itemValue: Double = - when (NotEnoughUpdates.INSTANCE.config.miscOverlays.museumCheapestItemOverlayValueSource) { + when (config.museumCheapestItemOverlayValueSource) { 0 -> NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarOrBin(it, false) 1 -> NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(it)?.craftCost ?: return@forEach else -> -1.0 //unreachable @@ -210,42 +208,25 @@ object MuseumCheapestItemOverlay { * Parse the not already donated items present in the currently open Museum page */ private fun parseItems(slots: List) { - //iterate upper chest with 56 slots + // Iterate upper chest with 56 slots val time = System.currentTimeMillis() + val armor = Utils.getOpenChestName().endsWith("Armor Sets") for (i in 0..53) { val stack = slots[i].stack ?: continue - //check for gray dye which indicates that the item has not been donated - if (stack.item is ItemDye && stack.itemDamage == 8) { - val name = stack.displayName.stripControlCodes() - val armor = Utils.getOpenChestName().endsWith("Armor Sets") - val internalNames = guessInternalNames(name, armor) - val value = calculateValue(internalNames) - - val displayName = if (armor) { - "${EnumChatFormatting.BLUE}$name" - } else { - NotEnoughUpdates.INSTANCE.manager.getDisplayName(internalNames[0]) ?: "ERROR" - } + val parsedItems = MuseumUtil.findMuseumItem(stack, armor) ?: continue + when (parsedItems.state) { + MISSING -> + if (itemsToDonate.none { it.internalNames == parsedItems.skyblockItemIds }) + itemsToDonate.add( + MuseumItem( + stack.displayName, + parsedItems.skyblockItemIds, + calculateValue(parsedItems.skyblockItemIds), + time + ) + ) - //make sure this item does not already exist - if (itemsToDonate.none { it.internalNames == internalNames }) { - itemsToDonate.add(MuseumItem(displayName, internalNames, value, time)) - } - } else if (stack.item is ItemDye && stack.itemDamage == 10) { //also check donated items - val name = stack.displayName.stripControlCodes() - val armor = Utils.getOpenChestName().endsWith("Armor Sets") - val internalNames = guessInternalNames(name, armor) - //remove items that have these internalnames - itemsToDonate.retainAll { it.internalNames != internalNames } - } else { - var name = listOf( - NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack) - .resolveInternalName() - ) - if (name[0] == null) { - name = guessInternalNames(stack.displayName, true) - } - itemsToDonate.retainAll { it.internalNames != name } + else -> itemsToDonate.retainAll { it.internalNames != parsedItems.skyblockItemIds } } } } @@ -256,47 +237,12 @@ object MuseumCheapestItemOverlay { private fun checkIfHighestPageWasVisited(slots: List) { val category = getCategory() val nextPageSlot = slots[53] - //if the "Next Page" arrow is missing, we are at the highest page + // If the "Next Page" arrow is missing, we are at the highest page if ((nextPageSlot.stack ?: return).item != Items.arrow) { checkedPages[category] = true } } - /** - * Try to guess the internal names for a given item from the Museum. Due to Hypixels naming inconsistencies this does not work on every armor set - */ - private fun guessInternalNames(itemName: String, armor: Boolean): List { - return if (armor) { - val mustHaves = arrayOf( - "HELMET", - "LEGGINGS", - "CHESTPLATE", - "BOOTS" - ) - val monochromeName = NEUManager.cleanForTitleMapSearch(itemName) - val candidates = monochromeName.split(" ") - .asSequence() - .mapNotNull { NotEnoughUpdates.INSTANCE.manager.titleWordMap[it]?.keys } - .flatten() - .filter { - val item = NotEnoughUpdates.INSTANCE.manager.createItem(it) - val name = NEUManager.cleanForTitleMapSearch(item.displayName) - monochromeName.replace("armor", "") in name - }.filter { item -> - mustHaves.any { - item.contains(it) - } - } - //filter out duplicates - .toSet() - .toList() - - return candidates - } else { - listOf(ItemResolutionQuery.getInternalNameByDisplayName(itemName)) - } - } - /** * Draw the background texture to the right side of the open Museum Page */ @@ -321,7 +267,7 @@ object MuseumCheapestItemOverlay { * Determine if the overlay should be active based on the config option and the currently open GuiChest, if applicable */ private fun shouldRender(gui: GuiScreen): Boolean = - NotEnoughUpdates.INSTANCE.config.miscOverlays.museumCheapestItemOverlay && gui is GuiChest && Utils.getOpenChestName() + config.museumCheapestItemOverlay && gui is GuiChest && Utils.getOpenChestName() .startsWith("Museum ➜") /** diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt index 63b88094..b809ee9f 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 NotEnoughUpdates contributors + * Copyright (C) 2022 Linnea Gräf * * This file is part of NotEnoughUpdates. * @@ -19,51 +19,42 @@ package io.github.moulberry.notenoughupdates.miscfeatures.inventory -import io.github.moulberry.notenoughupdates.NEUManager import io.github.moulberry.notenoughupdates.NotEnoughUpdates import io.github.moulberry.notenoughupdates.core.ChromaColour import io.github.moulberry.notenoughupdates.core.util.StringUtils import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent +import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery import io.github.moulberry.notenoughupdates.util.ItemUtils import io.github.moulberry.notenoughupdates.util.LRUCache +import io.github.moulberry.notenoughupdates.util.MuseumUtil import net.minecraft.client.gui.Gui import net.minecraft.init.Items import net.minecraft.inventory.ContainerChest import net.minecraft.inventory.IInventory -import net.minecraft.inventory.Slot import net.minecraft.item.EnumDyeColor import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object MuseumItemHighlighter { - val manager get() = NotEnoughUpdates.INSTANCE.manager - val config get() = NotEnoughUpdates.INSTANCE.config.miscOverlays + private val manager get() = NotEnoughUpdates.INSTANCE.manager + private val config get() = NotEnoughUpdates.INSTANCE.config.museum - fun getHighlightColor() = ChromaColour.specialToChromaRGB(config.museumItemColor) + private fun getHighlightColor() = ChromaColour.specialToChromaRGB(config.museumItemColor) - val findRawItemForName = LRUCache.memoize(::findRawItemForName0, 4 * 7 * 2) + private val findRawItemForName = LRUCache.memoize(::findRawItemForName0, 4 * 7 * 2) @SubscribeEvent fun onRepositoryReload(event: RepositoryReloadEvent) { findRawItemForName.clearCache() } - fun findRawItemForName0(name: String): ItemStack? { - val monochromeName = NEUManager.cleanForTitleMapSearch(name) - return monochromeName.split(" ") - .mapNotNull { manager.titleWordMap[it]?.keys } - .flatten() - .toSet() - .asSequence() - .map { manager.createItem(it) } - .filter { - it.displayName != null && it.displayName.isNotEmpty() && NEUManager.cleanForTitleMapSearch(it.displayName) in monochromeName - } - .maxByOrNull { it.displayName.length } + private fun findRawItemForName0(arg: Pair): ItemStack? { + val (name, armor) = arg + return MuseumUtil.findItemsByName(name, armor).firstOrNull()?.let { manager.createItem(it) } } @@ -73,7 +64,8 @@ object MuseumItemHighlighter { if (!isMuseumInventory(event.inventory)) return val original = event.original ?: return if (!isCompletedRetrievedItem(original)) return - val rawItem = findRawItemForName.apply(original.displayName) ?: return + val armor = StringUtils.cleanColour(event.inventory.displayName.unformattedText).endsWith("Armor Sets") + val rawItem = findRawItemForName.apply(original.displayName to armor) ?: return val hydratedItem = hydrateMuseumItem(rawItem, original) event.replaceWith(hydratedItem) } @@ -122,11 +114,6 @@ object MuseumItemHighlighter { return ItemUtils.getOrCreateTag(stack).getBoolean(MUSEUM_HYDRATED_ITEM_TAG) } - @JvmStatic - fun onDrawSlot(slotIn: Slot) { - - } - const val MUSEUM_HYDRATED_ITEM_TAG = "NEU_HYDRATED_MUSEUM_ITEM" } diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/MuseumUtil.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/MuseumUtil.kt new file mode 100644 index 00000000..dd52d175 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/MuseumUtil.kt @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.util + +import io.github.moulberry.notenoughupdates.NEUManager +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import net.minecraft.item.EnumDyeColor +import net.minecraft.item.ItemDye +import net.minecraft.item.ItemStack + +object MuseumUtil { + + data class MuseumItem( + /** + * A potentially non-exhaustive list of item ids that are required for this museum donation. + */ + val skyblockItemIds: List, + val state: DonationState, + ) + + enum class DonationState { + /** + * Donated armor only shows one piece, so we use that for id resolution, which might result in incomplete + * results (hence the separate state). This still means that the entire set is donated, but it is guaranteed to + * be only a partial result. Other values of this enum do not guarantee a full result, but at least they do not + * guarantee a partial one. + */ + DONATED_PRESENT_PARTIAL, + DONATED_PRESENT, + DONATED_VACANT, + MISSING, + } + + fun findMuseumItem(stack: ItemStack, isOnArmorPage: Boolean): MuseumItem? { + val item = stack.item ?: return null + val items by lazy { findItemsByName(stack.displayName, isOnArmorPage)} + if (item is ItemDye) { + val dyeColor = EnumDyeColor.byDyeDamage(stack.itemDamage) + if (dyeColor == EnumDyeColor.LIME) { + // Item is donated, but not present in the museum + return MuseumItem(items, DonationState.DONATED_VACANT) + } else if (dyeColor == EnumDyeColor.GRAY) { + // Item is not donated + return MuseumItem(items, DonationState.MISSING) + } + // Otherwise unknown item, try to analyze as normal item. + } + val skyblockId = NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack) + .resolveInternalName() + if (skyblockId != null) { + return MuseumItem( + listOf(skyblockId), + if (isOnArmorPage) DonationState.DONATED_PRESENT_PARTIAL else DonationState.DONATED_PRESENT + ) + } + return MuseumItem( + items, + DonationState.DONATED_PRESENT + ) + } + + fun findItemsByName(displayName: String, armor: Boolean): List { + return (if (armor) + findMuseumArmorSetByName(displayName) + else + listOf(findMuseumItemByName(displayName))).filterNotNull() + + } + + fun findMuseumItemByName(displayName: String): String? = + ItemResolutionQuery.findInternalNameByDisplayName(displayName, true) + + + fun findMuseumArmorSetByName(displayName: String): List { + val armorSlots = arrayOf( + "HELMET", + "LEGGINGS", + "CHESTPLATE", + "BOOTS" + ) + val monochromeName = NEUManager.cleanForTitleMapSearch(displayName) + val results = ItemResolutionQuery.findInternalNameCandidatesForDisplayName(displayName) + .asSequence() + .filter { + val item = NotEnoughUpdates.INSTANCE.manager.createItem(it) + val name = NEUManager.cleanForTitleMapSearch(item.displayName) + monochromeName.replace("armor", "") in name + } + .toSet() + return armorSlots.map { armorSlot -> + results.singleOrNull { armorSlot in it } + } + } + + +} -- cgit