runelite-client: update for search api changes

This moves the item search locally and does a contains check instead of
requiring item searches to contain full item names.

Fixes assert fail introduced in b72bda1c75 from
fetching item compositions on the executor thread in the !price command.
This commit is contained in:
Adam
2018-10-07 12:30:38 -04:00
parent 7adca5bda2
commit 3129fea229
3 changed files with 62 additions and 90 deletions

View File

@@ -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<String, SearchResult> itemSearches;
private Map<Integer, ItemPrice> itemPrices = Collections.emptyMap();
private final LoadingCache<ImageKey, AsyncBufferedImage> itemImages;
private final LoadingCache<Integer, ItemComposition> 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<String, SearchResult>()
{
@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<ItemPrice> search(String itemName)
{
return itemSearches.get(itemName);
itemName = itemName.toLowerCase();
List<ItemPrice> result = new ArrayList<>();
for (ItemPrice itemPrice : itemPrices.values())
{
final String name = itemPrice.getName();
if (name.toLowerCase().contains(itemName))
{
result.add(itemPrice);
}
}
return result;
}
/**

View File

@@ -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<ItemPrice> 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<Item> items, String originalInput)
private ItemPrice retrieveFromList(List<ItemPrice> 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;
}
/**

View File

@@ -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<ItemPrice> 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<ItemPrice> 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(() ->