From 5e4cded98ddc4dc8076ec89838778b2b79b420d9 Mon Sep 17 00:00:00 2001 From: loldudester Date: Fri, 15 May 2020 04:31:48 +0100 Subject: [PATCH 01/19] antidrag: Enable shift-antidrag in PvP regardless of onShiftOnly config --- .../net/runelite/client/plugins/antidrag/AntiDragConfig.java | 2 +- .../net/runelite/client/plugins/antidrag/AntiDragPlugin.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java index 3e645547f1..d685fe6573 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java @@ -46,7 +46,7 @@ public interface AntiDragConfig extends Config @ConfigItem( keyName = "onShiftOnly", name = "On Shift Only", - description = "Configures whether to only adjust the delay while holding shift. Required for anti drag in PvP scenarios.", + description = "Configures whether to only adjust the delay while holding shift in non-PvP scenarios. Shift is required in PvP regardless of this config setting", position = 2 ) default boolean onShiftOnly() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java index 06b50e3e49..8a6459382a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java @@ -112,7 +112,7 @@ public class AntiDragPlugin extends Plugin implements KeyListener @Override public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_SHIFT && config.onShiftOnly()) + if (e.getKeyCode() == KeyEvent.VK_SHIFT && (inPvp || config.onShiftOnly())) { setDragDelay(); held = true; @@ -122,7 +122,7 @@ public class AntiDragPlugin extends Plugin implements KeyListener @Override public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_SHIFT && config.onShiftOnly()) + if (e.getKeyCode() == KeyEvent.VK_SHIFT && (inPvp || config.onShiftOnly())) { resetDragDelay(); held = false; From cb0d9ce3d08416f07013009b83fd49c51d2d801f Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 15 May 2020 02:06:09 -0600 Subject: [PATCH 02/19] hiscore: modify the ui on the edt only --- .../client/plugins/hiscore/HiscorePanel.java | 4 ++-- .../client/plugins/hiscore/HiscorePlugin.java | 18 +++--------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 5a82c4fb22..1a7333ecb1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -194,7 +194,7 @@ public class HiscorePanel extends PluginPanel if (localPlayer != null) { - executor.execute(() -> lookup(localPlayer.getName())); + lookup(localPlayer.getName()); } } }); @@ -363,7 +363,7 @@ public class HiscorePanel extends PluginPanel { searchBar.setText(username); resetEndpoints(); - lookup(); + executor.execute(this::lookup); } private void lookup() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index 5ce1d4b9e9..e7c18d9133 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -28,7 +28,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; -import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -213,23 +212,12 @@ public class HiscorePlugin extends Plugin private void lookupPlayer(String playerName) { - executor.execute(() -> + SwingUtilities.invokeLater(() -> { - try + if (!navButton.isSelected()) { - SwingUtilities.invokeAndWait(() -> - { - if (!navButton.isSelected()) - { - navButton.getOnSelect().run(); - } - }); + navButton.getOnSelect().run(); } - catch (InterruptedException | InvocationTargetException e) - { - throw new RuntimeException(e); - } - hiscorePanel.lookup(playerName); }); } From d8d5631734c3e0fa848f3dc192036b74bc804cad Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 15 May 2020 02:08:32 -0600 Subject: [PATCH 03/19] IconTextField: add combobox-style suggestion dropdown --- .../client/ui/components/IconTextField.java | 144 +++++++++++++++--- 1 file changed, 119 insertions(+), 25 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java index 0408837302..0266caa450 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java @@ -31,25 +31,36 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.function.Consumer; +import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JTextField; +import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; import javax.swing.text.Document; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; +import net.runelite.client.util.SwingUtil; +import org.apache.commons.lang3.StringUtils; +import org.pushingpixels.substance.internal.ui.SubstanceListUI; /** * This component is a FlatTextField with an icon on its left side, and a clear button (×) on its right side. @@ -58,10 +69,13 @@ public class IconTextField extends JPanel { // To support gifs, the icon needs to be wrapped in a JLabel private final JLabel iconWrapperLabel; - private final FlatTextField textField; private final JButton clearButton; + private final JButton suggestionButton; + + @Getter + private final DefaultListModel suggestionListModel; public IconTextField() { @@ -108,66 +122,146 @@ public class IconTextField extends JPanel textField.addMouseListener(hoverEffect); innerTxt.addMouseListener(hoverEffect); - clearButton = new JButton("×"); - clearButton.setPreferredSize(new Dimension(30, 0)); - clearButton.setFont(FontManager.getRunescapeBoldFont()); - clearButton.setForeground(ColorScheme.PROGRESS_ERROR_COLOR); - clearButton.setBorder(null); - clearButton.setBorderPainted(false); - clearButton.setContentAreaFilled(false); - clearButton.setVisible(false); - - // ActionListener for keyboard use (via Tab -> Space) + clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK); + clearButton.setText("×"); clearButton.addActionListener(evt -> setText(null)); - // MouseListener for hover and click events - clearButton.addMouseListener(new MouseAdapter() + suggestionListModel = new DefaultListModel<>(); + suggestionListModel.addListDataListener(new ListDataListener() { @Override - public void mousePressed(MouseEvent mouseEvent) + public void intervalAdded(ListDataEvent e) { - setText(null); + updateContextButton(); } @Override - public void mouseEntered(MouseEvent mouseEvent) + public void intervalRemoved(ListDataEvent e) { - clearButton.setForeground(Color.PINK); - textField.dispatchEvent(mouseEvent); + updateContextButton(); } @Override - public void mouseExited(MouseEvent mouseEvent) + public void contentsChanged(ListDataEvent e) { - clearButton.setForeground(ColorScheme.PROGRESS_ERROR_COLOR); - textField.dispatchEvent(mouseEvent); + updateContextButton(); } }); + JList suggestionList = new JList<>(); + suggestionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + suggestionList.setModel(suggestionListModel); + suggestionList.addListSelectionListener(e -> + { + String val = suggestionList.getSelectedValue(); + if (val == null) + { + return; + } + + textField.setText(val); + textField.getTextField().selectAll(); + textField.getTextField().requestFocusInWindow(); + }); + + JPopupMenu popup = new JPopupMenu(); + popup.setLightWeightPopupEnabled(true); + popup.setLayout(new BorderLayout()); + popup.add(suggestionList, BorderLayout.CENTER); + popup.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + popup.setVisible(false); + suggestionList.clearSelection(); + + SubstanceListUI ui = (SubstanceListUI) suggestionList.getUI(); + ui.resetRolloverIndex(); + } + }); + + suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR); + suggestionButton.setText("▾"); + suggestionButton.addActionListener(e -> + { + popup.setPopupSize(getWidth(), suggestionList.getPreferredSize().height); + popup.show(IconTextField.this, 0, suggestionButton.getHeight()); + popup.revalidate(); + popup.requestFocusInWindow(); + }); + // Show the clear button when text is present, and hide again when empty textField.getTextField().getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { - SwingUtilities.invokeLater(() -> clearButton.setVisible(true)); + updateContextButton(); } @Override public void removeUpdate(DocumentEvent e) { - SwingUtilities.invokeLater(() -> clearButton.setVisible(!getText().isEmpty())); + updateContextButton(); } @Override public void changedUpdate(DocumentEvent e) { + updateContextButton(); } }); + JPanel rhsButtons = new JPanel(); + rhsButtons.setBackground(new Color(0, 0, 0, 0)); + rhsButtons.setOpaque(false); + rhsButtons.setLayout(new BorderLayout()); + rhsButtons.add(clearButton, BorderLayout.EAST); + rhsButtons.add(suggestionButton, BorderLayout.WEST); + updateContextButton(); + add(iconWrapperLabel, BorderLayout.WEST); add(textField, BorderLayout.CENTER); - add(clearButton, BorderLayout.EAST); + add(rhsButtons, BorderLayout.EAST); + } + + private JButton createRHSButton(Color fg, Color rollover) + { + JButton b = new JButton(); + b.setPreferredSize(new Dimension(30, 0)); + b.setFont(FontManager.getRunescapeBoldFont()); + b.setBorder(null); + b.setRolloverEnabled(true); + SwingUtil.removeButtonDecorations(b); + b.setForeground(fg); + + b.addMouseListener(new MouseAdapter() + { + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + b.setForeground(rollover); + textField.dispatchEvent(mouseEvent); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + b.setForeground(fg); + textField.dispatchEvent(mouseEvent); + } + }); + + return b; + } + + private void updateContextButton() + { + boolean empty = StringUtils.isBlank(textField.getText()); + + clearButton.setVisible(!empty); + suggestionButton.setVisible(!suggestionListModel.isEmpty() && empty); } public void addActionListener(ActionListener actionListener) @@ -188,6 +282,7 @@ public class IconTextField extends JPanel public void setText(String text) { + assert SwingUtilities.isEventDispatchThread(); textField.setText(text); } @@ -290,5 +385,4 @@ public class IconTextField extends JPanel private final String file; } - } From 857126284082e52bbe17cc707fe351ef2e40ee43 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 15 May 2020 02:19:08 -0600 Subject: [PATCH 04/19] config: add tag suggestions This is intended to make the tags feature more discoverable, as people keep requesting "plugin categories". Putting plugins into a singular category that will make sense for most users is impossible, as many plugins will can logically be placed into multiple categories. The Category Tag list is intended to be a short, curated, list of tags that are helpful to a user trying to find plugins. --- .../client/plugins/config/PluginListPanel.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java index 57ac970cae..72d5d4cf36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.config; +import com.google.common.collect.ImmutableList; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; @@ -74,6 +75,15 @@ class PluginListPanel extends PluginPanel { private static final String RUNELITE_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value(); private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins"; + private static final ImmutableList CATEGORY_TAGS = ImmutableList.of( + "Combat", + "Chat", + "Item", + "Minigame", + "Notification", + "Skilling", + "XP" + ); private final ConfigManager configManager; private final PluginManager pluginManager; @@ -150,6 +160,7 @@ class PluginListPanel extends PluginPanel onSearchBarChanged(); } }); + CATEGORY_TAGS.forEach(searchBar.getSuggestionListModel()::addElement); setLayout(new BorderLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); From 432f32c28c92ffd080914b42b69465ee649004fb Mon Sep 17 00:00:00 2001 From: TheStonedTurtle Date: Fri, 15 May 2020 21:09:17 -0700 Subject: [PATCH 05/19] loot tracker - Fix total values when not grouping loot --- .../client/plugins/loottracker/LootTrackerPanel.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index 596ca1ff2c..d3ca782f64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -613,7 +613,13 @@ class LootTrackerPanel extends PluginPanel long overallGe = 0; long overallHa = 0; - for (LootTrackerRecord record : concat(aggregateRecords, sessionRecords)) + Iterable records = sessionRecords; + if (groupLoot) + { + records = concat(aggregateRecords, sessionRecords); + } + + for (LootTrackerRecord record : records) { if (!record.matches(currentView, currentType)) { From 7675f92ee5f3d8d26b539a71c7e14a36c35e8475 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 30 May 2020 23:24:34 -0400 Subject: [PATCH 06/19] ge controller: add total to trade message --- .../net/runelite/http/service/ge/GrandExchangeController.java | 1 + .../src/main/java/net/runelite/http/service/ge/Trade.java | 1 + 2 files changed, 2 insertions(+) diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java index 2a67655b6a..6219b00b61 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java @@ -89,6 +89,7 @@ public class GrandExchangeController trade.setCancel(grandExchangeTrade.isCancel()); trade.setItemId(grandExchangeTrade.getItemId()); trade.setQuantity(grandExchangeTrade.getQuantity()); + trade.setTotal(grandExchangeTrade.getTotal()); trade.setPrice(grandExchangeTrade.getPrice()); trade.setOffer(grandExchangeTrade.getOffer()); trade.setTime((int) (System.currentTimeMillis() / 1000L)); diff --git a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java index 6e71efbb13..00c549bdfa 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java @@ -34,6 +34,7 @@ class Trade private boolean cancel; private int itemId; private int quantity; + private int total; private int price; private int offer; private int time; From c39cbd6b4fa76eb5ee6e8970d0c937168433811e Mon Sep 17 00:00:00 2001 From: Aleksander Birkeland Date: Sun, 31 May 2020 18:05:48 +0200 Subject: [PATCH 07/19] ClientUI: Add support for changing window opacity. --- .../client/config/RuneLiteConfig.java | 21 ++++++++++++++++--- .../java/net/runelite/client/ui/ClientUI.java | 10 ++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) 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 b511a5e407..43e2a93ae6 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 @@ -105,11 +105,26 @@ public interface RuneLiteConfig extends Config return true; } + @Range( + min = 10, + max = 100 + ) + @ConfigItem( + keyName = "uiWindowOpacity", + name = "Window opacity", + description = "Set the windows opacity. Requires \"Enable custom window chrome\" to be enabled.", + position = 16 + ) + default int windowOpacity() + { + return 100; + } + @ConfigItem( keyName = "gameAlwaysOnTop", name = "Enable client always on top", description = "The game will always be on the top of the screen", - position = 16 + position = 17 ) default boolean gameAlwaysOnTop() { @@ -120,7 +135,7 @@ public interface RuneLiteConfig extends Config keyName = "warningOnExit", name = "Display warning on exit", description = "Toggles a warning popup when trying to exit the client", - position = 17 + position = 18 ) default WarningOnExit warningOnExit() { @@ -131,7 +146,7 @@ public interface RuneLiteConfig extends Config keyName = "usernameInTitle", name = "Show display name in title", description = "Toggles displaying of local player's display name in client title", - position = 18 + position = 19 ) default boolean usernameInTitle() { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 5c6f2b8fe5..78fffa2128 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -161,7 +161,7 @@ public class ClientUI @Subscribe public void onConfigChanged(ConfigChanged event) { - if (!event.getGroup().equals("runelite") || + if (!event.getGroup().equals(CONFIG_GROUP) || event.getKey().equals(CONFIG_CLIENT_MAXIMIZED) || event.getKey().equals(CONFIG_CLIENT_BOUNDS)) { @@ -979,6 +979,14 @@ public class ClientUI return; } + // Update window opacity if the frame is undecorated, translucency capable and not fullscreen + if (frame.isUndecorated() && + frame.getGraphicsConfiguration().isTranslucencyCapable() && + frame.getGraphicsConfiguration().getDevice().getFullScreenWindow() == null) + { + frame.setOpacity(((float) config.windowOpacity()) / 100.0f); + } + if (config.usernameInTitle() && (client instanceof Client)) { final Player player = ((Client)client).getLocalPlayer(); From 482f9c5e440922c0b8d92ec02772d690dc43df83 Mon Sep 17 00:00:00 2001 From: Alfred Ababio Date: Sun, 31 May 2020 12:33:51 -0400 Subject: [PATCH 08/19] key remapper: don't consume keytype events when dialog is open This fixes having a remapped key held down during a dialog opening that consumes the raw key event. --- .../client/plugins/keyremapping/KeyRemappingListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index 726881379a..f07ccbf553 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -59,7 +59,7 @@ class KeyRemappingListener implements KeyListener public void keyTyped(KeyEvent e) { char keyChar = e.getKeyChar(); - if (keyChar != KeyEvent.CHAR_UNDEFINED && blockedChars.contains(keyChar)) + if (keyChar != KeyEvent.CHAR_UNDEFINED && blockedChars.contains(keyChar) && plugin.chatboxFocused()) { e.consume(); } From 2a174e7a8dfe4632530db1edb075abe58a9fdbcb Mon Sep 17 00:00:00 2001 From: Dominik Date: Mon, 1 Jun 2020 01:03:52 +0200 Subject: [PATCH 09/19] Add item mapping for twisted ancestral robes (#11761) --- .../main/java/net/runelite/client/game/ItemMapping.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java index de133ed12b..b6bef6d52f 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java @@ -249,7 +249,12 @@ public enum ItemMapping ITEM_CRYSTAL_SHIELD(CRYSTAL_WEAPON_SEED, CRYSTAL_SHIELD, CRYSTAL_SHIELD_24127, CRYSTAL_SHIELD_INACTIVE), // Bird nests - ITEM_BIRD_NEST(BIRD_NEST_5075, BIRD_NEST, BIRD_NEST_5071, BIRD_NEST_5072, BIRD_NEST_5073, BIRD_NEST_5074, BIRD_NEST_7413, BIRD_NEST_13653, BIRD_NEST_22798, BIRD_NEST_22800, CLUE_NEST_EASY, CLUE_NEST_MEDIUM, CLUE_NEST_HARD, CLUE_NEST_ELITE); + ITEM_BIRD_NEST(BIRD_NEST_5075, BIRD_NEST, BIRD_NEST_5071, BIRD_NEST_5072, BIRD_NEST_5073, BIRD_NEST_5074, BIRD_NEST_7413, BIRD_NEST_13653, BIRD_NEST_22798, BIRD_NEST_22800, CLUE_NEST_EASY, CLUE_NEST_MEDIUM, CLUE_NEST_HARD, CLUE_NEST_ELITE), + + // Ancestral robes + ITEM_ANCESTRAL_HAT(ANCESTRAL_HAT, TWISTED_ANCESTRAL_HAT), + ITEM_ANCESTRAL_ROBE_TOP(ANCESTRAL_ROBE_TOP, TWISTED_ANCESTRAL_ROBE_TOP), + ITEM_ANCESTRAL_ROBE_BOTTOM(ANCESTRAL_ROBE_BOTTOM, TWISTED_ANCESTRAL_ROBE_BOTTOM); private static final Multimap MAPPINGS = HashMultimap.create(); private final int tradeableItem; From 41a041972afe8ac99b936a2b0d7721ce34516a22 Mon Sep 17 00:00:00 2001 From: MarbleTurtle <60723971+MarbleTurtle@users.noreply.github.com> Date: Sun, 31 May 2020 21:57:22 -0700 Subject: [PATCH 10/19] clanchat: Add player name to kick message (#11555) --- .../client/plugins/clanchat/ClanChatConfig.java | 15 +++++++++++++-- .../client/plugins/clanchat/ClanChatPlugin.java | 16 ++++++++++++++++ .../src/main/scripts/ClanSendKick.rs2asm | 7 +++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java index 3a7dbfa20d..08ba3de298 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java @@ -150,11 +150,22 @@ public interface ClanChatConfig extends Config return false; } + @ConfigItem( + keyName = "kickWithName", + name = "Show kicked player", + description = "Changes kick message to say who was kicked", + position = 10 + ) + default boolean kickWithName() + { + return true; + } + @ConfigItem( keyName = "showIgnores", name = "Recolor ignored players", description = "Recolors players that are on your ignore list", - position = 10 + position = 11 ) default boolean showIgnores() { @@ -165,7 +176,7 @@ public interface ClanChatConfig extends Config keyName = "showIgnoresColor", name = "Ignored color", description = "Allows you to change the color of the ignored players in your clan chat", - position = 11 + position = 12 ) default Color showIgnoresColor() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java index 1e51d1b4df..49dfa8027a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java @@ -555,6 +555,22 @@ public class ClanChatPlugin extends Plugin clientThread.invokeLater(() -> confirmKickPlayer(kickPlayerName)); break; } + case "sendKickName": + { + if (!config.kickWithName()) + { + break; + } + + // Get name of the player we are kicking + final String[] stringStack = client.getStringStack(); + final int stringSize = client.getStringStackSize(); + final String kickPlayerName = stringStack[stringSize - 1]; + + // Sets the kick message based on players name + stringStack[stringSize - 2] = "-Attempting to kick " + kickPlayerName + " from friends chat..."; + break; + } } } diff --git a/runelite-client/src/main/scripts/ClanSendKick.rs2asm b/runelite-client/src/main/scripts/ClanSendKick.rs2asm index 1da495029f..f26f49c73a 100644 --- a/runelite-client/src/main/scripts/ClanSendKick.rs2asm +++ b/runelite-client/src/main/scripts/ClanSendKick.rs2asm @@ -6,6 +6,9 @@ ; callback "confirmClanKick" ; Used by the ClanChat plugin to show a chatbox panel confirming the requested kick ; Also requires the "confirmKicks" option of ClanChatConfig to be enabled +; callback "sendKickName" +; Used by the ClanChat plugin to modify the kick message to include player name +; Also requires the "kickWithName" option of ClanChatConfig to be enabled invoke 1942 iconst 1 if_icmpeq LABEL4 @@ -16,6 +19,10 @@ LABEL4: return LABEL7: sconst "-Attempting to kick player from friends chat..." + sload 0 ; Username we are kicking + sconst "sendKickName" + runelite_callback + pop_string ; Username we are kicking iconst 2 invoke 96 sload 0 From b25cfc5f809f310b52adca701892de1cdc00efba Mon Sep 17 00:00:00 2001 From: johannfrias <30681899+johannfrias@users.noreply.github.com> Date: Mon, 1 Jun 2020 01:59:58 -0400 Subject: [PATCH 11/19] screenshot: fix quest screenshot naming method (#11580) This commit adds a quest completion dialog parsing method which gives proper quest screenshot filenames for all quests, including those with unique/non-uniform completion texts such as "You have Made Friends with My Arm" and "You have rebuilt The Giant Dwarf". --- .../plugins/screenshot/ScreenshotPlugin.java | 51 ++++++++++++++++++- .../screenshot/ScreenshotPluginTest.java | 13 +++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 26a612456a..0dd69bffd6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -102,6 +102,10 @@ public class ScreenshotPlugin extends Plugin private static final Pattern VALUABLE_DROP_PATTERN = Pattern.compile(".*Valuable drop: ([^<>]+)(?:)?"); private static final Pattern UNTRADEABLE_DROP_PATTERN = Pattern.compile(".*Untradeable drop: ([^<>]+)(?:)?"); private static final Pattern DUEL_END_PATTERN = Pattern.compile("You have now (won|lost) ([0-9]+) duels?\\."); + private static final Pattern QUEST_PATTERN_1 = Pattern.compile(".+?ve\\.*? (?been|rebuilt|.+?ed)? ?(?:the )?'?(?.+?)'?(?: [Qq]uest)?[!.]?$"); + private static final Pattern QUEST_PATTERN_2 = Pattern.compile("'?(?.+?)'?(?: [Qq]uest)? (?[a-z]\\w+?ed)?(?: f.*?)?[!.]?$"); + private static final ImmutableList RFD_TAGS = ImmutableList.of("Another Cook", "freed", "defeated", "saved"); + private static final ImmutableList WORD_QUEST_IN_NAME_TAGS = ImmutableList.of("Another Cook", "Doric", "Heroes", "Legends", "Observatory", "Olaf", "Waterfall"); private static final ImmutableList PET_MESSAGES = ImmutableList.of("You have a funny feeling like you're being followed", "You feel something weird sneaking into your backpack", "You have a funny feeling like you would have been followed"); @@ -238,9 +242,8 @@ public class ScreenshotPlugin extends Plugin } else if (client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT) != null) { - // "You have completed The Corsair Curse!" String text = client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT).getText(); - fileName = "Quest(" + text.substring(19, text.length() - 1) + ")"; + fileName = parseQuestCompletedWidget(text); screenshotSubDir = "Quests"; } @@ -574,6 +577,50 @@ public class ScreenshotPlugin extends Plugin return skillName + "(" + skillLevel + ")"; } + /** + * Parses the passed quest completion dialog text into a shortened string for filename usage. + * + * @param text The {@link Widget#getText() text} of the {@link WidgetInfo#QUEST_COMPLETED_NAME_TEXT} widget. + * @return Shortened string in the format "Quest(The Corsair Curse)" + */ + @VisibleForTesting + static String parseQuestCompletedWidget(final String text) + { + // "You have completed The Corsair Curse!" + final Matcher questMatch1 = QUEST_PATTERN_1.matcher(text); + // "'One Small Favour' completed!" + final Matcher questMatch2 = QUEST_PATTERN_2.matcher(text); + final Matcher questMatchFinal = questMatch1.matches() ? questMatch1 : questMatch2; + if (!questMatchFinal.matches()) + { + return "Quest(quest not found)"; + } + + String quest = questMatchFinal.group("quest"); + String verb = questMatchFinal.group("verb") != null ? questMatchFinal.group("verb") : ""; + + if (verb.contains("kind of")) + { + quest += " partial completion"; + } + else if (verb.contains("completely")) + { + quest += " II"; + } + + if (RFD_TAGS.stream().anyMatch((quest + verb)::contains)) + { + quest = "Recipe for Disaster - " + quest; + } + + if (WORD_QUEST_IN_NAME_TAGS.stream().anyMatch(quest::contains)) + { + quest += " Quest"; + } + + return "Quest(" + quest + ')'; + } + /** * Saves a screenshot of the client window to the screenshot folder as a PNG, * and optionally uploads it to an image-hosting service. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java index b7058d4092..2616db357e 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java @@ -245,4 +245,17 @@ public class ScreenshotPluginTest verify(drawManager).requestNextFrameListener(any(Consumer.class)); } + + @Test + public void testQuestParsing() + { + assertEquals("Quest(The Corsair Curse)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed The Corsair Curse!")); + assertEquals("Quest(One Small Favour)", ScreenshotPlugin.parseQuestCompletedWidget("'One Small Favour' completed!")); + assertEquals("Quest(Hazeel Cult partial completion)", ScreenshotPlugin.parseQuestCompletedWidget("You have... kind of... completed the Hazeel Cult Quest!")); + assertEquals("Quest(Rag and Bone Man II)", ScreenshotPlugin.parseQuestCompletedWidget("You have completely completed Rag and Bone Man!")); + assertEquals("Quest(Recipe for Disaster - Culinaromancer)", ScreenshotPlugin.parseQuestCompletedWidget("Congratulations! You have defeated the Culinaromancer!")); + assertEquals("Quest(Recipe for Disaster - Another Cook's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Another Cook's Quest!")); + assertEquals("Quest(Doric's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Doric's Quest!")); + assertEquals("Quest(quest not found)", ScreenshotPlugin.parseQuestCompletedWidget("Sins of the Father forgiven!")); + } } From eb92a61760590c1ce55a165de1acf0da06c75032 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Mon, 1 Jun 2020 02:02:16 -0400 Subject: [PATCH 12/19] emoji: Add gorilla emoji (#11562) --- .../net/runelite/client/plugins/emojis/Emoji.java | 3 ++- .../runelite/client/plugins/emojis/gorilla.png | Bin 0 -> 308 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/gorilla.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java index 5f05110bd5..3ac56872d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -87,7 +87,8 @@ enum Emoji HEART_EYES("(*.*)"), FACEPALM("M-)"), PENSIVE("V_V"), - ACORN("D~") // D~"), // emojiMap; diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/gorilla.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/gorilla.png new file mode 100644 index 0000000000000000000000000000000000000000..c5122e6a3a96c9f4ad68abfb3435802e573cfb27 GIT binary patch literal 308 zcmV-40n7f0P)5np zO>4qH6wF^zu^P}CW5C3(l&nULqG&`9N-5GFDuEsf1uwnm{~ejth%xKQg~z;kGsD|m zO;emqp^Uf`a&iMn96uRO9k%@D*jw3Uoz43CwM7au-e^+MV&tSHC`j9SKx>M z%da1lY7O||M)pK<&TSD$AN}&0Yz*g3is8o&yZsTLzyJ8&A3)9!^=p7B61`fNB8}d7 zf%oW7A~{34QBQ}gPEU$7sEY4RY~nVv>A|0`VS7V3Vg#o5jSy}l5V_TxEYn-!FxS^w0&Xyen6A(n%uuo2RNw@u Date: Mon, 1 Jun 2020 07:05:07 +0100 Subject: [PATCH 13/19] npchighlight: Recolor spell cast and "use item" menu entries (#11595) --- .../client/plugins/npchighlight/NpcIndicatorsPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 200eedfd8b..fc7cf4ac91 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -86,7 +86,8 @@ public class NpcIndicatorsPlugin extends Plugin private static final String UNTAG = "Un-tag"; private static final Set NPC_MENU_ACTIONS = ImmutableSet.of(MenuAction.NPC_FIRST_OPTION, MenuAction.NPC_SECOND_OPTION, - MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION); + MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION, MenuAction.SPELL_CAST_ON_NPC, + MenuAction.ITEM_USE_ON_NPC); @Inject private Client client; From de54c44894972c3fd7d07afc0773ed080d94fdca Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Sat, 30 May 2020 02:19:59 -0400 Subject: [PATCH 14/19] clues: Add missing Agility and Max cape IDs to skill challenge --- .../client/plugins/cluescrolls/clues/SkillChallengeClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index ab0b7d0606..46d42af87d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -163,7 +163,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam new SkillChallengeClue("Complete a lap of Rellekka's Rooftop Agility Course", "complete a lap of the rellekka rooftop agility course whilst sporting the finest amount of grace.", true, all("A full Graceful set", any("", item(ItemID.GRACEFUL_HOOD), item(ItemID.GRACEFUL_HOOD_11851), item(ItemID.GRACEFUL_HOOD_13579), item(ItemID.GRACEFUL_HOOD_13580), item(ItemID.GRACEFUL_HOOD_13591), item(ItemID.GRACEFUL_HOOD_13592), item(ItemID.GRACEFUL_HOOD_13603), item(ItemID.GRACEFUL_HOOD_13604), item(ItemID.GRACEFUL_HOOD_13615), item(ItemID.GRACEFUL_HOOD_13616), item(ItemID.GRACEFUL_HOOD_13627), item(ItemID.GRACEFUL_HOOD_13628), item(ItemID.GRACEFUL_HOOD_13667), item(ItemID.GRACEFUL_HOOD_13668), item(ItemID.GRACEFUL_HOOD_21061), item(ItemID.GRACEFUL_HOOD_21063)), - any("", item(ItemID.GRACEFUL_CAPE), item(ItemID.GRACEFUL_CAPE_11853), item(ItemID.GRACEFUL_CAPE_13581), item(ItemID.GRACEFUL_CAPE_13582), item(ItemID.GRACEFUL_CAPE_13593), item(ItemID.GRACEFUL_CAPE_13594), item(ItemID.GRACEFUL_CAPE_13605), item(ItemID.GRACEFUL_CAPE_13606), item(ItemID.GRACEFUL_CAPE_13617), item(ItemID.GRACEFUL_CAPE_13618), item(ItemID.GRACEFUL_CAPE_13629), item(ItemID.GRACEFUL_CAPE_13630), item(ItemID.GRACEFUL_CAPE_13669), item(ItemID.GRACEFUL_CAPE_13670), item(ItemID.GRACEFUL_CAPE_21064), item(ItemID.GRACEFUL_CAPE_21066), item(ItemID.AGILITY_CAPE), item(ItemID.AGILITY_CAPET), item(ItemID.MAX_CAPE)), + any("", item(ItemID.GRACEFUL_CAPE), item(ItemID.GRACEFUL_CAPE_11853), item(ItemID.GRACEFUL_CAPE_13581), item(ItemID.GRACEFUL_CAPE_13582), item(ItemID.GRACEFUL_CAPE_13593), item(ItemID.GRACEFUL_CAPE_13594), item(ItemID.GRACEFUL_CAPE_13605), item(ItemID.GRACEFUL_CAPE_13606), item(ItemID.GRACEFUL_CAPE_13617), item(ItemID.GRACEFUL_CAPE_13618), item(ItemID.GRACEFUL_CAPE_13629), item(ItemID.GRACEFUL_CAPE_13630), item(ItemID.GRACEFUL_CAPE_13669), item(ItemID.GRACEFUL_CAPE_13670), item(ItemID.GRACEFUL_CAPE_21064), item(ItemID.GRACEFUL_CAPE_21066), item(ItemID.AGILITY_CAPE), item (ItemID.AGILITY_CAPE_10648), item(ItemID.AGILITY_CAPE_13340), item(ItemID.AGILITY_CAPET), item(ItemID.AGILITY_CAPET_13341), item(ItemID.MAX_CAPE), item(ItemID.MAX_CAPE_13282), item(ItemID.MAX_CAPE_13342)), any("", item(ItemID.GRACEFUL_TOP), item(ItemID.GRACEFUL_TOP_11855), item(ItemID.GRACEFUL_TOP_13583), item(ItemID.GRACEFUL_TOP_13584), item(ItemID.GRACEFUL_TOP_13595), item(ItemID.GRACEFUL_TOP_13596), item(ItemID.GRACEFUL_TOP_13607), item(ItemID.GRACEFUL_TOP_13608), item(ItemID.GRACEFUL_TOP_13619), item(ItemID.GRACEFUL_TOP_13620), item(ItemID.GRACEFUL_TOP_13631), item(ItemID.GRACEFUL_TOP_13632), item(ItemID.GRACEFUL_TOP_13671), item(ItemID.GRACEFUL_TOP_13672), item(ItemID.GRACEFUL_TOP_21067), item(ItemID.GRACEFUL_TOP_21069)), any("", item(ItemID.GRACEFUL_LEGS), item(ItemID.GRACEFUL_LEGS_11857), item(ItemID.GRACEFUL_LEGS_13585), item(ItemID.GRACEFUL_LEGS_13586), item(ItemID.GRACEFUL_LEGS_13597), item(ItemID.GRACEFUL_LEGS_13598), item(ItemID.GRACEFUL_LEGS_13609), item(ItemID.GRACEFUL_LEGS_13610), item(ItemID.GRACEFUL_LEGS_13621), item(ItemID.GRACEFUL_LEGS_13622), item(ItemID.GRACEFUL_LEGS_13633), item(ItemID.GRACEFUL_LEGS_13634), item(ItemID.GRACEFUL_LEGS_13673), item(ItemID.GRACEFUL_LEGS_13674), item(ItemID.GRACEFUL_LEGS_21070), item(ItemID.GRACEFUL_LEGS_21072)), any("", item(ItemID.GRACEFUL_GLOVES), item(ItemID.GRACEFUL_GLOVES_11859), item(ItemID.GRACEFUL_GLOVES_13587), item(ItemID.GRACEFUL_GLOVES_13588), item(ItemID.GRACEFUL_GLOVES_13599), item(ItemID.GRACEFUL_GLOVES_13600), item(ItemID.GRACEFUL_GLOVES_13611), item(ItemID.GRACEFUL_GLOVES_13612), item(ItemID.GRACEFUL_GLOVES_13623), item(ItemID.GRACEFUL_GLOVES_13624), item(ItemID.GRACEFUL_GLOVES_13635), item(ItemID.GRACEFUL_GLOVES_13636), item(ItemID.GRACEFUL_GLOVES_13675), item(ItemID.GRACEFUL_GLOVES_13676), item(ItemID.GRACEFUL_GLOVES_21073), item(ItemID.GRACEFUL_GLOVES_21075)), From 9ee3c2d8f1807322f16e387511b86f1989ad2730 Mon Sep 17 00:00:00 2001 From: branisk <56201891+branisk@users.noreply.github.com> Date: Mon, 1 Jun 2020 03:41:07 -0400 Subject: [PATCH 15/19] timers: remove stamina timer upon entering the Gauntlet (#11742) --- .../java/net/runelite/client/plugins/timers/TimersPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 71d3b67e95..6376b329ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -93,6 +93,7 @@ public class TimersPlugin extends Plugin private static final String EXTENDED_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended antifire potion."; private static final String EXTENDED_SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended super antifire potion."; private static final String FROZEN_MESSAGE = "You have been frozen!"; + private static final String GAUNTLET_ENTER_MESSAGE = "You enter the Gauntlet."; private static final String GOD_WARS_ALTAR_MESSAGE = "you recharge your prayer."; private static final String IMBUED_HEART_READY_MESSAGE = "Your imbued heart has regained its magical power."; private static final String MAGIC_IMBUE_EXPIRED_MESSAGE = "Your Magic Imbue charge has ended."; @@ -442,7 +443,7 @@ public class TimersPlugin extends Plugin createGameTimer(STAMINA); } - if (config.showStamina() && event.getMessage().equals(STAMINA_EXPIRED_MESSAGE)) + if (config.showStamina() && (event.getMessage().equals(STAMINA_EXPIRED_MESSAGE) || event.getMessage().equals(GAUNTLET_ENTER_MESSAGE))) { removeGameTimer(STAMINA); } From ea45059f20a21426dfe7ec9221fae42731beb073 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 May 2020 18:34:04 -0400 Subject: [PATCH 16/19] ge plugin: null client session id on session close --- .../client/plugins/grandexchange/GrandExchangePlugin.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 b421dd7aaf..1b78aad7e8 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 @@ -85,6 +85,7 @@ import net.runelite.client.account.SessionManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.game.ItemManager; import net.runelite.client.input.KeyManager; @@ -341,6 +342,12 @@ public class GrandExchangePlugin extends Plugin grandExchangeClient.setUuid(accountSession.getUuid()); } + @Subscribe + public void onSessionClose(SessionClose sessionClose) + { + grandExchangeClient.setUuid(null); + } + @Subscribe public void onConfigChanged(ConfigChanged event) { From 83756e8722a837165cfbbce3ef78b99d0c64eab0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 May 2020 18:40:42 -0400 Subject: [PATCH 17/19] ge: submit spent price instead of computed per-item price --- .../runelite/http/api/ge/GrandExchangeTrade.java | 2 +- .../http/service/ge/GrandExchangeController.java | 6 ++++-- .../http/service/ge/GrandExchangeService.java | 2 +- .../java/net/runelite/http/service/ge/Trade.java | 2 +- .../grandexchange/GrandExchangePlugin.java | 16 ++++------------ .../grandexchange/GrandExchangePluginTest.java | 4 ++-- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java index a3ef3f484d..00a06f195e 100644 --- a/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java +++ b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java @@ -35,7 +35,7 @@ public class GrandExchangeTrade private int itemId; private int quantity; private int total; - private int price; + private int spent; private int offer; private WorldType worldType; } diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java index 6219b00b61..2c2cc71f4c 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java @@ -79,7 +79,9 @@ public class GrandExchangeController Integer userId = session == null ? null : session.getUser(); // We don't keep track of pending trades in the web UI, so only add cancelled or completed trades - if (userId != null && (grandExchangeTrade.isCancel() || grandExchangeTrade.getQuantity() == grandExchangeTrade.getTotal())) + if (userId != null && + grandExchangeTrade.getQuantity() > 0 && + (grandExchangeTrade.isCancel() || grandExchangeTrade.getQuantity() == grandExchangeTrade.getTotal())) { grandExchangeService.add(userId, grandExchangeTrade); } @@ -90,7 +92,7 @@ public class GrandExchangeController trade.setItemId(grandExchangeTrade.getItemId()); trade.setQuantity(grandExchangeTrade.getQuantity()); trade.setTotal(grandExchangeTrade.getTotal()); - trade.setPrice(grandExchangeTrade.getPrice()); + trade.setSpent(grandExchangeTrade.getSpent()); trade.setOffer(grandExchangeTrade.getOffer()); trade.setTime((int) (System.currentTimeMillis() / 1000L)); trade.setMachineId(request.getHeader(RuneLiteAPI.RUNELITE_MACHINEID)); diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java index f53a9095c6..e5acbc6aa7 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java @@ -80,7 +80,7 @@ public class GrandExchangeService .addParameter("action", grandExchangeTrade.isBuy() ? "BUY" : "SELL") .addParameter("item", grandExchangeTrade.getItemId()) .addParameter("quantity", grandExchangeTrade.getQuantity()) - .addParameter("price", grandExchangeTrade.getPrice()) + .addParameter("price", grandExchangeTrade.getSpent() / grandExchangeTrade.getQuantity()) .executeUpdate(); } } diff --git a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java index 00c549bdfa..62fa30f6ac 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java @@ -35,7 +35,7 @@ class Trade private int itemId; private int quantity; private int total; - private int price; + private int spent; private int offer; private int time; private String machineId; 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 1b78aad7e8..54cc559e0a 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 @@ -404,7 +404,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setItemId(offer.getItemId()); grandExchangeTrade.setQuantity(0); grandExchangeTrade.setTotal(offer.getTotalQuantity()); - grandExchangeTrade.setPrice(0); + grandExchangeTrade.setSpent(0); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); @@ -433,7 +433,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setItemId(offer.getItemId()); grandExchangeTrade.setQuantity(offer.getQuantitySold()); grandExchangeTrade.setTotal(offer.getTotalQuantity()); - grandExchangeTrade.setPrice(offer.getQuantitySold() > 0 ? offer.getSpent() / offer.getQuantitySold() : 0); + grandExchangeTrade.setSpent(offer.getSpent()); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); @@ -443,16 +443,8 @@ public class GrandExchangePlugin extends Plugin } final int qty = offer.getQuantitySold() - savedOffer.getQuantitySold(); - if (qty <= 0) - { - return; - } - - // offer.getPrice() is the price of the offer, not necessarily what the item bought at, so we compute it - // based on how much was spent & the qty final int dspent = offer.getSpent() - savedOffer.getSpent(); - final int price = dspent / qty; - if (price <= 0) + if (qty <= 0 || dspent <= 0) { return; } @@ -462,7 +454,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setItemId(offer.getItemId()); grandExchangeTrade.setQuantity(qty); grandExchangeTrade.setTotal(offer.getTotalQuantity()); - grandExchangeTrade.setPrice(price); + grandExchangeTrade.setSpent(dspent); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); 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 d4afc5cf0e..9f638b837d 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 @@ -159,7 +159,7 @@ public class GrandExchangePluginTest assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId()); assertEquals(2, trade.getQuantity()); assertEquals(10, trade.getTotal()); - assertEquals(10, trade.getPrice()); + assertEquals(20, trade.getSpent()); } @Test @@ -216,6 +216,6 @@ public class GrandExchangePluginTest assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId()); assertEquals(1, trade.getQuantity()); assertEquals(10, trade.getTotal()); - assertEquals(25, trade.getPrice()); + assertEquals(25, trade.getSpent()); } } \ No newline at end of file From c67378c09e24aba7f1edbc4f3bc4ae7c6bbc2185 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 May 2020 20:30:08 -0400 Subject: [PATCH 18/19] ge plugin: include if trade is synced on login --- .../runelite/http/api/ge/GrandExchangeTrade.java | 1 + .../http/service/ge/GrandExchangeController.java | 1 + .../java/net/runelite/http/service/ge/Trade.java | 1 + .../plugins/grandexchange/GrandExchangePlugin.java | 14 ++++++++++++++ 4 files changed, 17 insertions(+) diff --git a/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java index 00a06f195e..e5dfe923d4 100644 --- a/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java +++ b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java @@ -32,6 +32,7 @@ public class GrandExchangeTrade { private boolean buy; private boolean cancel; + private boolean login; private int itemId; private int quantity; private int total; diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java index 2c2cc71f4c..6d4d8fd6ef 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java @@ -89,6 +89,7 @@ public class GrandExchangeController Trade trade = new Trade(); trade.setBuy(grandExchangeTrade.isBuy()); trade.setCancel(grandExchangeTrade.isCancel()); + trade.setLogin(grandExchangeTrade.isLogin()); trade.setItemId(grandExchangeTrade.getItemId()); trade.setQuantity(grandExchangeTrade.getQuantity()); trade.setTotal(grandExchangeTrade.getTotal()); diff --git a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java index 62fa30f6ac..ff2d7be0cd 100644 --- a/http-service/src/main/java/net/runelite/http/service/ge/Trade.java +++ b/http-service/src/main/java/net/runelite/http/service/ge/Trade.java @@ -32,6 +32,7 @@ class Trade { private boolean buy; private boolean cancel; + private boolean login; private int itemId; private int quantity; private int total; 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 54cc559e0a..5cddd9df7f 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 @@ -116,6 +116,7 @@ import org.apache.commons.text.similarity.FuzzyScore; @Slf4j public class GrandExchangePlugin extends Plugin { + private static final int GE_SLOTS = 8; private static final int OFFER_CONTAINER_ITEM = 21; private static final int OFFER_DEFAULT_ITEM_ID = 6512; private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient(); @@ -185,6 +186,7 @@ public class GrandExchangePlugin extends Plugin @Inject private GrandExchangeClient grandExchangeClient; + private boolean loginBurstGeUpdates; private static String machineUuid; private boolean wasFuzzySearch; @@ -375,6 +377,9 @@ public class GrandExchangePlugin extends Plugin final int slot = offerEvent.getSlot(); final GrandExchangeOffer offer = offerEvent.getOffer(); + log.debug("GE offer updated: state: {}, slot: {}, item: {}, qty: {}, login: {}", + offer.getState(), slot, offer.getItemId(), offer.getQuantitySold(), loginBurstGeUpdates); + ItemComposition offerItem = itemManager.getItemComposition(offer.getItemId()); boolean shouldStack = offerItem.isStackable() || offer.getTotalQuantity() > 1; BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack); @@ -383,6 +388,11 @@ public class GrandExchangePlugin extends Plugin submitTrade(slot, offer); updateConfig(slot, offer); + + if (loginBurstGeUpdates && slot == GE_SLOTS - 1) // slots are sent sequentially on login; this is the last one + { + loginBurstGeUpdates = false; + } } @VisibleForTesting @@ -407,6 +417,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setSpent(0); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); + grandExchangeTrade.setLogin(loginBurstGeUpdates); log.debug("Submitting new trade: {}", grandExchangeTrade); grandExchangeClient.submit(grandExchangeTrade); @@ -436,6 +447,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setSpent(offer.getSpent()); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); + grandExchangeTrade.setLogin(loginBurstGeUpdates); log.debug("Submitting cancelled: {}", grandExchangeTrade); grandExchangeClient.submit(grandExchangeTrade); @@ -457,6 +469,7 @@ public class GrandExchangePlugin extends Plugin grandExchangeTrade.setSpent(dspent); grandExchangeTrade.setOffer(offer.getPrice()); grandExchangeTrade.setWorldType(getGeWorldType()); + grandExchangeTrade.setLogin(loginBurstGeUpdates); log.debug("Submitting trade: {}", grandExchangeTrade); grandExchangeClient.submit(grandExchangeTrade); @@ -522,6 +535,7 @@ public class GrandExchangePlugin extends Plugin if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN) { panel.getOffersPanel().resetOffers(); + loginBurstGeUpdates = true; } } From 4652e8ede45abad2a7f4a46f1b288f8fe628ea47 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Tue, 2 Jun 2020 17:27:01 -0600 Subject: [PATCH 19/19] PluginManager: don't duplicate dependency plugins if they already exist If you had an external plugin with a PluginDependency on a core plugin the core plugin would be included in the external `loadPlugins` dependency graph, which would make it be instantiated twice. Since external plugins can't depend on other external plugins, and core plugins are guaranteed to be loaded first with no external dependencies, we can just exclude dependency edges for nodes outside of the current load list. --- .../main/java/net/runelite/client/plugins/PluginManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 1a2dc1f365..f48da0de17 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -320,7 +320,10 @@ public class PluginManager for (PluginDependency pluginDependency : pluginDependencies) { - graph.putEdge(pluginClazz, pluginDependency.value()); + if (graph.nodes().contains(pluginDependency.value())) + { + graph.putEdge(pluginClazz, pluginDependency.value()); + } } }