From 594573faebd72175a29c23153e6336b4c7e3ed1a Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 1 Aug 2018 22:00:05 -0600 Subject: [PATCH 1/2] runelite-client: Make ItemManager's price update thread safe --- .../java/net/runelite/client/game/ItemManager.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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 764b30ddfe..aaefdcce9b 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 @@ -27,12 +27,13 @@ package net.runelite.client.game; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableMap; import com.google.common.eventbus.Subscribe; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import java.util.Collections; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -77,7 +78,7 @@ public class ItemManager private final ItemClient itemClient = new ItemClient(); private final LoadingCache itemSearches; - private final ConcurrentMap itemPrices = new ConcurrentHashMap<>(); + private Map itemPrices = Collections.emptyMap(); private final LoadingCache itemImages; private final LoadingCache itemCompositions; private final LoadingCache itemOutlines; @@ -147,11 +148,12 @@ public class ItemManager ItemPrice[] prices = itemClient.getPrices(); if (prices != null) { - itemPrices.clear(); + ImmutableMap.Builder map = ImmutableMap.builderWithExpectedSize(prices.length); for (ItemPrice price : prices) { - itemPrices.put(price.getItem().getId(), price); + map.put(price.getItem().getId(), price); } + itemPrices = map.build(); } log.debug("Loaded {} prices", itemPrices.size()); From b4f95f1f4b0bfdc0075849e5f3611e0be45bbb17 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 1 Aug 2018 23:40:41 -0600 Subject: [PATCH 2/2] runelite-client: Always use the mapped price for items --- .../net/runelite/client/game/ItemManager.java | 27 ++++++++++++++++--- .../plugins/bankvalue/BankCalculation.java | 17 +----------- .../client/plugins/barrows/BarrowsPlugin.java | 9 +------ .../chatcommands/ChatCommandsPlugin.java | 5 ++-- .../client/plugins/examine/ExaminePlugin.java | 8 +----- .../GrandExchangeSearchPanel.java | 5 ++-- .../grounditems/GroundItemsPlugin.java | 11 +++----- .../plugins/itemprices/ItemPricesOverlay.java | 7 +---- .../loottracker/LootTrackerPlugin.java | 17 +----------- 9 files changed, 35 insertions(+), 71 deletions(-) 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 aaefdcce9b..d1361568a6 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 @@ -45,6 +45,7 @@ import net.runelite.api.Client; import static net.runelite.api.Constants.CLIENT_DEFAULT_ZOOM; import net.runelite.api.GameState; import net.runelite.api.ItemComposition; +import net.runelite.api.ItemID; import net.runelite.api.SpritePixels; import net.runelite.api.events.GameStateChanged; import net.runelite.client.callback.ClientThread; @@ -176,13 +177,31 @@ public class ItemManager /** * Look up an item's price * - * @param itemId item id + * @param itemID item id * @return item price */ - public ItemPrice getItemPrice(int itemId) + public int getItemPrice(int itemID) { - itemId = ItemMapping.mapFirst(itemId); - return itemPrices.get(itemId); + if (itemID == ItemID.COINS_995) + { + return 1; + } + if (itemID == ItemID.PLATINUM_TOKEN) + { + return 1000; + } + + int price = 0; + for (int mappedID : ItemMapping.map(itemID)) + { + ItemPrice ip = itemPrices.get(mappedID); + if (ip != null) + { + price += ip.getPrice(); + } + } + + return price; } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bankvalue/BankCalculation.java b/runelite-client/src/main/java/net/runelite/client/plugins/bankvalue/BankCalculation.java index 19a6b6399a..b22df90da9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bankvalue/BankCalculation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bankvalue/BankCalculation.java @@ -38,9 +38,7 @@ import static net.runelite.api.ItemID.PLATINUM_TOKEN; import net.runelite.api.queries.BankItemQuery; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemMapping; import net.runelite.client.util.QueryRunner; -import net.runelite.http.api.item.ItemPrice; @Slf4j class BankCalculation @@ -143,20 +141,7 @@ class BankCalculation continue; } - long price = 0; - for (int mappedItemId : ItemMapping.map(itemId)) - { - ItemPrice cachedItemPrice = itemManager.getItemPrice(mappedItemId); - if (cachedItemPrice == null) - { - // this happens to items which have no ge price - continue; - } - - price += cachedItemPrice.getPrice(); - } - - gePrice += price * quantity; + gePrice += (long) itemManager.getItemPrice(itemId) * quantity; } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java index c13618059d..2ee16a6a43 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -62,7 +62,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.StackFormatter; -import net.runelite.http.api.item.ItemPrice; @PluginDescriptor( name = "Barrows Brothers", @@ -222,13 +221,7 @@ public class BarrowsPlugin extends Plugin for (Item item : items) { - ItemPrice cachedItemPrice = itemManager.getItemPrice(item.getId()); - if (cachedItemPrice == null) - { - continue; - } - - long itemStack = (long) cachedItemPrice.getPrice() * (long) item.getQuantity(); + long itemStack = (long) itemManager.getItemPrice(item.getId()) * (long) item.getQuantity(); chestPrice += itemStack; } 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 ef7df50c62..a8f70861cf 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 @@ -70,7 +70,6 @@ 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.ItemPrice; import net.runelite.http.api.item.SearchResult; import net.runelite.http.api.kc.KillCountClient; @@ -480,7 +479,7 @@ public class ChatCommandsPlugin extends Plugin implements ChatboxInputListener } int itemId = item.getId(); - ItemPrice itemPrice = itemManager.getItemPrice(itemId); + int itemPrice = itemManager.getItemPrice(itemId); final ChatMessageBuilder builder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) @@ -490,7 +489,7 @@ public class ChatCommandsPlugin extends Plugin implements ChatboxInputListener .append(ChatColorType.NORMAL) .append(": GE average ") .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(itemPrice.getPrice())); + .append(StackFormatter.formatNumber(itemPrice)); ItemComposition itemComposition = itemManager.getItemComposition(itemId); if (itemComposition != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index a28926a2be..6818e2b70b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -53,7 +53,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.StackFormatter; import net.runelite.http.api.examine.ExamineClient; -import net.runelite.http.api.item.ItemPrice; /** * Submits exammine info to the api @@ -272,14 +271,9 @@ public class ExaminePlugin extends Plugin final boolean note = itemComposition.getNote() != -1; final int id = note ? itemComposition.getLinkedNoteId() : itemComposition.getId(); - ItemPrice itemPrice = itemManager.getItemPrice(id); - if (itemPrice == null) - { - return; - } int itemCompositionPrice = itemComposition.getPrice(); - final int gePrice = itemPrice == null ? 0 : itemPrice.getPrice(); + final int gePrice = itemManager.getItemPrice(id); final int alchPrice = itemCompositionPrice <= 0 ? 0 : Math.round(itemCompositionPrice * HIGH_ALCHEMY_CONSTANT); if (gePrice > 0 || alchPrice > 0) 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 d57e599021..addbf7dabe 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,7 +50,6 @@ import net.runelite.client.ui.components.PluginErrorPanel; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.RunnableExceptionLogger; import net.runelite.http.api.item.Item; -import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.SearchResult; /** @@ -222,10 +221,10 @@ class GrandExchangeSearchPanel extends JPanel continue; } - ItemPrice itemPrice = itemManager.getItemPrice(itemId); + int itemPrice = itemManager.getItemPrice(itemId); AsyncBufferedImage itemImage = itemManager.getImage(itemId); - itemsList.add(new GrandExchangeItems(itemImage, item.getName(), itemId, itemPrice != null ? itemPrice.getPrice() : 0, itemComp.getPrice() * 0.6)); + itemsList.add(new GrandExchangeItems(itemImage, item.getName(), itemId, itemPrice, itemComp.getPrice() * 0.6)); // If using hotkey to lookup item, stop after finding match. if (exactMatch && item.getName().equalsIgnoreCase(lookup)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index dbf106bd04..42b4ab8583 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -76,7 +76,6 @@ import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.N import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.OPTION; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import net.runelite.http.api.item.ItemPrice; @PluginDescriptor( name = "Ground Items", @@ -277,11 +276,7 @@ public class GroundItemsPlugin extends Plugin } else { - final ItemPrice itemPrice = itemManager.getItemPrice(realItemId); - if (itemPrice != null) - { - groundItem.setGePrice(itemPrice.getPrice()); - } + groundItem.setGePrice(itemManager.getItemPrice(realItemId)); } return groundItem; @@ -369,8 +364,8 @@ public class GroundItemsPlugin extends Plugin final ItemComposition itemComposition = itemManager.getItemComposition(itemId); final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemComposition.getId(); - final ItemPrice itemPrice = itemManager.getItemPrice(realItemId); - final int price = itemPrice == null ? itemComposition.getPrice() : itemPrice.getPrice(); + final int itemPrice = itemManager.getItemPrice(realItemId); + final int price = itemPrice <= 0 ? itemComposition.getPrice() : itemPrice; final int haPrice = Math.round(itemComposition.getPrice() * HIGH_ALCHEMY_CONSTANT) * quantity; final int gePrice = quantity * price; final Color hidden = getHidden(itemComposition.getName(), gePrice, haPrice, itemComposition.isTradeable()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java index 591fefe625..7e170db214 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java @@ -45,7 +45,6 @@ import net.runelite.client.ui.overlay.tooltip.Tooltip; import net.runelite.client.ui.overlay.tooltip.TooltipManager; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.StackFormatter; -import net.runelite.http.api.item.ItemPrice; class ItemPricesOverlay extends Overlay { @@ -200,11 +199,7 @@ class ItemPricesOverlay extends Overlay if (config.showGEPrice()) { - final ItemPrice price = itemManager.getItemPrice(id); - if (price != null) - { - gePrice = price.getPrice(); - } + gePrice = itemManager.getItemPrice(id); } if (config.showHAValue()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 35fe556174..f3cb7eb233 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -42,7 +42,6 @@ import net.runelite.api.Client; import net.runelite.api.InventoryID; import net.runelite.api.ItemComposition; import net.runelite.api.ItemContainer; -import net.runelite.api.ItemID; import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.SpriteID; @@ -60,7 +59,6 @@ import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.http.api.item.ItemPrice; @PluginDescriptor( name = "Loot Tracker", @@ -253,20 +251,7 @@ public class LootTrackerPlugin extends Plugin { final ItemComposition itemComposition = itemManager.getItemComposition(itemStack.getId()); final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemStack.getId(); - final ItemPrice itemPrice = itemManager.getItemPrice(realItemId); - final long price; - if (itemPrice != null) - { - price = (long) itemPrice.getPrice() * itemStack.getQuantity(); - } - else if (realItemId == ItemID.COINS_995) - { - price = itemStack.getQuantity(); - } - else - { - price = 0; - } + final long price = (long)itemManager.getItemPrice(realItemId) * (long)itemStack.getQuantity(); return new LootTrackerItemEntry( itemStack.getId(),