diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 208946ff83..94b3ec686d 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -25,9 +25,9 @@ object ProjectVersions { const val launcherVersion = "2.2.0" - const val rlVersion = "1.7.2" + const val rlVersion = "1.7.2.2" - const val openosrsVersion = "4.0.1" + const val openosrsVersion = "4.1.0" const val rsversion = 194 const val cacheversion = 165 diff --git a/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java index 6f4b003df0..feec0f6d66 100644 --- a/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java +++ b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java @@ -43,10 +43,7 @@ public class ColorTypeAdapter extends TypeAdapter } int rgba = value.getRGB(); - out.beginObject() - .name("value") - .value(rgba) - .endObject(); + out.value(String.format("#%08X", rgba)); } @Override @@ -57,7 +54,18 @@ public class ColorTypeAdapter extends TypeAdapter case NULL: in.nextNull(); return null; + case STRING: + { + String value = in.nextString(); + if (value.charAt(0) == '#') + { + value = value.substring(1); + } + int intValue = Integer.parseUnsignedInt(value, 16); + return new Color(intValue, true); + } case BEGIN_OBJECT: + { in.beginObject(); double value = 0; while (in.peek() != JsonToken.END_OBJECT) @@ -74,6 +82,7 @@ public class ColorTypeAdapter extends TypeAdapter } in.endObject(); return new Color((int) value, true); + } } return null; // throws } diff --git a/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java index bf92af94b8..d5162c0e01 100644 --- a/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java +++ b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java @@ -43,12 +43,7 @@ public class InstantTypeAdapter extends TypeAdapter return; } - out.beginObject() - .name("seconds") - .value(value.getEpochSecond()) - .name("nanos") - .value(value.getNano()) - .endObject(); + out.value(value.toEpochMilli()); } @Override @@ -60,6 +55,12 @@ public class InstantTypeAdapter extends TypeAdapter return null; } + if (in.peek() == JsonToken.NUMBER) + { + long jsTime = in.nextLong(); + return Instant.ofEpochMilli(jsTime); + } + long seconds = 0; int nanos = 0; in.beginObject(); diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemPrice.java b/http-api/src/main/java/net/runelite/http/api/item/ItemPrice.java index 001c63deb8..faf5bfc3fb 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemPrice.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemPrice.java @@ -24,7 +24,6 @@ */ package net.runelite.http.api.item; -import java.time.Instant; import lombok.Data; @Data @@ -33,5 +32,5 @@ public class ItemPrice private int id; private String name; private int price; - private Instant time; + private int wikiPrice; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 4bb471b57f..8288f98c74 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -84,6 +84,7 @@ import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Player; @@ -445,7 +446,7 @@ public class ConfigManager setConfiguration(groupName, null, key, value); } - public void setConfiguration(String groupName, String profile, String key, String value) + public void setConfiguration(String groupName, String profile, String key, @NonNull String value) { if (Strings.isNullOrEmpty(groupName) || Strings.isNullOrEmpty(key)) { @@ -565,6 +566,7 @@ public class ConfigManager ConfigChanged configChanged = new ConfigChanged(); configChanged.setGroup(groupName); + configChanged.setProfile(profile); configChanged.setKey(key); configChanged.setOldValue(oldValue); diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 36b3084946..a3dac72172 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -381,17 +381,6 @@ public interface RuneLiteConfig extends Config return ComponentConstants.STANDARD_BACKGROUND_COLOR; } - @ConfigItem( - keyName = "blockExtraMouseButtons", - name = "Block Extra Mouse Buttons", - description = "Blocks extra mouse buttons (4 and above)", - position = 44 - ) - default boolean blockExtraMouseButtons() - { - return true; - } - @ConfigItem( keyName = "sidebarToggleKey", name = "Sidebar Toggle Key", @@ -415,4 +404,26 @@ public interface RuneLiteConfig extends Config { return new Keybind(KeyEvent.VK_F12, InputEvent.CTRL_DOWN_MASK); } + + @ConfigItem( + keyName = "blockExtraMouseButtons", + name = "Block extra mouse buttons", + description = "Blocks extra mouse buttons (4 and above)", + position = 50 + ) + default boolean blockExtraMouseButtons() + { + return true; + } + + @ConfigItem( + keyName = "useWikiItemPrices", + name = "Use actively traded price", + description = "Use actively traded prices, sourced from the RuneScape wiki, for item prices", + position = 51 + ) + default boolean useWikiItemPrices() + { + return true; + } } 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 7ae68ebcfc..07e94f3d4f 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 @@ -56,6 +56,7 @@ import net.runelite.api.SpritePixels; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.PostItemComposition; import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.AsyncBufferedImage; @@ -87,6 +88,7 @@ public class ItemManager private final Client client; private final ClientThread clientThread; private final ItemClient itemClient; + private final RuneLiteConfig runeLiteConfig; private Map itemPrices = Collections.emptyMap(); private Map itemStats = Collections.emptyMap(); @@ -171,11 +173,12 @@ public class ItemManager @Inject public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread, - OkHttpClient okHttpClient, EventBus eventBus) + OkHttpClient okHttpClient, EventBus eventBus, RuneLiteConfig runeLiteConfig) { this.client = client; this.clientThread = clientThread; this.itemClient = new ItemClient(okHttpClient); + this.runeLiteConfig = runeLiteConfig; scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES); scheduledExecutorService.submit(this::loadStats); @@ -293,17 +296,36 @@ public class ItemManager */ public int getItemPrice(int itemID) { - return getItemPrice(itemID, false); + return getItemPriceWithSource(itemID, runeLiteConfig.useWikiItemPrices()); } /** * Look up an item's price * * @param itemID item id - * @param ignoreUntradeableMap should the price returned ignore items that are not tradeable for coins in regular way + * @param ignoreUntradeableMap skip untradeables * @return item price */ + @Deprecated(since = "4.1.0", forRemoval = true) public int getItemPrice(int itemID, boolean ignoreUntradeableMap) + { + return getItemPriceWithSource(itemID, runeLiteConfig.useWikiItemPrices(), ignoreUntradeableMap); + } + + /** + * Look up an item's price + * + * @param itemID item id + * @param useWikiPrice use the actively traded/wiki price + * @return item price + */ + public int getItemPriceWithSource(int itemID, boolean useWikiPrice) + { + return getItemPriceWithSource(itemID, useWikiPrice, false); + } + + // TODO: inline this back to getItemPriceWithSource(int, boolean) next minor ver + private int getItemPriceWithSource(int itemID, boolean useWikiPrice, boolean ignoreUntradeableMap) { if (itemID == COINS_995) { @@ -331,7 +353,7 @@ public class ItemManager if (ip != null) { - price += ip.getPrice(); + price = useWikiPrice && ip.getWikiPrice() > 0 ? ip.getWikiPrice() : ip.getPrice(); } } else @@ -343,7 +365,7 @@ public class ItemManager continue; } - price += getItemPrice(mappedItem.getTradeableItem(), ignoreUntradeableMap) * mappedItem.getQuantity(); + price += getItemPriceWithSource(mappedItem.getTradeableItem(), useWikiPrice) * mappedItem.getQuantity(); } } 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 cde5c6bb73..0cb6174d6e 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 @@ -77,7 +77,6 @@ public class BarrowsPlugin extends Plugin private static final int CRYPT_REGION_ID = 14231; private LoopTimer barrowsPrayerDrainTimer; - private boolean wasInCrypt = false; @Getter private Widget puzzleAnswer; @@ -128,7 +127,6 @@ public class BarrowsPlugin extends Plugin overlayManager.remove(barrowsOverlay); overlayManager.remove(brotherOverlay); puzzleAnswer = null; - wasInCrypt = false; stopPrayerDrainTimer(); // Restore widgets @@ -157,18 +155,14 @@ public class BarrowsPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged event) { - if (event.getGameState() == GameState.LOADING) - { - wasInCrypt = isInCrypt(); - } - else if (event.getGameState() == GameState.LOGGED_IN) + if (event.getGameState() == GameState.LOGGED_IN) { boolean isInCrypt = isInCrypt(); - if (wasInCrypt && !isInCrypt) + if (!isInCrypt && barrowsPrayerDrainTimer != null) { stopPrayerDrainTimer(); } - else if (!wasInCrypt && isInCrypt) + else if (isInCrypt && barrowsPrayerDrainTimer == null) { startPrayerDrainTimer(); } @@ -233,6 +227,7 @@ public class BarrowsPlugin extends Plugin { if (config.showPrayerDrainTimer()) { + assert barrowsPrayerDrainTimer == null; final LoopTimer loopTimer = new LoopTimer( PRAYER_DRAIN_INTERVAL_MS, ChronoUnit.MILLIS, 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 4d7bac6c1e..e9c2f0c174 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 @@ -65,6 +65,7 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; +import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; import net.runelite.client.game.ItemManager; @@ -177,6 +178,9 @@ public class ChatCommandsPlugin extends Plugin @Inject private ChatClient chatClient; + @Inject + private RuneLiteConfig runeLiteConfig; + @Override public void startUp() { @@ -996,7 +1000,7 @@ public class ChatCommandsPlugin extends Plugin ItemPrice item = retrieveFromList(results, search); int itemId = item.getId(); - int itemPrice = item.getPrice(); + int itemPrice = runeLiteConfig.useWikiItemPrices() && item.getWikiPrice() > 0 ? item.getWikiPrice() : item.getPrice(); final ChatMessageBuilder builder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java index c208d5238f..2135bbbe52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java @@ -58,13 +58,12 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl new FaloTheBardClue("A mark used to increase one's grace, found atop a seer's place.", item(MARK_OF_GRACE)), new FaloTheBardClue("A molten beast with fiery breath, you acquire these with its death.", item(LAVA_DRAGON_BONES)), new FaloTheBardClue("A shiny helmet of flight, to obtain this with melee, struggle you might.", item(ARMADYL_HELMET)), - // The wiki doesn't specify whether the trimmed dragon defender will work so I've assumed that it doesn't - new FaloTheBardClue("A sword held in the other hand, red its colour, Cyclops strength you must withstand.", any("Dragon or Avernic Defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_L), item(AVERNIC_DEFENDER), item(AVERNIC_DEFENDER_L))), + new FaloTheBardClue("A sword held in the other hand, red its colour, Cyclops strength you must withstand.", any("Dragon or Avernic Defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_T), item(DRAGON_DEFENDER_L), item(AVERNIC_DEFENDER), item(AVERNIC_DEFENDER_L))), new FaloTheBardClue("A token used to kill mythical beasts, in hopes of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)), new FaloTheBardClue("Green is my favourite, mature ale I do love, this takes your herblore above.", item(GREENMANS_ALEM)), new FaloTheBardClue("It can hold down a boat or crush a goat, this object, you see, is quite heavy.", item(BARRELCHEST_ANCHOR)), new FaloTheBardClue("It comes from the ground, underneath the snowy plain. Trolls aplenty, with what looks like a mane.", item(BASALT)), - new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian, but with no room for a shield.", item(TZHAARKETOM)), + new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian, but with no room for a shield.", any("Tzhaar-ket-om", item(TZHAARKETOM), item(TZHAARKETOM_T))), new FaloTheBardClue("Penance healers runners and more, obtaining this body often gives much deplore.", any("Fighter Torso", item(FIGHTER_TORSO), item(FIGHTER_TORSO_L))), new FaloTheBardClue("Strangely found in a chest, many believe these gloves are the best.", item(BARROWS_GLOVES)), new FaloTheBardClue("These gloves of white won't help you fight, but aid in cooking, they just might.", item(COOKING_GAUNTLETS)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java index c7db3ab0ab..ab4e78c9a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java @@ -57,13 +57,13 @@ public interface GrandExchangeConfig extends Config @ConfigItem( position = 3, - keyName = "enableOsbPrices", - name = "Enable OSB actively traded prices", - description = "Shows the OSBuddy actively traded price on the GE buy interface" + keyName = "showActivelyTradedPrice", + name = "Enable actively traded prices", + description = "Shows the actively traded price on the GE buy interface, sourced from the RuneScape wiki" ) - default boolean enableOsbPrices() + default boolean showActivelyTradedPrice() { - return false; + return true; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOffersPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOffersPanel.java index a64f4b1474..a9100c52a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOffersPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOffersPanel.java @@ -38,7 +38,7 @@ import net.runelite.api.ItemComposition; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.components.PluginErrorPanel; -public class GrandExchangeOffersPanel extends JPanel +class GrandExchangeOffersPanel extends JPanel { private static final String ERROR_PANEL = "ERROR_PANEL"; private static final String OFFERS_PANEL = "OFFERS_PANEL"; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePanel.java index 0b59270de5..a3fc4c70dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePanel.java @@ -27,13 +27,10 @@ package net.runelite.client.plugins.grandexchange; import java.awt.BorderLayout; -import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import lombok.Getter; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.game.ItemManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.materialtabs.MaterialTab; @@ -49,21 +46,20 @@ class GrandExchangePanel extends PluginPanel private final MaterialTab searchTab; @Getter - private GrandExchangeSearchPanel searchPanel; + private final GrandExchangeSearchPanel searchPanel; @Getter private GrandExchangeOffersPanel offersPanel; @Inject - private GrandExchangePanel(ClientThread clientThread, ItemManager itemManager, ScheduledExecutorService executor) + private GrandExchangePanel(GrandExchangeSearchPanel searchPanel) { super(false); + this.searchPanel = searchPanel; + setLayout(new BorderLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); - // Search Panel - searchPanel = new GrandExchangeSearchPanel(clientThread, itemManager, executor); - //Offers Panel offersPanel = new GrandExchangeOffersPanel(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index f3d9b513b3..0517769726 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -36,7 +36,6 @@ import com.google.gson.Gson; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; -import java.io.IOException; import java.net.NetworkInterface; import java.net.SocketException; import java.time.Duration; @@ -48,7 +47,6 @@ import java.util.EnumSet; import java.util.Enumeration; import java.util.List; import java.util.Locale; -import java.util.concurrent.ScheduledExecutorService; import java.util.function.ToIntFunction; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -105,7 +103,6 @@ import net.runelite.http.api.ge.GrandExchangeClient; import net.runelite.http.api.ge.GrandExchangeTrade; import net.runelite.http.api.item.ItemStats; import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; -import net.runelite.http.api.osbuddy.OSBGrandExchangeResult; import net.runelite.http.api.worlds.WorldType; import okhttp3.OkHttpClient; import org.apache.commons.lang3.time.DurationFormatUtils; @@ -124,7 +121,6 @@ public class GrandExchangePlugin extends Plugin private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks private static final int OFFER_CONTAINER_ITEM = 21; private static final int OFFER_DEFAULT_ITEM_ID = 6512; - private static final String OSB_GE_TEXT = "
OSBuddy Actively traded price: "; private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; @@ -173,9 +169,6 @@ public class GrandExchangePlugin extends Plugin @Inject private Notifier notifier; - @Inject - private ScheduledExecutorService executorService; - @Inject private SessionManager sessionManager; @@ -189,16 +182,10 @@ public class GrandExchangePlugin extends Plugin private Widget grandExchangeItem; private String grandExchangeExamine; - private int osbItem; - private OSBGrandExchangeResult osbGrandExchangeResult; - @Inject private GrandExchangeClient grandExchangeClient; private int lastLoginTick; - @Inject - private OSBGrandExchangeClient osbGrandExchangeClient; - private boolean wasFuzzySearch; private String machineUuid; @@ -318,9 +305,6 @@ public class GrandExchangePlugin extends Plugin grandExchangeClient.setUuid(null); } - osbItem = -1; - osbGrandExchangeResult = null; - lastLoginTick = -1; } @@ -880,50 +864,17 @@ public class GrandExchangePlugin extends Plugin } } + if (config.showActivelyTradedPrice()) + { + final int price = itemManager.getItemPriceWithSource(itemId, true); + if (price > 0) + { + text += "
Actively traded price: " + QuantityFormatter.formatNumber(price); + } + } + grandExchangeExamine = text; geText.setText(text); - - if (!config.enableOsbPrices()) - { - return; - } - - // If we already have the result, use it - if (osbGrandExchangeResult != null && osbGrandExchangeResult.getItem_id() == itemId && osbGrandExchangeResult.getOverall_average() > 0) - { - grandExchangeExamine = text + OSB_GE_TEXT + QuantityFormatter.formatNumber(osbGrandExchangeResult.getOverall_average()); - geText.setText(grandExchangeExamine); - } - - if (osbItem == itemId) - { - // avoid starting duplicate lookups - return; - } - - osbItem = itemId; - - log.debug("Looking up OSB item price {}", itemId); - - final String start = text; - executorService.submit(() -> - { - try - { - final OSBGrandExchangeResult result = osbGrandExchangeClient.lookupItem(itemId); - if (result != null && result.getOverall_average() > 0) - { - osbGrandExchangeResult = result; - // Update the text on the widget too - grandExchangeExamine = start + OSB_GE_TEXT + QuantityFormatter.formatNumber(result.getOverall_average()); - geText.setText(grandExchangeExamine); - } - } - catch (IOException e) - { - log.debug("Error getting price of item {}", itemId, e); - } - }); } static void openGeLink(String name, int itemId) 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 723d9f697a..942ee98cde 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 @@ -34,12 +34,14 @@ import java.awt.GridBagLayout; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledExecutorService; +import javax.inject.Inject; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import net.runelite.api.ItemComposition; import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.components.IconTextField; @@ -64,6 +66,7 @@ class GrandExchangeSearchPanel extends JPanel private final ClientThread clientThread; private final ItemManager itemManager; private final ScheduledExecutorService executor; + private final RuneLiteConfig runeLiteConfig; private final IconTextField searchBar = new IconTextField(); @@ -78,11 +81,14 @@ class GrandExchangeSearchPanel extends JPanel private final List itemsList = new ArrayList<>(); - GrandExchangeSearchPanel(ClientThread clientThread, ItemManager itemManager, ScheduledExecutorService executor) + @Inject + private GrandExchangeSearchPanel(ClientThread clientThread, ItemManager itemManager, + ScheduledExecutorService executor, RuneLiteConfig runeLiteConfig) { this.clientThread = clientThread; this.itemManager = itemManager; this.executor = executor; + this.runeLiteConfig = runeLiteConfig; setLayout(new BorderLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); @@ -192,6 +198,7 @@ class GrandExchangeSearchPanel extends JPanel cardLayout.show(centerPanel, RESULTS_PANEL); int count = 0; + boolean useActivelyTradedPrice = runeLiteConfig.useWikiItemPrices(); for (ItemPrice item : result) { @@ -206,7 +213,7 @@ class GrandExchangeSearchPanel extends JPanel ItemComposition itemComp = itemManager.getItemComposition(itemId); ItemStats itemStats = itemManager.getItemStats(itemId, false); - int itemPrice = item.getPrice(); + int itemPrice = useActivelyTradedPrice && item.getWikiPrice() > 0 ? item.getWikiPrice() : item.getPrice(); int itemLimit = itemStats != null ? itemStats.getGeLimit() : 0; AsyncBufferedImage itemImage = itemManager.getImage(itemId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 6e24212005..86a27c8915 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -208,7 +208,7 @@ public class ObjectIndicatorsPlugin extends Plugin } } - if (gameStateChanged.getGameState() != GameState.LOGGED_IN) + if (gameStateChanged.getGameState() != GameState.LOGGED_IN && gameStateChanged.getGameState() != GameState.CONNECTION_LOST) { objects.clear(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 801148c447..65fcf0af05 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -25,6 +25,7 @@ */ package net.runelite.client.plugins.opponentinfo; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Provides; import java.time.Duration; import java.time.Instant; @@ -80,6 +81,8 @@ public class OpponentInfoPlugin extends Plugin @Getter(AccessLevel.PACKAGE) private Actor lastOpponent; + @Getter(AccessLevel.PACKAGE) + @VisibleForTesting private Instant lastTime; @Provides diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 24816d559e..bc9281980e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -316,7 +316,14 @@ public class SlayerPlugin extends Plugin private void setProfileConfig(String key, Object value) { - configManager.setRSProfileConfiguration(SlayerConfig.GROUP_NAME, key, value); + if (value != null) + { + configManager.setRSProfileConfiguration(SlayerConfig.GROUP_NAME, key, value); + } + else + { + configManager.unsetRSProfileConfiguration(SlayerConfig.GROUP_NAME, key); + } } private void save() diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 102c66480e..40a4e10417 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -49,6 +49,7 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; +import net.runelite.client.config.RuneLiteConfig; import net.runelite.http.api.chat.ChatClient; import net.runelite.http.api.hiscore.HiscoreClient; import net.runelite.http.api.hiscore.HiscoreSkill; @@ -106,6 +107,10 @@ public class ChatCommandsPluginTest @Bind ChatClient chatClient; + @Mock + @Bind + RuneLiteConfig runeLiteConfig; + @Mock @Bind ChatCommandsConfig chatCommandsConfig; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java index e627dac19b..8624a9017a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java @@ -32,7 +32,6 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.GameState; @@ -109,10 +108,6 @@ public class GrandExchangePluginTest @Bind private MouseManager mouseManager; - @Mock - @Bind - private ScheduledExecutorService scheduledExecutorService; - @Mock @Bind private GrandExchangeClient grandExchangeClient; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPluginTest.java new file mode 100644 index 0000000000..4b213bde95 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPluginTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2021, Jordan Atwood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.opponentinfo; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.events.InteractingChanged; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.junit.Test; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class OpponentInfoPluginTest +{ + @Mock + @Bind + Client client; + + @Mock + @Bind + OverlayManager overlayManager; + + @Mock + @Bind + OpponentInfoConfig config; + + @Mock + @Bind + OpponentInfoOverlay opponentInfoOverlay; + + @Mock + @Bind + PlayerComparisonOverlay playerComparisonOverlay; + + @Inject + OpponentInfoPlugin plugin; + + private final Player localPlayer = mock(Player.class); + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getLocalPlayer()).thenReturn(localPlayer); + } + + @Test + public void testNpcInteractions() + { + final NPC npc = mock(NPC.class); + + interactingChanged(npc, localPlayer); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(npc, null); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(localPlayer, npc); + + assertSame(npc, plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(npc, localPlayer); + + assertSame(npc, plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(localPlayer, null); + + // last opponent is remembered for 5 seconds + assertSame(npc, plugin.getLastOpponent()); + assertNotNull(plugin.getLastTime()); + } + + @Test + public void testOtherPlayerInteractions() + { + final Player otherPlayer = mock(Player.class); + + interactingChanged(otherPlayer, localPlayer); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(otherPlayer, null); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(localPlayer, otherPlayer); + + assertSame(otherPlayer, plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(otherPlayer, localPlayer); + + assertSame(otherPlayer, plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(localPlayer, null); + + // last opponent is remembered for 5 seconds + assertSame(otherPlayer, plugin.getLastOpponent()); + assertNotNull(plugin.getLastTime()); + } + + @Test + public void testNonLocalPlayerInteractions() + { + final Player otherPlayer = mock(Player.class); + final NPC npc = mock(NPC.class); + + interactingChanged(otherPlayer, npc); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(npc, otherPlayer); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(otherPlayer, null); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + + interactingChanged(npc, null); + + assertNull(plugin.getLastOpponent()); + assertNull(plugin.getLastTime()); + } + + private void interactingChanged(final Actor source, final Actor target) + { + when(source.getInteracting()).thenReturn(target); + plugin.onInteractingChanged(new InteractingChanged(source, target)); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java index 21af0f0538..f10e525ce8 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java @@ -553,6 +553,8 @@ public class SlayerPluginTest assertEquals("", slayerPlugin.getTaskName()); assertEquals(0, slayerPlugin.getAmount()); + + verify(configManager).unsetRSProfileConfiguration(SlayerConfig.GROUP_NAME, SlayerConfig.TASK_LOC_KEY); } @Test