diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 6d44d7d9c8..56c28d5bb4 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -32,7 +32,9 @@ import com.google.common.eventbus.Subscribe; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; @@ -51,7 +53,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.client.callback.ClientThread; import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; -import net.runelite.http.api.item.SearchResult; @Singleton @Slf4j @@ -78,7 +79,6 @@ public class ItemManager private final ClientThread clientThread; private final ItemClient itemClient = new ItemClient(); - private final LoadingCache itemSearches; private Map itemPrices = Collections.emptyMap(); private final LoadingCache itemImages; private final LoadingCache itemCompositions; @@ -93,18 +93,6 @@ public class ItemManager scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES); - itemSearches = CacheBuilder.newBuilder() - .maximumSize(512L) - .expireAfterAccess(1, TimeUnit.HOURS) - .build(new CacheLoader() - { - @Override - public SearchResult load(String key) throws Exception - { - return itemClient.search(key); - } - }); - itemImages = CacheBuilder.newBuilder() .maximumSize(128L) .expireAfterAccess(1, TimeUnit.HOURS) @@ -205,16 +193,25 @@ public class ItemManager } /** - * Look up an item's composition + * Search for tradeable items based on item name * * @param itemName item name - * @return item search result - * @throws java.util.concurrent.ExecutionException exception when item - * is not found + * @return */ - public SearchResult searchForItem(String itemName) throws ExecutionException + public List search(String itemName) { - return itemSearches.get(itemName); + itemName = itemName.toLowerCase(); + + List result = new ArrayList<>(); + for (ItemPrice itemPrice : itemPrices.values()) + { + final String name = itemPrice.getName(); + if (name.toLowerCase().contains(itemName)) + { + result.add(itemPrice); + } + } + return result; } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 7de9f99cd0..26866c534f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -29,7 +29,6 @@ import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.io.IOException; import java.util.List; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,8 +68,7 @@ import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.hiscore.HiscoreSkill; import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; import net.runelite.http.api.hiscore.Skill; -import net.runelite.http.api.item.Item; -import net.runelite.http.api.item.SearchResult; +import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.kc.KillCountClient; @PluginDescriptor( @@ -205,7 +203,7 @@ public class ChatCommandsPlugin extends Plugin implements ChatboxInputListener String search = message.substring(PRICE_COMMAND_STRING.length() + 1); log.debug("Running price lookup for {}", search); - executor.submit(() -> itemPriceLookup(setMessage.getMessageNode(), search)); + itemPriceLookup(setMessage.getMessageNode(), search); } else if (config.lvl() && message.toLowerCase().startsWith(LEVEL_COMMAND_STRING + " ")) { @@ -457,29 +455,14 @@ public class ChatCommandsPlugin extends Plugin implements ChatboxInputListener */ private void itemPriceLookup(MessageNode messageNode, String search) { - SearchResult result; + List results = itemManager.search(search); - try + if (!results.isEmpty()) { - result = itemManager.searchForItem(search); - } - catch (ExecutionException ex) - { - log.warn("Unable to search for item {}", search, ex); - return; - } - - if (result != null && !result.getItems().isEmpty()) - { - Item item = retrieveFromList(result.getItems(), search); - if (item == null) - { - log.debug("Unable to find item {} in result {}", search, result); - return; - } + ItemPrice item = retrieveFromList(results, search); int itemId = item.getId(); - int itemPrice = itemManager.getItemPrice(itemId); + int itemPrice = item.getPrice(); final ChatMessageBuilder builder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) @@ -767,23 +750,31 @@ public class ChatCommandsPlugin extends Plugin implements ChatboxInputListener /** * Compares the names of the items in the list with the original input. - * Returns the item if its name is equal to the original input or null - * if it can't find the item. + * Returns the item if its name is equal to the original input or the + * shortest match if no exact match is found. * * @param items List of items. * @param originalInput String with the original input. * @return Item which has a name equal to the original input. */ - private Item retrieveFromList(List items, String originalInput) + private ItemPrice retrieveFromList(List items, String originalInput) { - for (Item item : items) + ItemPrice shortest = null; + for (ItemPrice item : items) { if (item.getName().toLowerCase().equals(originalInput.toLowerCase())) { return item; } + + if (shortest == null || item.getName().length() < shortest.getName().length()) + { + shortest = item; + } } - return null; + + // Take a guess + return shortest; } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java index 870df19458..af827227ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java @@ -50,8 +50,7 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.components.IconTextField; import net.runelite.client.ui.components.PluginErrorPanel; import net.runelite.client.util.RunnableExceptionLogger; -import net.runelite.http.api.item.Item; -import net.runelite.http.api.item.SearchResult; +import net.runelite.http.api.item.ItemPrice; /** * This panel holds the search section of the Grand Exchange Plugin. @@ -169,19 +168,13 @@ class GrandExchangeSearchPanel extends JPanel searchBar.setEditable(false); searchBar.setIcon(IconTextField.Icon.LOADING); - SearchResult result; - - try + List result = itemManager.search(lookup); + if (result.isEmpty()) { - result = itemManager.searchForItem(lookup); - } - catch (Exception ex) // handle com.google.common.cache.CacheLoader$InvalidCacheLoadException - { - log.warn("Unable to search for item {}", lookup, ex); searchBar.setIcon(IconTextField.Icon.ERROR); - searchBar.setEditable(true); - errorPanel.setContent("Error fetching results", "An error occurred while trying to fetch item data, please try again later."); + errorPanel.setContent("No results found.", "No items were found with that name, please try again."); cardLayout.show(centerPanel, ERROR_PANEL); + searchBar.setEditable(true); return; } @@ -189,42 +182,33 @@ class GrandExchangeSearchPanel extends JPanel clientThread.invokeLater(() -> processResult(result, lookup, exactMatch)); } - private void processResult(SearchResult result, String lookup, boolean exactMatch) + private void processResult(List result, String lookup, boolean exactMatch) { itemsList.clear(); - if (result != null && !result.getItems().isEmpty()) - { - cardLayout.show(centerPanel, RESULTS_PANEL); + cardLayout.show(centerPanel, RESULTS_PANEL); - for (Item item : result.getItems()) + for (ItemPrice item : result) + { + int itemId = item.getId(); + + ItemComposition itemComp = itemManager.getItemComposition(itemId); + if (itemComp == null) { - int itemId = item.getId(); - - ItemComposition itemComp = itemManager.getItemComposition(itemId); - if (itemComp == null) - { - continue; - } - - int itemPrice = itemManager.getItemPrice(itemId); - int itemLimit = itemGELimits.getOrDefault(itemId, 0); - AsyncBufferedImage itemImage = itemManager.getImage(itemId); - - itemsList.add(new GrandExchangeItems(itemImage, item.getName(), itemId, itemPrice, itemComp.getPrice() * 0.6, itemLimit)); - - // If using hotkey to lookup item, stop after finding match. - if (exactMatch && item.getName().equalsIgnoreCase(lookup)) - { - break; - } + continue; + } + + int itemPrice = item.getPrice(); + int itemLimit = itemGELimits.getOrDefault(itemId, 0); + AsyncBufferedImage itemImage = itemManager.getImage(itemId); + + itemsList.add(new GrandExchangeItems(itemImage, item.getName(), itemId, itemPrice, itemComp.getPrice() * 0.6, itemLimit)); + + // If using hotkey to lookup item, stop after finding match. + if (exactMatch && item.getName().equalsIgnoreCase(lookup)) + { + break; } - } - else - { - searchBar.setIcon(IconTextField.Icon.ERROR); - errorPanel.setContent("No results found.", "No items were found with that name, please try again."); - cardLayout.show(centerPanel, ERROR_PANEL); } SwingUtilities.invokeLater(() ->