From 2fd6ec9d8c0306db00765f82e26e6e1d47787071 Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 9 Dec 2021 09:11:59 +1100 Subject: [PATCH 01/42] configs: reimplement rework --- .../config/ConfigInvocationHandler.java | 6 +- .../client/config/ConfigItemDescriptor.java | 3 +- .../runelite/client/config/ConfigManager.java | 68 +- .../client/plugins/config/ConfigPanel.java | 820 +++++++----------- 4 files changed, 332 insertions(+), 565 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java index 3b14bc9da9..466bed401d 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java @@ -99,11 +99,9 @@ class ConfigInvocationHandler implements InvocationHandler } // Convert value to return type - Class returnType = method.getReturnType(); - try { - Object objectValue = ConfigManager.stringToObject(value, returnType); + Object objectValue = manager.stringToObject(value, method.getGenericReturnType()); cache.put(method, objectValue == null ? NULL : objectValue); return objectValue; } @@ -155,7 +153,7 @@ class ConfigInvocationHandler implements InvocationHandler } else { - String newValueStr = ConfigManager.objectToString(newValue); + String newValueStr = manager.objectToString(newValue); manager.setConfiguration(group.value(), item.keyName(), newValueStr); } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java index d6ced58e18..922fb531a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java @@ -24,13 +24,14 @@ */ package net.runelite.client.config; +import java.lang.reflect.Type; import lombok.Value; @Value public class ConfigItemDescriptor implements ConfigObject { private final ConfigItem item; - private final Class type; + private final Type type; private final Range range; private final Alpha alpha; private final Units units; 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 6fbdb1011d..d6d4e384b0 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 @@ -30,6 +30,7 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableSet; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; +import com.google.gson.Gson; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; @@ -44,6 +45,7 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.nio.channels.FileChannel; @@ -129,6 +131,7 @@ public class ConfigManager private final File settingsFileInput; private final EventBus eventBus; private final OkHttpClient okHttpClient; + private final Gson gson; private AccountSession session; private ConfigClient configClient; @@ -153,13 +156,15 @@ public class ConfigManager ScheduledExecutorService scheduledExecutorService, EventBus eventBus, OkHttpClient okHttpClient, - @Nullable Client client) + @Nullable Client client, + Gson gson) { this.settingsFileInput = config; this.eventBus = eventBus; this.okHttpClient = okHttpClient; this.client = client; this.propertiesFile = getPropertiesFile(); + this.gson = gson; scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); } @@ -413,17 +418,12 @@ public class ConfigManager return properties.getProperty(getWholeKey(groupName, profile, key)); } - public T getConfiguration(String groupName, String key, Class clazz) + public T getConfiguration(String groupName, String key, Type clazz) { return getConfiguration(groupName, null, key, clazz); } - public Object getConfiguration(String groupName, String key, Type clazz) - { - return getConfiguration(groupName, null, key, clazz); - } - - public T getRSProfileConfiguration(String groupName, String key, Class clazz) + public T getRSProfileConfiguration(String groupName, String key, Type clazz) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -434,31 +434,14 @@ public class ConfigManager return getConfiguration(groupName, rsProfileKey, key, clazz); } - public T getConfiguration(String groupName, String profile, String key, Type clazz) + public T getConfiguration(String groupName, String profile, String key, Type type) { String value = getConfiguration(groupName, profile, key); if (!Strings.isNullOrEmpty(value)) { try { - return (T) stringToObject(value, (Class) clazz); - } - catch (Exception e) - { - log.warn("Unable to unmarshal {} ", getWholeKey(groupName, profile, key), e); - } - } - return null; - } - - public T getConfiguration(String groupName, String profile, String key, Class clazz) - { - String value = getConfiguration(groupName, profile, key); - if (!Strings.isNullOrEmpty(value)) - { - try - { - return (T) stringToObject(value, clazz); + return (T) stringToObject(value, type); } catch (Exception e) { @@ -511,12 +494,12 @@ public class ConfigManager eventBus.post(configChanged); } - public void setConfiguration(String groupName, String profile, String key, Object value) + public void setConfiguration(String groupName, String profile, String key, T value) { setConfiguration(groupName, profile, key, objectToString(value)); } - public void setConfiguration(String groupName, String key, Object value) + public void setConfiguration(String groupName, String key, T value) { // do not save consumers for buttons, they cannot be changed anyway if (value instanceof Consumer) @@ -527,7 +510,7 @@ public class ConfigManager setConfiguration(groupName, null, key, value); } - public void setRSProfileConfiguration(String groupName, String key, Object value) + public void setRSProfileConfiguration(String groupName, String key, T value) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -646,7 +629,7 @@ public class ConfigManager .collect(Collectors.toList()); final List titles = getAllDeclaredInterfaceFields(inter).stream() - .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getType() == String.class) + .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getClass().equals(String.class)) .map(m -> { try @@ -673,7 +656,7 @@ public class ConfigManager .filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class)) .map(m -> new ConfigItemDescriptor( m.getDeclaredAnnotation(ConfigItem.class), - m.getReturnType(), + m.getGenericReturnType(), m.getDeclaredAnnotation(Range.class), m.getDeclaredAnnotation(Alpha.class), m.getDeclaredAnnotation(Units.class) @@ -748,7 +731,7 @@ public class ConfigManager { // This checks if it is set and is also unmarshallable to the correct type; so // we will overwrite invalid config values with the default - Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType()); + Object current = getConfiguration(group.value(), item.keyName(), method.getGenericReturnType()); if (current != null) { continue; // something else is already set @@ -783,7 +766,7 @@ public class ConfigManager } } - static Object stringToObject(String str, Class type) + Object stringToObject(String str, Type type) { if (type == boolean.class || type == Boolean.class) { @@ -824,7 +807,7 @@ public class ConfigManager int height = Integer.parseInt(splitStr[3]); return new Rectangle(x, y, width, height); } - if (type.isEnum()) + if (type instanceof Class && ((Class) type).isEnum()) { return Enum.valueOf((Class) type, str); } @@ -859,6 +842,14 @@ public class ConfigManager { return Base64.getUrlDecoder().decode(str); } + if (type instanceof ParameterizedType) + { + ParameterizedType parameterizedType = (ParameterizedType) type; + if (parameterizedType.getRawType() == Set.class) + { + return gson.fromJson(str, parameterizedType); + } + } if (type == EnumSet.class) { try @@ -898,7 +889,7 @@ public class ConfigManager } @Nullable - static String objectToString(Object object) + String objectToString(Object object) { if (object instanceof Color) { @@ -945,6 +936,10 @@ public class ConfigManager { return Base64.getUrlEncoder().encodeToString((byte[]) object); } + if (object instanceof Set) + { + return gson.toJson(object, Set.class); + } if (object instanceof EnumSet) { if (((EnumSet) object).size() == 0) @@ -954,7 +949,6 @@ public class ConfigManager return ((EnumSet) object).toArray()[0].getClass().getCanonicalName() + "{" + object.toString() + "}"; } - return object == null ? null : object.toString(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 3fc4c112d0..df8c74cf0f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -24,68 +24,36 @@ */ package net.runelite.client.plugins.config; +import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Sets; import com.google.common.primitives.Ints; -import java.awt.BasicStroke; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GridLayout; + +import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; +import java.lang.reflect.ParameterizedType; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; -import java.util.function.Consumer; import javax.inject.Inject; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JFormattedTextField; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JSlider; -import javax.swing.JSpinner; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.ScrollPaneConstants; -import javax.swing.SpinnerModel; -import javax.swing.SpinnerNumberModel; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; +import javax.swing.*; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.event.ChangeListener; -import javax.swing.plaf.basic.BasicSpinnerUI; import javax.swing.text.JTextComponent; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.events.ConfigButtonClicked; -import net.runelite.client.config.Button; import net.runelite.client.config.ConfigDescriptor; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -100,7 +68,6 @@ import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; import net.runelite.client.config.Range; import net.runelite.client.config.Units; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ExternalPluginsChanged; import net.runelite.client.events.PluginChanged; @@ -115,15 +82,14 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.ColorJButton; import net.runelite.client.ui.components.ComboBoxListRenderer; -import net.runelite.client.ui.components.ToggleButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker; import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.DeferredDocumentChangedListener; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; @Slf4j class ConfigPanel extends PluginPanel @@ -138,33 +104,6 @@ class ConfigPanel extends PluginPanel private static final Map sectionExpandStates = new HashMap<>(); - private final FixedWidthPanel mainPanel; - private final JLabel title; - private final PluginToggleButton pluginToggle; - - @Inject - private PluginListPanel pluginList; - - @Inject - private ConfigManager configManager; - - @Inject - private PluginManager pluginManager; - - @Inject - private ExternalPluginManager externalPluginManager; - - @Inject - private OPRSExternalPluginManager oprsExternalPluginManager; - - @Inject - private ColorPickerManager colorPickerManager; - - @Inject - private EventBus eventBus; - - private PluginConfigurationDescriptor pluginConfig = null; - static { final BufferedImage backIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_back_icon.png"); @@ -180,10 +119,36 @@ class ConfigPanel extends PluginPanel SECTION_RETRACT_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionExpandIcon, -100)); } - public ConfigPanel() + private final PluginListPanel pluginList; + private final ConfigManager configManager; + private final PluginManager pluginManager; + private final ExternalPluginManager externalPluginManager; + private final ColorPickerManager colorPickerManager; + + private final ListCellRenderer> listCellRenderer = new ComboBoxListRenderer<>(); + + private final FixedWidthPanel mainPanel; + private final JLabel title; + private final PluginToggleButton pluginToggle; + + private PluginConfigurationDescriptor pluginConfig = null; + + @Inject + private OPRSExternalPluginManager oprsExternalPluginManager; + + @Inject + private ConfigPanel(PluginListPanel pluginList, ConfigManager configManager, PluginManager pluginManager, + ExternalPluginManager externalPluginManager, ColorPickerManager colorPickerManager, OPRSExternalPluginManager oprsExternalPluginManager) { super(false); + this.pluginList = pluginList; + this.configManager = configManager; + this.pluginManager = pluginManager; + this.externalPluginManager = externalPluginManager; + this.colorPickerManager = colorPickerManager; + this.oprsExternalPluginManager = oprsExternalPluginManager; + setLayout(new BorderLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); @@ -462,436 +427,63 @@ class ConfigPanel extends PluginPanel configEntryName.setToolTipText("" + name + ":
" + cid.getItem().description() + ""); PluginListItem.addLabelPopupMenu(configEntryName, createResetMenuItem(pluginConfig, cid)); item.add(configEntryName, BorderLayout.CENTER); - item.setName(cid.getItem().keyName()); - - if (cid.getType() == Button.class) - { - try - { - ConfigItem cidItem = cid.getItem(); - JButton button = new JButton(cidItem.name()); - button.addActionListener((e) -> - { - ConfigButtonClicked event = new ConfigButtonClicked(); - event.setGroup(cd.getGroup().value()); - event.setKey(cid.getItem().keyName()); - eventBus.post(event); - }); - item.add(button); - } - catch (Exception ex) - { - log.error("Adding action listener failed: {}", ex.getMessage()); - ex.printStackTrace(); - } - } if (cid.getType() == boolean.class) { - JCheckBox checkbox = new ToggleButton(); - checkbox.setPreferredSize(new Dimension(26, 25)); - checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); - checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); - - item.add(checkbox, BorderLayout.EAST); + item.add(createCheckbox(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isAssignableFrom(Consumer.class)) + else if (cid.getType() == int.class) { - item.remove(configEntryName); - - JButton button = new JButton(cid.getItem().name()); - button.addActionListener((e) -> - { - log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); - configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); - }); - - item.add(button, BorderLayout.CENTER); + item.add(createIntSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == int.class) - { - int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - Units units = cid.getUnits(); - Range range = cid.getRange(); - int min = 0, max = Integer.MAX_VALUE; - if (range != null) - { - min = range.min(); - max = range.max(); - } - - // Config may previously have been out of range - value = Ints.constrainToRange(value, min, max); - - if (max < Integer.MAX_VALUE) - { - JLabel sliderValueLabel = new JLabel(); - JSlider slider = new JSlider(min, max, value); - slider.setBackground(ColorScheme.DARK_GRAY_COLOR); - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - slider.setPreferredSize(new Dimension(80, 25)); - slider.addChangeListener((l) -> - { - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - - if (!slider.getValueIsAdjusting()) - { - changeConfiguration(slider, cd, cid); - } - } - ); - - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.setUI(new BasicSpinnerUI() - { - protected Component createNextButton() - { - return null; - } - - protected Component createPreviousButton() - { - return null; - } - }); - - JPanel subPanel = new JPanel(); - subPanel.setPreferredSize(new Dimension(110, 25)); - subPanel.setLayout(new BorderLayout()); - - spinner.addChangeListener((ce) -> - { - changeConfiguration(spinner, cd, cid); - - if (units != null) - { - sliderValueLabel.setText(spinner.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(spinner.getValue())); - } - slider.setValue((Integer) spinner.getValue()); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - subPanel.remove(spinner); - - validate(); - repaint(); - }); - - sliderValueLabel.addMouseListener(new MouseAdapter() - { - public void mouseClicked(MouseEvent e) - { - spinner.setValue(slider.getValue()); - - subPanel.remove(sliderValueLabel); - subPanel.remove(slider); - subPanel.add(spinner, BorderLayout.EAST); - - validate(); - repaint(); - - final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); - tf.requestFocusInWindow(); - SwingUtilities.invokeLater(tf::selectAll); - } - }); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - - item.add(subPanel, BorderLayout.EAST); - } - else - { - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - if (units != null) - { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); - } - - item.add(spinner, BorderLayout.EAST); - } - } - else if (cid.getType() == double.class) { - double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); - - SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - item.add(spinner, BorderLayout.EAST); + item.add(createDoubleSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == String.class) + else if (cid.getType() == String.class) { - JTextComponent textField; - - if (cid.getItem().secret()) - { - textField = new JPasswordField(); - } - else - { - final JTextArea textArea = new JTextArea(); - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - textField = textArea; - } - - textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - textField.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(textField, cd, cid); - } - }); - - if (cid.getItem().parse()) - { - JLabel parsingLabel = new JLabel(); - parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); - parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); - - DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); - listener.addChangeListener(e -> - { - if (cid.getItem().parse()) - { - parseLabel(cid.getItem(), parsingLabel, textField.getText()); - } - }); - textField.getDocument().addDocumentListener(listener); - - item.add(configEntryName, BorderLayout.NORTH); - item.add(textField, BorderLayout.CENTER); - - - parseLabel(cid.getItem(), parsingLabel, textField.getText()); - item.add(parsingLabel, BorderLayout.SOUTH); - } - else - { - item.add(textField, BorderLayout.SOUTH); - } + item.add(createTextField(cd, cid), BorderLayout.SOUTH); } - - if (cid.getType() == Color.class) + else if (cid.getType() == Color.class) { - Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); - - ColorJButton colorPickerBtn; - - boolean alphaHidden = cid.getAlpha() == null; - - if (existing == null) - { - colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); - } - else - { - String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); - colorPickerBtn = new ColorJButton(colorHex, existing); - } - - colorPickerBtn.setFocusable(false); - colorPickerBtn.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - RuneliteColorPicker colorPicker = colorPickerManager.create( - SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getColor(), - cid.getItem().name(), - alphaHidden); - colorPicker.setLocation(getLocationOnScreen()); - colorPicker.setOnColorChange(c -> - { - colorPickerBtn.setColor(c); - colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); - }); - colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); - colorPicker.setVisible(true); - } - }); - - item.add(colorPickerBtn, BorderLayout.EAST); + item.add(createColorPicker(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Dimension.class) + else if (cid.getType() == Dimension.class) { - JPanel dimensionPanel = new JPanel(); - dimensionPanel.setLayout(new BorderLayout()); - - String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); - String[] splitStr = str.split("x"); - int width = Integer.parseInt(splitStr[0]); - int height = Integer.parseInt(splitStr[1]); - - SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); - JSpinner widthSpinner = new JSpinner(widthModel); - Component widthEditor = widthSpinner.getEditor(); - JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); - widthSpinnerTextField.setColumns(4); - - SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); - JSpinner heightSpinner = new JSpinner(heightModel); - Component heightEditor = heightSpinner.getEditor(); - JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); - heightSpinnerTextField.setColumns(4); - - ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); - - widthSpinner.addChangeListener(listener); - heightSpinner.addChangeListener(listener); - - dimensionPanel.add(widthSpinner, BorderLayout.WEST); - dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); - dimensionPanel.add(heightSpinner, BorderLayout.EAST); - - item.add(dimensionPanel, BorderLayout.EAST); + item.add(createDimension(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isEnum()) + else if (cid.getType() instanceof Class && ((Class) cid.getType()).isEnum()) { - Class type = (Class) cid.getType(); - - JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator - // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer - // to build components for each combobox element in order to compute the display size of the - // combobox - box.setRenderer(new ComboBoxListRenderer<>()); - box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); - box.setForeground(Color.WHITE); - box.setFocusable(false); - - try - { - Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - box.setSelectedItem(selectedItem); - box.setToolTipText(Text.titleCase(selectedItem)); - } - catch (IllegalArgumentException ex) - { - log.debug("invalid seleced item", ex); - } - box.addItemListener(e -> - { - if (e.getStateChange() == ItemEvent.SELECTED) - { - changeConfiguration(box, cd, cid); - box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); - } - }); - item.add(box, BorderLayout.EAST); + item.add(createComboBox(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) + else if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) { - Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), - (Class) cid.getType()); - - HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); - - button.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(button, cd, cid); - } - }); - - item.add(button, BorderLayout.EAST); + item.add(createKeybind(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == EnumSet.class) + else if (cid.getType() instanceof ParameterizedType) { - Class enumType = cid.getItem().enumClass(); - - EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), EnumSet.class); - if (enumSet == null || enumSet.contains(null)) + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + if (parameterizedType.getRawType() == Set.class) { - enumSet = EnumSet.noneOf(enumType); + item.add(createList(cd, cid), BorderLayout.EAST); + } + } + else if (cid.getType() instanceof EnumSet) + { + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + if (parameterizedType.getRawType() == EnumSet.class) + { + item.add(createList(cd, cid), BorderLayout.EAST); } - - JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); - List jcheckboxes = new ArrayList<>(); - - for (Object obj : enumType.getEnumConstants()) - { - String option = String.valueOf(obj).toLowerCase().replace("_", " "); - - JCheckBox checkbox = new ToggleButton(option); - checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); - checkbox.setSelected(enumSet.contains(obj)); - jcheckboxes.add(checkbox); - - enumsetLayout.add(checkbox); - } - - jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); - - item.add(enumsetLayout, BorderLayout.SOUTH); } - JPanel section = sectionWidgets.get(cid.getItem().section()); - JPanel title = titleWidgets.get(cid.getItem().title()); - - if (section != null) + if (section == null) { - section.add(item); - } - else if (title != null) - { - title.add(item); + topLevelPanels.put(cid, item); } else { - topLevelPanels.put(cid, item); + section.add(item); } } @@ -927,69 +519,249 @@ class ConfigPanel extends PluginPanel revalidate(); } - private Boolean parse(ConfigItem item, String value) + private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid) { - try - { - Method parse = item.clazz().getMethod(item.method(), String.class); - - return (boolean) parse.invoke(null, value); - } - catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) - { - log.error("Parsing failed: {}", ex.getMessage()); - } - - return null; + JCheckBox checkbox = new JCheckBox(); + checkbox.setBackground(ColorScheme.LIGHT_GRAY_COLOR); + checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); + checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); + return checkbox; } - private void parseLabel(ConfigItem item, JLabel label, String value) + private JSpinner createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) { - Boolean result = parse(item, value); + int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - if (result == null) + Range range = cid.getRange(); + int min = 0, max = Integer.MAX_VALUE; + if (range != null) { - label.setForeground(Color.RED); - label.setText("Parsing failed"); + min = range.min(); + max = range.max(); } - else if (result) + + // Config may previously have been out of range + value = Ints.constrainToRange(value, min, max); + + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + Units units = cid.getUnits(); + if (units != null) { - label.setForeground(Color.GREEN); - label.setText("Valid input"); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); + } + + return spinner; + } + + private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); + + SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + return spinner; + } + + private JTextComponent createTextField(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JTextComponent textField; + + if (cid.getItem().secret()) + { + textField = new JPasswordField(); } else { - label.setForeground(Color.RED); - label.setText("Invalid input"); + final JTextArea textArea = new JTextArea(); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + textField = textArea; } - } - private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) - { - Class enumType = cid.getItem().enumClass(); - EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), EnumSet.class); - if (enumSet == null) + textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + + textField.addFocusListener(new FocusAdapter() { - //noinspection unchecked - enumSet = EnumSet.noneOf(enumType); - } - enumSet.clear(); - - EnumSet finalEnumSet = enumSet; - - //noinspection unchecked - components.forEach(value -> - { - if (value.isSelected()) + @Override + public void focusLost(FocusEvent e) { - finalEnumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); + changeConfiguration(textField, cd, cid); } }); - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), finalEnumSet); + return textField; + } - rebuild(); + private ColorJButton createColorPicker(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); + + ColorJButton colorPickerBtn; + + boolean alphaHidden = cid.getAlpha() == null; + + if (existing == null) + { + colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); + } + else + { + String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); + colorPickerBtn = new ColorJButton(colorHex, existing); + } + + colorPickerBtn.setFocusable(false); + colorPickerBtn.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + RuneliteColorPicker colorPicker = colorPickerManager.create( + SwingUtilities.windowForComponent(ConfigPanel.this), + colorPickerBtn.getColor(), + cid.getItem().name(), + alphaHidden); + colorPicker.setLocation(getLocationOnScreen()); + colorPicker.setOnColorChange(c -> + { + colorPickerBtn.setColor(c); + colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); + }); + colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); + colorPicker.setVisible(true); + } + }); + + return colorPickerBtn; + } + + private JPanel createDimension(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JPanel dimensionPanel = new JPanel(); + dimensionPanel.setLayout(new BorderLayout()); + + String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); + String[] splitStr = str.split("x"); + int width = Integer.parseInt(splitStr[0]); + int height = Integer.parseInt(splitStr[1]); + + SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); + JSpinner widthSpinner = new JSpinner(widthModel); + Component widthEditor = widthSpinner.getEditor(); + JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); + widthSpinnerTextField.setColumns(4); + + SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); + JSpinner heightSpinner = new JSpinner(heightModel); + Component heightEditor = heightSpinner.getEditor(); + JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); + heightSpinnerTextField.setColumns(4); + + ChangeListener listener = e -> + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + + widthSpinner.addChangeListener(listener); + heightSpinner.addChangeListener(listener); + + dimensionPanel.add(widthSpinner, BorderLayout.WEST); + dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); + dimensionPanel.add(heightSpinner, BorderLayout.EAST); + + return dimensionPanel; + } + + private JComboBox> createComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Class type = (Class) cid.getType(); + + JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator + // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer + // to build components for each combobox element in order to compute the display size of the + // combobox + box.setRenderer(listCellRenderer); + box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); + box.setForeground(Color.WHITE); + box.setFocusable(false); + + try + { + Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + box.setSelectedItem(selectedItem); + box.setToolTipText(Text.titleCase(selectedItem)); + } + catch (IllegalArgumentException ex) + { + log.debug("invalid selected item", ex); + } + box.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + changeConfiguration(box, cd, cid); + box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); + } + }); + + return box; + } + + private HotkeyButton createKeybind(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), + cid.getItem().keyName(), + (Class) cid.getType()); + + HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); + + button.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(button, cd, cid); + } + }); + + return button; + } + + private JList> createList(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + Class type = (Class) parameterizedType.getActualTypeArguments()[0]; + Set set = configManager.getConfiguration(cd.getGroup().value(), null, + cid.getItem().keyName(), parameterizedType); + + JList> list = new JList>(type.getEnumConstants()); // NOPMD: UseDiamondOperator + list.setCellRenderer(listCellRenderer); + list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + list.setLayoutOrientation(JList.VERTICAL); + list.setSelectedIndices( + MoreObjects.firstNonNull(set, Collections.emptySet()) + .stream() + .mapToInt(e -> ArrayUtils.indexOf(type.getEnumConstants(), e)) + .toArray()); + list.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(list, cd, cid); + } + }); + + return list; } private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid) @@ -1019,11 +791,6 @@ class ConfigPanel extends PluginPanel JSpinner spinner = (JSpinner) component; configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), "" + spinner.getValue()); } - else if (component instanceof JSlider) - { - JSlider slider = (JSlider) component; - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), slider.getValue()); - } else if (component instanceof JTextComponent) { JTextComponent textField = (JTextComponent) component; @@ -1044,6 +811,13 @@ class ConfigPanel extends PluginPanel HotkeyButton hotkeyButton = (HotkeyButton) component; configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue()); } + else if (component instanceof JList) + { + JList list = (JList) component; + List selectedValues = list.getSelectedValuesList(); + + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Sets.newHashSet(selectedValues)); + } enableDisable(component, cid); rebuild(); @@ -1121,7 +895,7 @@ class ConfigPanel extends PluginPanel { show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); } - else if (cid2.getType().isEnum()) + else if (cid2.getType() instanceof Class && ((Class) cid2.getType()).isEnum()) { Class type = (Class) cid2.getType(); try From 11517494477937708ded4ec9347bea62629ff16f Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 9 Dec 2021 09:42:03 +1100 Subject: [PATCH 02/42] configpanel: checkstyle + togglebutton for boolean --- .../client/plugins/config/ConfigPanel.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index df8c74cf0f..c526d66379 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -31,7 +31,16 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.Sets; import com.google.common.primitives.Ints; -import java.awt.*; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; @@ -47,7 +56,29 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.inject.Inject; -import javax.swing.*; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JSpinner; +import javax.swing.JTextArea; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; @@ -82,6 +113,7 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.ColorJButton; import net.runelite.client.ui.components.ComboBoxListRenderer; +import net.runelite.client.ui.components.ToggleButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker; import net.runelite.client.util.ColorUtil; @@ -521,8 +553,8 @@ class ConfigPanel extends PluginPanel private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid) { - JCheckBox checkbox = new JCheckBox(); - checkbox.setBackground(ColorScheme.LIGHT_GRAY_COLOR); + JCheckBox checkbox = new ToggleButton(); + checkbox.setPreferredSize(new Dimension(26, 25)); checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); return checkbox; From 595f65c7b707ef6d7f3df16be6861b4b24ae7d46 Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 9 Dec 2021 10:24:33 +1100 Subject: [PATCH 03/42] worldhopper: allow selecting multiple region filters --- .../plugins/worldhopper/RegionFilterMode.java | 28 ++++++++++++++----- .../worldhopper/WorldHopperConfig.java | 10 ++++--- .../worldhopper/WorldHopperPlugin.java | 9 ++++-- .../worldhopper/WorldSwitcherPanel.java | 5 ++-- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java index dccd9d499c..32713a7b17 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java @@ -24,16 +24,13 @@ */ package net.runelite.client.plugins.worldhopper; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import net.runelite.http.api.worlds.WorldRegion; -@NoArgsConstructor -@AllArgsConstructor -public enum RegionFilterMode +@RequiredArgsConstructor +enum RegionFilterMode { - NONE, AUSTRALIA(WorldRegion.AUSTRALIA), GERMANY(WorldRegion.GERMANY), UNITED_KINGDOM(WorldRegion.UNITED_KINGDOM) @@ -54,5 +51,22 @@ public enum RegionFilterMode }; @Getter - private WorldRegion region; + private final WorldRegion region; + + static RegionFilterMode of(WorldRegion region) + { + switch (region) + { + case UNITED_STATES_OF_AMERICA: + return UNITED_STATES; + case UNITED_KINGDOM: + return UNITED_KINGDOM; + case AUSTRALIA: + return AUSTRALIA; + case GERMANY: + return GERMANY; + default: + throw new IllegalStateException(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index 11db14d55a..0c087993cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -27,6 +27,8 @@ package net.runelite.client.plugins.worldhopper; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.Collections; +import java.util.Set; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -76,9 +78,9 @@ public interface WorldHopperConfig extends Config description = "Limit quick-hopping to worlds of a specific region", position = 3 ) - default RegionFilterMode quickHopRegionFilter() + default Set quickHopRegionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( @@ -142,9 +144,9 @@ public interface WorldHopperConfig extends Config description = "Restrict sidebar worlds to one region", position = 8 ) - default RegionFilterMode regionFilter() + default Set regionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index dcb8d5e560..61ef2e963c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -36,6 +36,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -355,7 +356,7 @@ public class WorldHopperPlugin extends Plugin return; } - final int componentId = event.getParam1(); + final int componentId = event.getActionParam1(); int groupId = WidgetInfo.TO_GROUP(componentId); String option = event.getOption(); @@ -401,7 +402,7 @@ public class WorldHopperPlugin extends Plugin hopTo.setTarget(event.getTarget()); hopTo.setType(MenuAction.RUNELITE.getId()); hopTo.setParam0(event.getActionParam0()); - hopTo.setParam1(event.getParam1()); + hopTo.setParam1(event.getActionParam1()); insertMenuEntry(hopTo, client.getMenuEntries(), after); } @@ -533,6 +534,8 @@ public class WorldHopperPlugin extends Plugin int worldIdx = worlds.indexOf(currentWorld); int totalLevel = client.getTotalLevel(); + final Set regionFilter = config.quickHopRegionFilter(); + World world; do { @@ -564,7 +567,7 @@ public class WorldHopperPlugin extends Plugin world = worlds.get(worldIdx); // Check world region if filter is enabled - if (config.quickHopRegionFilter() != RegionFilterMode.NONE && world.getRegion() != config.quickHopRegionFilter().getRegion()) + if (!regionFilter.isEmpty() && !regionFilter.contains(RegionFilterMode.of(world.getRegion()))) { continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index e1e541d1bf..d446204884 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -34,6 +34,7 @@ import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -68,7 +69,7 @@ class WorldSwitcherPanel extends PluginPanel @Setter(AccessLevel.PACKAGE) private SubscriptionFilterMode subscriptionFilterMode; @Setter(AccessLevel.PACKAGE) - private RegionFilterMode regionFilterMode; + private Set regionFilterMode; WorldSwitcherPanel(WorldHopperPlugin plugin) { @@ -249,7 +250,7 @@ class WorldSwitcherPanel extends PluginPanel break; } - if (regionFilterMode.getRegion() != null && !regionFilterMode.getRegion().equals(world.getRegion())) + if (!regionFilterMode.isEmpty() && !regionFilterMode.contains(RegionFilterMode.of(world.getRegion()))) { continue; } From 409d0dda7661468d0cc3c664894421bc7e17f1b2 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 4 Dec 2021 15:28:27 -0500 Subject: [PATCH 04/42] api: make MenuEntry an interface This adds a new createMenuEntry api method to make MenuEntries instead. Menu entries now have an associated callback called when they are clicked on, avoiding most plugins from having to hook separately to detect the menu click. Additionally get/set type has changed to take a MenuAction. --- .../main/java/net/runelite/api/Client.java | 7 + .../main/java/net/runelite/api/MenuEntry.java | 48 +++-- .../api/events/WidgetMenuOptionClicked.java | 54 ------ .../java/net/runelite/client/RuneLite.java | 1 - .../runelite/client/menus/MenuManager.java | 55 ++---- .../client/menus/WidgetMenuOption.java | 4 + .../plugins/banktags/BankTagsPlugin.java | 141 +++++++-------- .../plugins/banktags/tabs/TabInterface.java | 36 ++-- .../client/plugins/camera/CameraPlugin.java | 2 +- .../chathistory/ChatHistoryPlugin.java | 39 ++--- .../plugins/devtools/DevToolsPlugin.java | 1 - .../plugins/devtools/WidgetInspector.java | 14 +- .../friendnotes/FriendNotesPlugin.java | 76 +++----- .../grandexchange/GrandExchangePlugin.java | 3 +- .../grounditems/GroundItemsPlugin.java | 21 +-- .../groundmarkers/GroundMarkerPlugin.java | 65 +++---- .../GroundMarkerSharingManager.java | 44 +---- .../client/plugins/hiscore/HiscorePlugin.java | 64 +++---- .../instancemap/InstanceMapPlugin.java | 39 ++--- .../InteractHighlightOverlay.java | 2 +- .../inventorytags/InventoryTagsPlugin.java | 97 +++++------ .../plugins/itemprices/ItemPricesOverlay.java | 2 +- .../MenuEntrySwapperPlugin.java | 106 +++++------ .../mousehighlight/MouseHighlightOverlay.java | 2 +- .../npchighlight/NpcIndicatorsPlugin.java | 54 ++---- .../ObjectIndicatorsPlugin.java | 35 ++-- .../opponentinfo/OpponentInfoPlugin.java | 1 - .../PlayerIndicatorsPlugin.java | 42 ++--- .../client/plugins/wiki/WikiPlugin.java | 42 ++--- .../worldhopper/WorldHopperPlugin.java | 52 ++---- .../plugins/xptracker/XpTrackerPlugin.java | 60 ++----- .../client/ui/overlay/OverlayManager.java | 34 +--- .../client/ui/overlay/OverlayRenderer.java | 66 +++---- .../ui/overlay/worldmap/WorldMapOverlay.java | 56 ++---- .../client/menus/MenuManagerTest.java | 76 ++++---- .../runelite/client/menus/TestMenuEntry.java | 164 ++++++++++++++++++ .../MenuEntrySwapperPluginTest.java | 10 +- .../npchighlight/NpcIndicatorsPluginTest.java | 16 +- 38 files changed, 665 insertions(+), 966 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java create mode 100644 runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 5f1175fcdd..e53d03ec7f 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -593,6 +593,13 @@ public interface Client extends GameEngine */ World[] getWorldList(); + /** + * Create a new menu entry + * @param idx the index to create the menu entry at. Accepts negative indexes eg. -1 inserts at the end. + * @return the newly created menu entry + */ + MenuEntry createMenuEntry(int idx); + /** * Gets an array of currently open right-click menu entries that can be * clicked and activated. diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index e28165e603..6891927c4b 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,46 +24,72 @@ */ package net.runelite.api; -import lombok.Data; +import java.util.function.Consumer; /** * A menu entry in a right-click menu. */ -@Data -public class MenuEntry +public interface MenuEntry { /** * The option text added to the menu. (ie. "Walk here", "Use") */ - private String option; + String getOption(); + MenuEntry setOption(String option); + /** * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. */ - private String target; + String getTarget(); + MenuEntry setTarget(String target); + /** * An identifier value for the target of the action. */ - private int identifier; + int getIdentifier(); + MenuEntry setIdentifier(int identifier); + /** * The action the entry will trigger. */ - private int type; + MenuAction getType(); + MenuEntry setType(MenuAction type); + /** * An additional parameter for the action. */ - private int param0; + int getParam0(); + MenuEntry setParam0(int param0); + /** * A second additional parameter for the action. */ - private int param1; + int getParam1(); + MenuEntry setParam1(int param1); + /** - * If this field is true and you have single mouse button on and this entry is + * If this is true and you have single mouse button on and this entry is * the top entry the right click menu will not be opened when you left click * * This is used for shift click */ - private boolean forceLeftClick; + boolean isForceLeftClick(); + MenuEntry setForceLeftClick(boolean forceLeftClick); + + /** + * Deprioritized menus are sorted in the menu to be below the other menu entries. + * @return + */ + boolean isDeprioritized(); + void setDeprioritized(boolean deprioritized); + + /** + * Set a callback to be called when this menu option is clicked + * @param callback + * @return + */ + MenuEntry onClick(Consumer callback); } diff --git a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java deleted file mode 100644 index d3a4dda748..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.api.events; - -import javax.annotation.Nullable; -import lombok.Data; -import net.runelite.api.widgets.WidgetInfo; - -/** - * A MenuManager widget menu was clicked. This event is fired only for MenuManager managed custom menus. - */ -@Data -public class WidgetMenuOptionClicked -{ - /** - * The clicked menu option. - */ - private String menuOption; - /** - * The clicked menu target. - */ - private String menuTarget; - /** - * The WidgetInfo of the widget that was clicked, if available. - */ - @Nullable - private WidgetInfo widget; - /** - * The widget id of the widget that was clicked. - */ - private int widgetId; -} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index dde04da268..142c4570c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -326,7 +326,6 @@ public class RuneLite // Add core overlays WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add); overlayManager.add(worldMapOverlay.get()); - eventBus.register(worldMapOverlay.get()); overlayManager.add(tooltipOverlay.get()); } diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index c6a952239a..2b77f99e13 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -27,10 +27,10 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -38,9 +38,7 @@ import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PlayerMenuOptionsChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -55,7 +53,6 @@ public class MenuManager private static final int IDX_UPPER = 8; private final Client client; - private final EventBus eventBus; //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); @@ -66,7 +63,6 @@ public class MenuManager private MenuManager(Client client, EventBus eventBus) { this.client = client; - this.eventBus = eventBus; eventBus.register(this); } @@ -74,10 +70,12 @@ public class MenuManager * Adds a CustomMenuOption to the list of managed menu options. * * @param customMenuOption The custom menu to add + * @param callback callback to be called when the menu is clicked */ - public void addManagedCustomMenu(WidgetMenuOption customMenuOption) + public void addManagedCustomMenu(WidgetMenuOption customMenuOption, Consumer callback) { managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption); + customMenuOption.callback = callback; } /** @@ -122,11 +120,10 @@ public class MenuManager MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry[] newMenuEntries = Arrays.copyOf(menuEntries, menuEntries.length + options.size()); // Menu entries are sorted with higher-index entries appearing toward the top of the minimenu, so insert older // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at // the bottom - int insertIdx = newMenuEntries.length - 1; + int insertIdx = -1; for (WidgetMenuOption currentMenu : options) { // Exit if we've inserted the managed menu entries already @@ -135,16 +132,13 @@ public class MenuManager return; } - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - newMenuEntries[insertIdx--] = menuEntry; + client.createMenuEntry(insertIdx--) + .setOption(currentMenu.getMenuOption()) + .setTarget(currentMenu.getMenuTarget()) + .setType(MenuAction.RUNELITE) + .setParam1(widgetId) + .onClick(currentMenu.callback); } - - client.setMenuEntries(newMenuEntries); } public void addPlayerMenuItem(String menuText) @@ -198,33 +192,6 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - int widgetId = event.getParam1(); - Collection options = managedMenuOptions.get(widgetId); - - for (WidgetMenuOption curMenuOption : options) - { - if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) - && curMenuOption.getMenuOption().equals(event.getMenuOption())) - { - WidgetMenuOptionClicked customMenu = new WidgetMenuOptionClicked(); - customMenu.setMenuOption(event.getMenuOption()); - customMenu.setMenuTarget(event.getMenuTarget()); - customMenu.setWidget(curMenuOption.getWidget()); - customMenu.setWidgetId(curMenuOption.getWidgetId()); - eventBus.post(customMenu); - return; - } - } - } - private void addPlayerMenuItem(int playerOptionIndex, String menuText) { client.getPlayerOptions()[playerOptionIndex] = menuText; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 1f1a74606b..7727897f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -25,9 +25,11 @@ package net.runelite.client.menus; import java.awt.Color; +import java.util.function.Consumer; import javax.annotation.Nullable; import lombok.Getter; import lombok.Setter; +import net.runelite.api.MenuEntry; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @@ -65,6 +67,8 @@ public final class WidgetMenuOption @Getter private final int widgetId; + Consumer callback; + /** * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 70088692c8..bacab9beae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -341,8 +341,6 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - MenuEntry[] entries = client.getMenuEntries(); - if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { @@ -357,87 +355,80 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener text += " (" + tagCount + ")"; } - MenuEntry editTags = new MenuEntry(); - editTags.setParam0(event.getActionParam0()); - editTags.setParam1(event.getActionParam1()); - editTags.setTarget(event.getTarget()); - editTags.setOption(text); - editTags.setType(MenuAction.RUNELITE.getId()); - editTags.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = editTags; - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(event.getTarget()) + .setOption(text) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(this::editTags); } tabInterface.handleAdd(event); } + private void editTags(MenuEntry entry) + { + int inventoryIndex = entry.getParam0(); + ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); + if (bankContainer == null) + { + return; + } + Item[] items = bankContainer.getItems(); + if (inventoryIndex < 0 || inventoryIndex >= items.length) + { + return; + } + Item item = bankContainer.getItems()[inventoryIndex]; + if (item == null) + { + return; + } + + int itemId = item.getId(); + ItemComposition itemComposition = itemManager.getItemComposition(itemId); + String name = itemComposition.getName(); + + // Get both tags and vartags and append * to end of vartags name + Collection tags = tagManager.getTags(itemId, false); + tagManager.getTags(itemId, true).stream() + .map(i -> i + "*") + .forEach(tags::add); + + String initialValue = Text.toCSV(tags); + + chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") + .addCharValidator(FILTERED_CHARS) + .value(initialValue) + .onDone((Consumer) (newValue) -> + clientThread.invoke(() -> + { + // Split inputted tags to vartags (ending with *) and regular tags + final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); + final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> + { + newTags.remove(s); + return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); + }).collect(Collectors.toList()); + + // And save them + tagManager.setTagString(itemId, Text.toCSV(newTags), false); + tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); + + // Check both previous and current tags in case the tag got removed in new tags or in case + // the tag got added in new tags + tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + })) + .build(); + } + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() - && event.getMenuAction() == MenuAction.RUNELITE - && event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION)) - { - event.consume(); - int inventoryIndex = event.getParam0(); - ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); - if (bankContainer == null) - { - return; - } - Item[] items = bankContainer.getItems(); - if (inventoryIndex < 0 || inventoryIndex >= items.length) - { - return; - } - Item item = bankContainer.getItems()[inventoryIndex]; - if (item == null) - { - return; - } - - int itemId = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(itemId); - String name = itemComposition.getName(); - - // Get both tags and vartags and append * to end of vartags name - Collection tags = tagManager.getTags(itemId, false); - tagManager.getTags(itemId, true).stream() - .map(i -> i + "*") - .forEach(tags::add); - - String initialValue = Text.toCSV(tags); - - chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") - .addCharValidator(FILTERED_CHARS) - .value(initialValue) - .onDone((Consumer) (newValue) -> - clientThread.invoke(() -> - { - // Split inputted tags to vartags (ending with *) and regular tags - final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); - final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> - { - newTags.remove(s); - return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); - }).collect(Collectors.toList()); - - // And save them - tagManager.setTagString(itemId, Text.toCSV(newTags), false); - tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); - - // Check both previous and current tags in case the tag got removed in new tags or in case - // the tag got added in new tags - tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - })) - .build(); - } - else - { - tabInterface.handleClick(event); - } + tabInterface.handleClick(event); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 04c41c9d1b..7a1954e656 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -618,38 +618,32 @@ public class TabInterface return; } - MenuEntry[] entries = client.getMenuEntries(); if (activeTab != null && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { - entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); - client.setMenuEntries(entries); + createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget()); } else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getOption().equals("Deposit inventory")) { - entries = createMenuEntry(event, TAG_INVENTORY, event.getTarget(), entries); + createMenuEntry(event, TAG_INVENTORY, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getOption().equals("Deposit worn items")) { - entries = createMenuEntry(event, TAG_GEAR, event.getTarget(), entries); + createMenuEntry(event, TAG_GEAR, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } } @@ -773,7 +767,6 @@ public class TabInterface { entry.setOption(TAG_SEARCH + Text.removeTags(entry.getTarget()) + (shiftDown ? VAR_TAG_SUFFIX : "")); entry.setTarget(draggedWidget.getName()); - client.setMenuEntries(entries); } if (entry.getOption().equals(SCROLL_UP)) @@ -1195,17 +1188,14 @@ public class TabInterface searchButtonBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE); } - private static MenuEntry[] createMenuEntry(MenuEntryAdded event, String option, String target, MenuEntry[] entries) + private void createMenuEntry(MenuEntryAdded event, String option, String target) { - final MenuEntry entry = new MenuEntry(); - entry.setParam0(event.getActionParam0()); - entry.setParam1(event.getActionParam1()); - entry.setTarget(target); - entry.setOption(option); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = entry; - return entries; + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(target) + .setOption(option) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java index dfb29e8950..21c495b603 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java @@ -294,7 +294,7 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener { for (MenuEntry menuEntry : menuEntries) { - MenuAction action = MenuAction.of(menuEntry.getType()); + MenuAction action = menuEntry.getType(); switch (action) { case CANCEL: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index ad6530a2e7..2b11c3318b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.chathistory; -import com.google.common.base.Strings; import com.google.common.collect.EvictingQueue; import com.google.inject.Provides; import java.awt.Toolkit; @@ -83,8 +82,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener private Queue messageQueue; private Deque friends; - private String currentMessage = null; - @Inject private Client client; @@ -121,7 +118,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener messageQueue = null; friends.clear(); friends = null; - currentMessage = null; keyManager.unregisterKeyListener(this); } @@ -195,7 +191,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener // Use second entry as first one can be walk here with transparent chatbox final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2]; - if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY.getId() && entry.getType() != MenuAction.RUNELITE.getId()) + if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY && entry.getType() != MenuAction.RUNELITE) { return; } @@ -236,16 +232,17 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - currentMessage = messageContents.getText(); + String currentMessage = messageContents.getText(); - final MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(COPY_TO_CLIPBOARD); - menuEntry.setTarget(entry.getTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - menuEntry.setParam0(entry.getParam0()); - menuEntry.setParam1(entry.getParam1()); - menuEntry.setIdentifier(entry.getIdentifier()); - client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry)); + client.createMenuEntry(1) + .setOption(COPY_TO_CLIPBOARD) + .setTarget(entry.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + }); } @Subscribe @@ -258,11 +255,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { clearChatboxHistory(ChatboxTab.of(event.getParam1())); } - else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage)) - { - final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - } } @Subscribe @@ -279,10 +271,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - final MenuEntry clearEntry = new MenuEntry(); - clearEntry.setTarget(""); - clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId()); - clearEntry.setParam0(entry.getActionParam0()); + final MenuEntry clearEntry = client.createMenuEntry(-2) + .setType(MenuAction.RUNELITE_HIGH_PRIORITY); clearEntry.setParam1(entry.getActionParam1()); final StringBuilder optionBuilder = new StringBuilder(); @@ -299,9 +289,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener optionBuilder.append(CLEAR_HISTORY); clearEntry.setOption(optionBuilder.toString()); - - final MenuEntry[] menuEntries = client.getMenuEntries(); - client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry)); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index b9cc30c8dd..a1588594ab 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -488,7 +488,6 @@ public class DevToolsPlugin extends Plugin } entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); - client.setMenuEntries(entries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java index 2f361bc99b..6e27c99a35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java @@ -487,7 +487,7 @@ class WidgetInspector extends DevToolsFrame client.setSpellSelected(false); ev.consume(); - Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction().getId(), ev.getParam0(), ev.getParam1()); + Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction(), ev.getParam0(), ev.getParam1()); if (target == null) { return; @@ -516,8 +516,8 @@ class WidgetInspector extends DevToolsFrame for (int i = 0; i < menuEntries.length; i++) { MenuEntry entry = menuEntries[i]; - if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET.getId() - && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET + && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET) { continue; } @@ -532,8 +532,6 @@ class WidgetInspector extends DevToolsFrame entry.setTarget(ColorUtil.wrapWithColorTag(name, color)); } - - client.setMenuEntries(menuEntries); } Color colorForWidget(int index, int length) @@ -543,9 +541,9 @@ class WidgetInspector extends DevToolsFrame return Color.getHSBColor(h, 1, 1); } - Object getWidgetOrWidgetItemForMenuOption(int type, int param0, int param1) + Object getWidgetOrWidgetItemForMenuOption(MenuAction type, int param0, int param1) { - if (type == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (type == MenuAction.SPELL_CAST_ON_WIDGET) { Widget w = client.getWidget(param1); if (param0 != -1) @@ -555,7 +553,7 @@ class WidgetInspector extends DevToolsFrame return w; } - else if (type == MenuAction.ITEM_USE_ON_WIDGET.getId()) + else if (type == MenuAction.ITEM_USE_ON_WIDGET) { Widget w = client.getWidget(param1); return w.getWidgetItem(param0); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index db87e799a0..c274b74834 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -28,7 +28,6 @@ package net.runelite.client.plugins.friendnotes; import com.google.common.base.Strings; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; @@ -43,12 +42,10 @@ import net.runelite.api.GameState; import net.runelite.api.Ignore; import net.runelite.api.IndexedSprite; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Nameable; import net.runelite.api.ScriptID; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.RemovedFriend; import net.runelite.api.events.ScriptCallbackEvent; @@ -245,16 +242,31 @@ public class FriendNotesPlugin extends Plugin setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget()))); // Build "Add Note" or "Edit Note" menu entry - final MenuEntry addNote = new MenuEntry(); - addNote.setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE); - addNote.setType(MenuAction.RUNELITE.getId()); - addNote.setTarget(event.getTarget()); //Preserve color codes here - addNote.setParam0(event.getActionParam0()); - addNote.setParam1(event.getActionParam1()); + client.createMenuEntry(-1) + .setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + //Friends have color tags + final String sanitizedTarget = Text.toJagexName(Text.removeTags(e.getTarget())); + final String note = getFriendNote(sanitizedTarget); - // Add menu entry - final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), addNote); - client.setMenuEntries(menuEntries); + // Open the new chatbox input dialog + chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) + .value(Strings.nullToEmpty(note)) + .onDone((content) -> + { + if (content == null) + { + return; + } + + content = Text.removeTags(content).trim(); + log.debug("Set note for '{}': '{}'", sanitizedTarget, content); + setFriendNote(sanitizedTarget, content); + }).build(); + }); } else if (hoveredFriend != null) { @@ -262,46 +274,6 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); - - if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.IGNORE_LIST.getGroupId()) - { - if (Strings.isNullOrEmpty(event.getMenuTarget())) - { - return; - } - - // Handle clicks on "Add Note" or "Edit Note" - if (event.getMenuOption().equals(ADD_NOTE) || event.getMenuOption().equals(EDIT_NOTE)) - { - event.consume(); - - //Friends have color tags - final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getMenuTarget())); - final String note = getFriendNote(sanitizedTarget); - - // Open the new chatbox input dialog - chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) - .value(Strings.nullToEmpty(note)) - .onDone((content) -> - { - if (content == null) - { - return; - } - - content = Text.removeTags(content).trim(); - log.debug("Set note for '{}': '{}'", sanitizedTarget, content); - setFriendNote(sanitizedTarget, content); - }).build(); - } - } - - } - @Subscribe public void onNameableNameChanged(NameableNameChanged event) { 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 6075b23e11..697bf0d43b 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 @@ -574,8 +574,7 @@ public class GrandExchangePlugin extends Plugin case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID: case WidgetID.SHOP_INVENTORY_GROUP_ID: menuEntry.setOption(SEARCH_GRAND_EXCHANGE); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(entries); + menuEntry.setType(MenuAction.RUNELITE); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 655ae55fc7..6490f4d8d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin static final int MAX_QUANTITY = 65535; // ItemID for coins private static final int COINS = ItemID.COINS_995; - // Ground item menu options - private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId(); - private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId(); - private static final int THIRD_OPTION = MenuAction.GROUND_ITEM_THIRD_OPTION.getId(); // this is Take - private static final int FOURTH_OPTION = MenuAction.GROUND_ITEM_FOURTH_OPTION.getId(); - private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId(); - private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); - private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); @@ -344,9 +336,10 @@ public class GroundItemsPlugin extends Plugin { MenuEntry menuEntry = menuEntries[i]; - int menuType = menuEntry.getType(); - if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION - || menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) + MenuAction menuType = menuEntry.getType(); + if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION + || menuType == MenuAction.GROUND_ITEM_THIRD_OPTION || menuType == MenuAction.GROUND_ITEM_FOURTH_OPTION + || menuType == MenuAction.GROUND_ITEM_FIFTH_OPTION || menuType == MenuAction.SPELL_CAST_ON_GROUND_ITEM) { for (MenuEntryWithCount entryWCount : newEntries) { @@ -490,8 +483,8 @@ public class GroundItemsPlugin extends Plugin { if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH) { - final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM; - if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry) + final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); + if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry) { return; } @@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin { lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); } - - client.setMenuEntries(menuEntries); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 850f383439..e8de79d73e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -30,7 +30,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -44,13 +43,11 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -243,48 +240,34 @@ public class GroundMarkerPlugin extends Plugin final GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), null, null); final boolean exists = getPoints(regionId).contains(point); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + (exists ? 2 : 1)); - - MenuEntry mark = menuEntries[menuEntries.length - 1] = new MenuEntry(); - mark.setOption(exists ? UNMARK : MARK); - mark.setTarget(event.getTarget()); - mark.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-1) + .setOption(exists ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + markTile(target.getLocalLocation()); + } + }); if (exists) { - MenuEntry label = menuEntries[menuEntries.length - 2] = new MenuEntry(); - label.setOption(LABEL); - label.setTarget(event.getTarget()); - label.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-2) + .setOption(LABEL) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + labelTile(target); + } + }); } - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId()) - { - return; - } - - Tile target = client.getSelectedSceneTile(); - if (target == null) - { - return; - } - - final String option = event.getMenuOption(); - if (option.equals(MARK) || option.equals(UNMARK)) - { - markTile(target.getLocalLocation()); - } - else if (option.equals(LABEL)) - { - labelTile(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index d311a51319..a7661ff202 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -45,11 +45,10 @@ import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.events.WidgetMenuOptionClicked; +import net.runelite.api.MenuEntry; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; @@ -82,13 +81,13 @@ class GroundMarkerSharingManager void addImportExportMenuOptions() { - menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); - menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION, this::exportGroundMarkers); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION, this::promptForImport); } void addClearMenuOption() { - menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION); + menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION, this::promptForClear); } void removeMenuOptions() @@ -98,36 +97,7 @@ class GroundMarkerSharingManager menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION); } - private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) - { - return event.getMenuTarget().equals(target.getMenuTarget()) && - event.getMenuOption().equals(target.getMenuOption()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - // ensure that the option clicked is the export markers option - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) - { - exportGroundMarkers(); - } - else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) - { - promptForImport(); - } - else if (widgetMenuClickedEquals(event, CLEAR_MARKERS_OPTION)) - { - promptForClear(); - } - } - - private void exportGroundMarkers() + private void exportGroundMarkers(MenuEntry menuEntry) { int[] regions = client.getMapRegions(); if (regions == null) @@ -156,7 +126,7 @@ class GroundMarkerSharingManager sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); } - private void promptForImport() + private void promptForImport(MenuEntry menuEntry) { final String clipboardText; try @@ -244,7 +214,7 @@ class GroundMarkerSharingManager sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); } - private void promptForClear() + private void promptForClear(MenuEntry entry) { int[] regions = client.getMapRegions(); if (regions == null) 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 95f12ec821..6123055d1c 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 @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.hiscore; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.util.EnumSet; @@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.IconID; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Player; import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; @@ -59,7 +57,6 @@ import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; import net.runelite.http.api.hiscore.HiscoreEndpoint; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "HiScore", @@ -169,46 +166,37 @@ public class HiscorePlugin extends Plugin || groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore")) ) { - final MenuEntry lookup = new MenuEntry(); - lookup.setOption(LOOKUP); - lookup.setTarget(event.getTarget()); - lookup.setType(MenuAction.RUNELITE.getId()); - lookup.setParam0(event.getActionParam0()); - lookup.setParam1(event.getActionParam1()); - lookup.setIdentifier(event.getIdentifier()); - - insertMenuEntry(lookup, client.getMenuEntries()); + client.createMenuEntry(-2) + .setOption(LOOKUP) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(e -> + { + // Determine proper endpoint from player name. + // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. + HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); + String target = Text.removeTags(e.getTarget()); + lookupPlayer(target, endpoint); + }); } } @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) - && event.getMenuOption().equals(LOOKUP)) + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP)) { - final String target; - HiscoreEndpoint endpoint; - if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) { - // The player id is included in the event, so we can use that to get the player name, - // which avoids having to parse out the combat level and any icons preceding the name. - Player player = client.getCachedPlayers()[event.getId()]; - if (player == null) - { - return; - } + return; + } - endpoint = getWorldEndpoint(); - target = player.getName(); - } - else - { - // Determine proper endpoint from player name. - // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. - endpoint = findHiscoreEndpointFromPlayerName(event.getMenuTarget()); - target = Text.removeTags(event.getMenuTarget()); - } + String target = player.getName(); + HiscoreEndpoint endpoint = getWorldEndpoint(); lookupPlayer(target, endpoint); } @@ -236,14 +224,6 @@ public class HiscorePlugin extends Plugin localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer(); } - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - client.setMenuEntries(newMenu); - } - private void lookupPlayer(String playerName, HiscoreEndpoint endpoint) { SwingUtilities.invokeLater(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java index f5cc4b6a51..8ed901350a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap; import com.google.inject.Binder; import javax.inject.Inject; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; @@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin private void addCustomOptions() { - menuManager.addManagedCustomMenu(openMapOption); + menuManager.addManagedCustomMenu(openMapOption, entry -> + { + if (overlay.isMapShown()) + { + closeMap(); + } + else + { + showMap(); + } + }); } private void removeCustomOptions() @@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin overlay.onGameStateChange(event); } - private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption) - { - return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (clickedOptionEquals(event, openMapOption)) - { - if (overlay.isMapShown()) - { - closeMap(); - } - else - { - showMap(); - } - } - } - public void showMap() { overlay.setShowMap(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java index a5dd9c95da..0a14053e36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java @@ -79,7 +79,7 @@ class InteractHighlightOverlay extends Overlay } MenuEntry top = menuEntries[menuEntries.length - 1]; - MenuAction menuAction = MenuAction.of(top.getType()); + MenuAction menuAction = top.getType(); switch (menuAction) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index cdbf26a845..d588ed42aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.inject.Provides; import java.awt.Color; +import java.util.Arrays; import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuOpened; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -46,7 +45,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.Text; @PluginDescriptor( name = "Inventory Tags", @@ -157,44 +155,11 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - editorMode = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET); - refreshInventoryMenuOptions(); - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - final String selectedMenu = Text.removeTags(event.getMenuTarget()); - - if (event.getMenuOption().equals(MENU_SET)) - { - setTag(event.getId(), selectedMenu); - } - else if (event.getMenuOption().equals(MENU_REMOVE)) - { - unsetTag(event.getId()); - } - } - @Subscribe public void onMenuOpened(final MenuOpened event) { final MenuEntry firstEntry = event.getFirstEntry(); - - if (firstEntry == null) + if (firstEntry == null || !editorMode) { return; } @@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin final int widgetId = firstEntry.getParam1(); // Inventory item menu - if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode) + if (widgetId == WidgetInfo.INVENTORY.getId()) { int itemId = firstEntry.getIdentifier(); @@ -211,26 +176,30 @@ public class InventoryTagsPlugin extends Plugin return; } - MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1]; - int num = 0; - - // preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action - menuList[num++] = event.getMenuEntries()[0]; + // Set menu to only be Cancel + client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1)); for (final String groupName : GROUPS) { final String group = getTag(itemId); - final MenuEntry newMenu = new MenuEntry(); final Color color = getGroupNameColor(groupName); - newMenu.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET); - newMenu.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))); - newMenu.setIdentifier(itemId); - newMenu.setParam1(widgetId); - newMenu.setType(MenuAction.RUNELITE.getId()); - menuList[num++] = newMenu; - } - client.setMenuEntries(menuList); + client.createMenuEntry(-1) + .setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET) + .setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (e.getOption().equals(MENU_SET)) + { + setTag(itemId, groupName); + } + else + { + unsetTag(itemId); + } + }); + } } } @@ -270,15 +239,27 @@ public class InventoryTagsPlugin extends Plugin removeInventoryMenuOptions(); if (editorMode) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save); } else { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE, this::configure); } } + + private void save(MenuEntry menuEntry) + { + editorMode = false; + refreshInventoryMenuOptions(); + } + + private void configure(MenuEntry menuEntry) + { + editorMode = true; + refreshInventoryMenuOptions(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java index ea33e614f8..bea5de5af5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java @@ -90,7 +90,7 @@ class ItemPricesOverlay extends Overlay } final MenuEntry menuEntry = menuEntries[last]; - final MenuAction action = MenuAction.of(menuEntry.getType()); + final MenuAction action = menuEntry.getType(); final int widgetId = menuEntry.getParam1(); final int groupId = WidgetInfo.TO_GROUP(widgetId); final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 56cb315caf..68ecf39f3b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -55,7 +55,6 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PostItemComposition; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; @@ -74,7 +73,6 @@ import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfi import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.MorytaniaLegsMode; import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Menu Entry Swapper", @@ -506,24 +504,6 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemCompositionCache); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - String option = event.getMenuOption(); - String target = Text.removeTags(event.getMenuTarget()); - if ((option.equals(CONFIGURE) || option.equals(SAVE)) && (target.equals(LEFT_CLICK_MENU_TARGET) || target.equals(SHIFT_CLICK_MENU_TARGET))) - { - configuringShiftClick = option.equals(CONFIGURE) && target.equals(SHIFT_CLICK_MENU_TARGET); - configuringLeftClick = option.equals(CONFIGURE) && target.equals(LEFT_CLICK_MENU_TARGET); - rebuildCustomizationMenus(); - } - } - } - @Subscribe public void onMenuOpened(MenuOpened event) { @@ -591,11 +571,11 @@ public class MenuEntrySwapperPlugin extends Plugin for (MenuEntry entry : entries) { - final MenuAction menuAction = MenuAction.of(entry.getType()); + final MenuAction menuAction = entry.getType(); if (ITEM_MENU_TYPES.contains(menuAction) && entry.getIdentifier() == itemId) { - entry.setType(MenuAction.RUNELITE.getId()); + entry.setType(MenuAction.RUNELITE); if (activeAction == menuAction) { @@ -604,13 +584,11 @@ public class MenuEntrySwapperPlugin extends Plugin } } - final MenuEntry resetShiftClickEntry = new MenuEntry(); - resetShiftClickEntry.setOption(RESET); - resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); - resetShiftClickEntry.setIdentifier(itemId); - resetShiftClickEntry.setParam1(widgetId); - resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); + client.createMenuEntry(-1) + .setOption(RESET) + .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) + .setType(MenuAction.RUNELITE) + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)); } @Subscribe @@ -636,8 +614,8 @@ public class MenuEntrySwapperPlugin extends Plugin final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox() : isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit() : shiftDepositMode.getIdentifier(); - final int actionId = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY.getId() : MenuAction.CC_OP.getId(); - bankModeSwap(actionId, opId); + final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP; + bankModeSwap(action, opId); } // Swap to shift-click withdraw behavior @@ -647,22 +625,23 @@ public class MenuEntrySwapperPlugin extends Plugin && menuEntryAdded.getOption().startsWith("Withdraw")) { ShiftWithdrawMode shiftWithdrawMode = config.bankWithdrawShiftClick(); - final int actionId, opId; + final MenuAction action; + final int opId; if (widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID || widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID) { - actionId = MenuAction.CC_OP.getId(); + action = MenuAction.CC_OP; opId = shiftWithdrawMode.getIdentifierChambersStorageUnit(); } else { - actionId = shiftWithdrawMode.getMenuAction().getId(); + action = shiftWithdrawMode.getMenuAction(); opId = shiftWithdrawMode.getIdentifier(); } - bankModeSwap(actionId, opId); + bankModeSwap(action, opId); } } - private void bankModeSwap(int entryTypeId, int entryIdentifier) + private void bankModeSwap(MenuAction entryType, int entryIdentifier) { MenuEntry[] menuEntries = client.getMenuEntries(); @@ -670,10 +649,10 @@ public class MenuEntrySwapperPlugin extends Plugin { MenuEntry entry = menuEntries[i]; - if (entry.getType() == entryTypeId && entry.getIdentifier() == entryIdentifier) + if (entry.getType() == entryType && entry.getIdentifier() == entryIdentifier) { // Raise the priority of the op so it doesn't get sorted later - entry.setType(MenuAction.CC_OP.getId()); + entry.setType(MenuAction.CC_OP); menuEntries[i] = menuEntries[menuEntries.length - 1]; menuEntries[menuEntries.length - 1] = entry; @@ -703,17 +682,6 @@ public class MenuEntrySwapperPlugin extends Plugin String target = event.getMenuTarget(); ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (option.equals(RESET) && target.equals(SHIFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(true, itemId); - return; - } - if (option.equals(RESET) && target.equals(LEFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(false, itemId); - return; - } - if (!itemComposition.getName().equals(Text.removeTags(target))) { return; @@ -741,7 +709,7 @@ public class MenuEntrySwapperPlugin extends Plugin private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) { final int eventId = menuEntry.getIdentifier(); - final MenuAction menuAction = MenuAction.of(menuEntry.getType()); + final MenuAction menuAction = menuEntry.getType(); final String option = Text.removeTags(menuEntry.getOption()).toLowerCase(); final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); @@ -968,31 +936,31 @@ public class MenuEntrySwapperPlugin extends Plugin removeCusomizationMenus(); if (configuringLeftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC, this::save); } else if (configuringShiftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC, this::save); } else { // Left click if (config.leftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC, this::configure); } // Shift click if (config.shiftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC, this::configure); } } } @@ -1001,4 +969,18 @@ public class MenuEntrySwapperPlugin extends Plugin { return client.isKeyPressed(KeyCode.KC_SHIFT); } + + private void save(MenuEntry menuEntry) + { + configuringLeftClick = configuringShiftClick = false; + rebuildCustomizationMenus(); + } + + private void configure(MenuEntry menuEntry) + { + String target = Text.removeTags(menuEntry.getTarget()); + configuringShiftClick = target.equals(SHIFT_CLICK_MENU_TARGET); + configuringLeftClick = target.equals(LEFT_CLICK_MENU_TARGET); + rebuildCustomizationMenus(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java index 1e56b743eb..f9355f0aa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java @@ -108,7 +108,7 @@ class MouseHighlightOverlay extends Overlay MenuEntry menuEntry = menuEntries[last]; String target = menuEntry.getTarget(); String option = menuEntry.getOption(); - MenuAction type = MenuAction.of(menuEntry.getType()); + MenuAction type = menuEntry.getType(); if (type == MenuAction.RUNELITE_OVERLAY || type == MenuAction.CC_OP_LOW_PRIORITY) { 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 c2fb671c10..ed736f728a 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 @@ -31,7 +31,6 @@ import com.google.inject.Provides; import java.awt.Color; import java.time.Instant; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +56,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; @@ -271,7 +269,6 @@ public class NpcIndicatorsPlugin extends Plugin final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); menuEntry.setTarget(target); - client.setMenuEntries(menuEntries); } } else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) @@ -291,48 +288,29 @@ public class NpcIndicatorsPlugin extends Plugin .filter(highlight -> !highlight.equalsIgnoreCase(npcName)) .anyMatch(highlight -> WildcardMatcher.matches(highlight, npcName)); - MenuEntry[] menuEntries = client.getMenuEntries(); - // Only add Untag-All option to npcs not highlighted by a wildcard entry, because untag-all will not remove wildcards if (!matchesList) { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); - final MenuEntry tagAllEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); - tagAllEntry.setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL); - tagAllEntry.setTarget(event.getTarget()); - tagAllEntry.setParam0(event.getActionParam0()); - tagAllEntry.setParam1(event.getActionParam1()); - tagAllEntry.setIdentifier(event.getIdentifier()); - tagAllEntry.setType(MenuAction.RUNELITE.getId()); - } - else - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + client.createMenuEntry(-1) + .setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } - final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - tagEntry.setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG); - tagEntry.setTarget(event.getTarget()); - tagEntry.setParam0(event.getActionParam0()); - tagEntry.setParam1(event.getActionParam1()); - tagEntry.setIdentifier(event.getIdentifier()); - tagEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked click) + private void tag(MenuEntry entry) { - if (click.getMenuAction() != MenuAction.RUNELITE || - !(click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG) || - click.getMenuOption().equals(TAG_ALL) || click.getMenuOption().equals(UNTAG_ALL))) - { - return; - } - - final int id = click.getId(); + final int id = entry.getIdentifier(); final NPC[] cachedNPCs = client.getCachedNPCs(); final NPC npc = cachedNPCs[id]; @@ -341,7 +319,7 @@ public class NpcIndicatorsPlugin extends Plugin return; } - if (click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG)) + if (entry.getOption().equals(TAG) || entry.getOption().equals(UNTAG)) { final boolean removed = npcTags.remove(id); @@ -371,8 +349,6 @@ public class NpcIndicatorsPlugin extends Plugin // this trips a config change which triggers the overlay rebuild updateNpcsToHighlight(name); } - - click.consume(); } @Subscribe 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 826eb725da..526ffe7f91 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 @@ -31,7 +31,6 @@ import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -65,7 +64,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -230,35 +228,26 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK); - menuEntry.setTarget(event.getTarget()); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(event.getActionParam1()); - menuEntry.setIdentifier(event.getIdentifier()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::markObject); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void markObject(MenuEntry entry) { - if (event.getMenuAction() != MenuAction.RUNELITE - || !(event.getMenuOption().equals(MARK) || event.getMenuOption().equals(UNMARK))) - { - return; - } - Scene scene = client.getScene(); Tile[][][] tiles = scene.getTiles(); - final int x = event.getParam0(); - final int y = event.getParam1(); + final int x = entry.getParam0(); + final int y = entry.getParam1(); final int z = client.getPlane(); final Tile tile = tiles[z][x][y]; - TileObject object = findTileObject(tile, event.getId()); + TileObject object = findTileObject(tile, entry.getIdentifier()); if (object == null) { return; 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 4d58b924d1..330f4dfb42 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 @@ -184,7 +184,6 @@ public class OpponentInfoPlugin extends Plugin { MenuEntry[] menuEntries = client.getMenuEntries(); menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget()); - client.setMenuEntries(menuEntries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index df72925bb8..eaa841a620 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -31,8 +31,8 @@ import lombok.Value; import net.runelite.api.Client; import net.runelite.api.FriendsChatRank; import static net.runelite.api.FriendsChatRank.UNRANKED; +import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; @@ -118,29 +118,23 @@ public class PlayerIndicatorsPlugin extends Plugin } MenuEntry[] menuEntries = client.getMenuEntries(); - boolean modified = false; for (MenuEntry entry : menuEntries) { - int type = entry.getType(); + MenuAction type = entry.getType(); - if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) - { - type -= MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - if (type == WALK.getId() - || type == SPELL_CAST_ON_PLAYER.getId() - || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId() - || type == RUNELITE_PLAYER.getId()) + if (type == WALK + || type == SPELL_CAST_ON_PLAYER + || type == ITEM_USE_ON_PLAYER + || type == PLAYER_FIRST_OPTION + || type == PLAYER_SECOND_OPTION + || type == PLAYER_THIRD_OPTION + || type == PLAYER_FOURTH_OPTION + || type == PLAYER_FIFTH_OPTION + || type == PLAYER_SIXTH_OPTION + || type == PLAYER_SEVENTH_OPTION + || type == PLAYER_EIGTH_OPTION + || type == RUNELITE_PLAYER) { Player[] players = client.getCachedPlayers(); Player player = null; @@ -149,7 +143,7 @@ public class PlayerIndicatorsPlugin extends Plugin // 'Walk here' identifiers are offset by 1 because the default // identifier for this option is 0, which is also a player index. - if (type == WALK.getId()) + if (type == WALK) { identifier--; } @@ -175,14 +169,8 @@ public class PlayerIndicatorsPlugin extends Plugin String newTarget = decorateTarget(oldTarget, decorations); entry.setTarget(newTarget); - modified = true; } } - - if (modified) - { - client.setMenuEntries(menuEntries); - } } private Decorations getDecorations(Player player) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index 241ebc9809..9ac225d4ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -70,7 +70,7 @@ import okhttp3.HttpUrl; ) public class WikiPlugin extends Plugin { - static final HttpUrl WIKI_BASE = HttpUrl.parse("https://oldschool.runescape.wiki"); + static final HttpUrl WIKI_BASE = HttpUrl.get("https://oldschool.runescape.wiki"); static final HttpUrl WIKI_API = WIKI_BASE.newBuilder().addPathSegments("api.php").build(); static final String UTM_SORUCE_KEY = "utm_source"; static final String UTM_SORUCE_VALUE = "runelite"; @@ -335,20 +335,6 @@ public class WikiPlugin extends Plugin LinkBrowser.browse(url.toString()); return; } - - if (ev.getMenuAction() == MenuAction.RUNELITE) - { - switch (ev.getMenuOption()) - { - case MENUOP_WIKI: - LinkBrowser.browse(WIKI_BASE.newBuilder() - .addPathSegment("w") - .addPathSegment(Text.removeTags(ev.getMenuTarget())) - .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString()); - - } - } } private void openSearchInput() @@ -372,17 +358,17 @@ public class WikiPlugin extends Plugin { int widgetIndex = event.getActionParam0(); int widgetID = event.getActionParam1(); - MenuEntry[] menuEntries = client.getMenuEntries(); if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) { + MenuEntry[] menuEntries = client.getMenuEntries(); Widget w = getWidget(widgetID, widgetIndex); if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1) { for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--) { MenuEntry entry = menuEntries[ourEntry]; - if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET) { int id = itemManager.canonicalize(w.getItemId()); String name = itemManager.getItemComposition(id).getName(); @@ -390,7 +376,6 @@ public class WikiPlugin extends Plugin break; } } - client.setMenuEntries(menuEntries); } else { @@ -400,7 +385,7 @@ public class WikiPlugin extends Plugin MenuEntry[] oldEntries = menuEntries; menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1); for (int ourEntry = oldEntries.length - 1; - ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId(); + ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET; ourEntry--) { menuEntries[ourEntry - 1] = oldEntries[ourEntry]; @@ -425,16 +410,15 @@ public class WikiPlugin extends Plugin return; } - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(action.replace("View ", "").replace(" guide", "")); - menuEntry.setOption(MENUOP_WIKI); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setTarget(action.replace("View ", "").replace(" guide", "")) + .setOption(MENUOP_WIKI) + .setType(MenuAction.RUNELITE) + .onClick(ev -> LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(Text.removeTags(ev.getTarget())) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .build().toString())); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index ef3bcaf423..109095545b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -28,7 +28,6 @@ package net.runelite.client.plugins.worldhopper; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.Instant; @@ -54,7 +53,6 @@ import net.runelite.api.FriendsChatManager; import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NameableContainer; import net.runelite.api.Varbits; import net.runelite.api.clan.ClanChannel; @@ -63,7 +61,6 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; @@ -92,7 +89,6 @@ import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "World Hopper", @@ -397,43 +393,19 @@ public class WorldHopperPlugin extends Plugin return; } - final MenuEntry hopTo = new MenuEntry(); - hopTo.setOption(HOP_TO); - hopTo.setTarget(event.getTarget()); - hopTo.setType(MenuAction.RUNELITE.getId()); - hopTo.setParam0(event.getActionParam0()); - hopTo.setParam1(event.getActionParam1()); + client.createMenuEntry(after ? -2 : -1) + .setOption(HOP_TO) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + ChatPlayer p = getChatPlayerFromName(e.getTarget()); - insertMenuEntry(hopTo, client.getMenuEntries(), after); - } - } - - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries, boolean after) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - - if (after) - { - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - } - - client.setMenuEntries(newMenu); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) - { - return; - } - - ChatPlayer player = getChatPlayerFromName(event.getMenuTarget()); - - if (player != null) - { - hop(player.getWorld()); + if (p != null) + { + hop(p.getWorld()); + } + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 7433a81323..5407226a99 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -32,7 +32,6 @@ import com.google.inject.Binder; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.temporal.ChronoUnit; -import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -45,7 +44,6 @@ import net.runelite.api.Client; import net.runelite.api.Experience; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Skill; @@ -54,7 +52,6 @@ import net.runelite.api.WorldType; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.StatChanged; import net.runelite.api.widgets.WidgetID; @@ -521,48 +518,21 @@ public class XpTrackerPlugin extends Plugin final String skillText = event.getOption().split(" ")[1]; final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase()); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(skillText); - menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() - || TO_GROUP(event.getParam1()) != WidgetID.SKILLS_GROUP_ID) - { - return; - } - - final Skill skill; - try - { - skill = Skill.valueOf(Text.removeTags(event.getMenuTarget()).toUpperCase()); - } - catch (IllegalArgumentException ex) - { - log.debug(null, ex); - return; - } - - switch (event.getMenuOption()) - { - case MENUOP_ADD_CANVAS_TRACKER: - addOverlay(skill); - break; - case MENUOP_REMOVE_CANVAS_TRACKER: - removeOverlay(skill); - break; - } + client.createMenuEntry(-1) + .setTarget(skillText) + .setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (hasOverlay(skill)) + { + removeOverlay(skill); + } + else + { + addOverlay(skill); + } + }); } XpStateSingle getSkillState(Skill skill) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index bea3f9d280..31d428ceed 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -40,17 +40,13 @@ import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; -import net.runelite.api.MenuAction; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; /** @@ -108,14 +104,12 @@ public class OverlayManager private ArrayListMultimap overlayMap = ArrayListMultimap.create(); private final ConfigManager configManager; - private final EventBus eventBus; private final RuneLiteConfig runeLiteConfig; @Inject - private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig) + private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig) { this.configManager = configManager; - this.eventBus = eventBus; this.runeLiteConfig = runeLiteConfig; } @@ -137,32 +131,6 @@ public class OverlayManager rebuildOverlayLayers(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - MenuAction menuAction = event.getMenuAction(); - if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG) - { - return; - } - - event.consume(); - - Overlay overlay = overlays.get(event.getId()); - if (overlay != null) - { - List menuEntries = overlay.getMenuEntries(); - OverlayMenuEntry overlayMenuEntry = menuEntries.stream() - .filter(me -> me.getOption().equals(event.getMenuOption())) - .findAny() - .orElse(null); - if (overlayMenuEntry != null) - { - eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay)); - } - } - } - /** * Gets all of the overlays on a layer sorted by priority and position * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index 99b75c0255..d673faba77 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -49,7 +49,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; -import net.runelite.api.MenuEntry; import net.runelite.api.Varbits; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ClientTick; @@ -60,6 +59,7 @@ import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; @@ -86,10 +86,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200); private static final Color MOVING_OVERLAY_TARGET_COLOR = Color.RED; private static final Color MOVING_OVERLAY_RESIZING_COLOR = new Color(255, 0, 255, 200); + private final Client client; private final OverlayManager overlayManager; private final RuneLiteConfig runeLiteConfig; private final ClientUI clientUI; + private final EventBus eventBus; // Overlay movement variables private final Point overlayOffset = new Point(); @@ -101,7 +103,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private boolean inOverlayResizingMode; private boolean inOverlayDraggingMode; private boolean startedMovingOverlay; - private MenuEntry[] menuEntries; + private Overlay hoveredOverlay; // for building menu entries // Overlay state validation private Rectangle viewportBounds; @@ -124,6 +126,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.overlayManager = overlayManager; this.runeLiteConfig = runeLiteConfig; this.clientUI = clientUI; + this.eventBus = eventBus; keyManager.registerKeyListener(this); mouseManager.registerMouseListener(this); eventBus.register(this); @@ -140,14 +143,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener resetOverlayManagementMode(); } - menuEntries = null; + hoveredOverlay = null; } } @Subscribe protected void onClientTick(ClientTick t) { - if (menuEntries == null) + final Overlay overlay = hoveredOverlay; + if (overlay == null || client.isMenuOpen()) { return; } @@ -158,24 +162,29 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener return; } - if (client.isMenuOpen()) + List menuEntries = overlay.getMenuEntries(); + if (menuEntries.isEmpty()) { return; } - MenuEntry[] clientMenuEntries = client.getMenuEntries(); - MenuEntry[] newEntries = new MenuEntry[clientMenuEntries.length + menuEntries.length]; + // Add in reverse order so they display correctly in the right-click menu + for (int i = menuEntries.size() - 1; i >= 0; --i) + { + OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - newEntries[0] = clientMenuEntries[0]; // Keep cancel at 0 - System.arraycopy(menuEntries, 0, newEntries, 1, menuEntries.length); // Add overlay menu entries - System.arraycopy(clientMenuEntries, 1, newEntries, menuEntries.length + 1, clientMenuEntries.length - 1); // Add remaining menu entries - client.setMenuEntries(newEntries); + client.createMenuEntry(-1) + .setOption(overlayMenuEntry.getOption()) + .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) + .setType(overlayMenuEntry.getMenuAction()) + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); + } } @Subscribe public void onBeforeRender(BeforeRender event) { - menuEntries = null; + hoveredOverlay = null; if (client.getGameState() == GameState.LOGGED_IN) { @@ -349,11 +358,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) { - if (menuEntries == null) - { - menuEntries = createRightClickMenuEntries(overlay); - } - + hoveredOverlay = overlay; overlay.onMouseOver(); } } @@ -902,33 +907,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); } - private MenuEntry[] createRightClickMenuEntries(Overlay overlay) - { - List menuEntries = overlay.getMenuEntries(); - if (menuEntries.isEmpty()) - { - return null; - } - - final MenuEntry[] entries = new MenuEntry[menuEntries.size()]; - - // Add in reverse order so they display correctly in the right-click menu - for (int i = menuEntries.size() - 1; i >= 0; --i) - { - OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - - final MenuEntry entry = new MenuEntry(); - entry.setOption(overlayMenuEntry.getOption()); - entry.setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)); - entry.setType(overlayMenuEntry.getMenuAction().getId()); - entry.setIdentifier(overlayManager.getOverlays().indexOf(overlay)); // overlay id - - entries[i] = entry; - } - - return entries; - } - /** * Adjust the given overlay position to be within its parent's bounds. * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 2f2beb0c62..16ca444f8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -24,6 +24,7 @@ */ package net.runelite.client.ui.overlay.worldmap; +import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import java.awt.Dimension; @@ -32,23 +33,18 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Point; import net.runelite.api.RenderOverview; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.overlay.Overlay; @@ -73,7 +69,7 @@ public class WorldMapOverlay extends Overlay private final WorldMapPointManager worldMapPointManager; private final Client client; - private final List mapMenuEntries = new ArrayList<>(); + private WorldMapPoint hoveredPoint; @Inject private WorldMapOverlay( @@ -107,19 +103,18 @@ public class WorldMapOverlay extends Overlay bottomBar.setOnTimerListener((JavaScriptCallback) ev -> { - if (client.isMenuOpen() || mapMenuEntries.isEmpty()) + WorldMapPoint worldPoint = hoveredPoint; + if (client.isMenuOpen() || worldPoint == null) { return; } - MenuEntry[] entries = client.getMenuEntries(); - int end = entries.length; - entries = Arrays.copyOf(entries, end + mapMenuEntries.size()); - for (int i = 0; i < mapMenuEntries.size(); i++) - { - entries[end + i] = mapMenuEntries.get(i); - } - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)) + .setOption(FOCUS_ON) + .setType(MenuAction.RUNELITE) + .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))); }); bottomBar.setHasListener(true); @@ -135,7 +130,7 @@ public class WorldMapOverlay extends Overlay mousePos = null; } - mapMenuEntries.clear(); + hoveredPoint = null; WorldMapPoint tooltipPoint = null; @@ -227,19 +222,7 @@ public class WorldMapOverlay extends Overlay if (worldPoint.isJumpOnClick()) { assert worldPoint.getName() != null; - - WorldPoint target = worldPoint.getTarget(); - if (target == null) - { - target = worldPoint.getWorldPoint(); - } - - MenuEntry entry = new MenuEntry(); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setOption(FOCUS_ON); - entry.setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)); - entry.setIdentifier(target.getPlane() << 28 | target.getX() << 14 | target.getY()); - mapMenuEntries.add(entry); + hoveredPoint = worldPoint; } } } @@ -259,21 +242,6 @@ public class WorldMapOverlay extends Overlay return null; } - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) - { - if (ev.getMenuAction() == MenuAction.RUNELITE && FOCUS_ON.equals(ev.getMenuOption())) - { - int pxy = ev.getId(); - WorldPoint wp = new WorldPoint( - pxy >> 14 & 0x3fff, - pxy & 0x3fff, - pxy >> 28); - - client.getRenderOverview().setWorldMapPositionTarget(wp); - } - } - /** * Get the screen coordinates for a WorldPoint on the world map * diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java index 30ca3dfeda..cd33ded89b 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -24,9 +24,12 @@ */ package net.runelite.client.menus; +import com.google.common.collect.Lists; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; @@ -38,24 +41,18 @@ import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.util.Text; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; +import static org.mockito.ArgumentMatchers.anyInt; import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) public class MenuManagerTest { - private static final MenuEntry CANCEL = new MenuEntry(); - @Inject private MenuManager menuManager; @@ -63,14 +60,18 @@ public class MenuManagerTest @Bind private Client client; - private MenuEntry[] clientMenuEntries = {CANCEL}; + private final MenuEntry CANCEL = createMenuEntry("Cancel", "", MenuAction.CANCEL, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - @BeforeClass - public static void beforeClass() + private final List createdMenuEntries = new ArrayList<>(); + + private static MenuEntry createMenuEntry(String option, String target, MenuAction type, int param1) { - CANCEL.setOption("Cancel"); - CANCEL.setType(MenuAction.CANCEL.getId()); - CANCEL.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(type); + menuEntry.setParam1(param1); + return menuEntry; } @Before @@ -78,35 +79,25 @@ public class MenuManagerTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - doAnswer((Answer) invocationOnMock -> - { - clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); - return null; - }).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); - when(client.getMenuEntries()).thenAnswer((Answer) invocationMock -> clientMenuEntries); + when(client.createMenuEntry(anyInt())) + .thenAnswer(a -> + { + MenuEntry e = new TestMenuEntry(); + createdMenuEntries.add(e); + return e; + }); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{CANCEL}); } @Test public void testManagedMenuOrder() { - final MenuEntry first = new MenuEntry(); - final MenuEntry second = new MenuEntry(); - final MenuEntry third = new MenuEntry(); - first.setOption("Test"); - first.setTarget("First Entry"); - first.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - first.setType(RUNELITE.getId()); - second.setOption("Test"); - second.setTarget("Second Entry"); - second.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - second.setType(RUNELITE.getId()); - third.setOption("Test"); - third.setTarget("Third Entry"); - third.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - third.setType(RUNELITE.getId()); - menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); + final MenuEntry first = createMenuEntry("Test", "First Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry second = createMenuEntry("Test", "Second Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry third = createMenuEntry("Test", "Third Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); menuManager.onMenuEntryAdded(new MenuEntryAdded( CANCEL.getOption(), @@ -116,12 +107,10 @@ public class MenuManagerTest CANCEL.getParam0(), CANCEL.getParam1())); - ArgumentCaptor captor = ArgumentCaptor.forClass(MenuEntry[].class); - verify(client, atLeastOnce()).setMenuEntries(captor.capture()); + verify(client, times(3)).createMenuEntry(anyInt()); - final MenuEntry[] resultMenuEntries = captor.getValue(); // Strip color tags from menu options before array comparison - for (MenuEntry resultEntry : resultMenuEntries) + for (MenuEntry resultEntry : createdMenuEntries) { final String resultTarget = resultEntry.getTarget(); if (resultTarget != null) @@ -130,6 +119,7 @@ public class MenuManagerTest } } - assertArrayEquals(new MenuEntry[]{CANCEL, third, second, first}, resultMenuEntries); + assertArrayEquals(new MenuEntry[]{third, second, first}, + Lists.reverse(createdMenuEntries).toArray(new MenuEntry[0])); } } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java new file mode 100644 index 0000000000..35ca935676 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021, Adam + * 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.menus; + +import java.util.function.Consumer; +import lombok.EqualsAndHashCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +@EqualsAndHashCode +public class TestMenuEntry implements MenuEntry +{ + private String option; + private String target; + private int identifier; + private int type; + private int param0; + private int param1; + private boolean forceLeftClick; + + @Override + public String getOption() + { + return option; + } + + @Override + public MenuEntry setOption(String option) + { + this.option = option; + return this; + } + + @Override + public String getTarget() + { + return target; + } + + @Override + public MenuEntry setTarget(String target) + { + this.target = target; + return this; + } + + @Override + public int getIdentifier() + { + return this.identifier; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + this.identifier = identifier; + return this; + } + + @Override + public MenuAction getType() + { + return MenuAction.of(this.type); + } + + @Override + public MenuEntry setType(MenuAction type) + { + this.type = type.getId(); + return this; + } + + @Override + public int getParam0() + { + return this.param0; + } + + @Override + public MenuEntry setParam0(int param0) + { + this.param0 = param0; + return this; + } + + @Override + public int getParam1() + { + return this.param1; + } + + @Override + public MenuEntry setParam1(int param1) + { + this.param1 = param1; + return this; + } + + @Override + public boolean isForceLeftClick() + { + return this.forceLeftClick; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + this.forceLeftClick = forceLeftClick; + return this; + } + + @Override + public boolean isDeprioritized() + { + return type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + + @Override + public void setDeprioritized(boolean deprioritized) + { + if (deprioritized) + { + if (type < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + else + { + if (type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + } + + @Override + public MenuEntry onClick(Consumer callback) + { + return this; + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java index cbe6cd34d6..4fa03023a1 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java @@ -28,6 +28,7 @@ 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 java.util.Arrays; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; @@ -37,6 +38,7 @@ import net.runelite.api.events.ClientTick; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; +import net.runelite.client.menus.TestMenuEntry; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; import org.junit.Test; @@ -88,9 +90,7 @@ public class MenuEntrySwapperPluginTest { // The menu implementation returns a copy of the array, which causes swap() to not // modify the same array being iterated in onClientTick - MenuEntry[] copy = new MenuEntry[entries.length]; - System.arraycopy(entries, 0, copy, 0, entries.length); - return copy; + return Arrays.copyOf(entries, entries.length); }); doAnswer((Answer) invocationOnMock -> { @@ -109,10 +109,10 @@ public class MenuEntrySwapperPluginTest private static MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) { - MenuEntry menuEntry = new MenuEntry(); + MenuEntry menuEntry = new TestMenuEntry(); menuEntry.setOption(option); menuEntry.setTarget(target); - menuEntry.setType(menuAction.getId()); + menuEntry.setType(menuAction); menuEntry.setIdentifier(identifier); return menuEntry; } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 00d3bd2eaa..90d306a1cd 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -39,6 +39,7 @@ import net.runelite.api.NPC; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcSpawned; +import net.runelite.client.menus.TestMenuEntry; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -48,7 +49,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -109,13 +109,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // red - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // red } @Test @@ -133,13 +132,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // blue - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // blue } @Test From 3ad7fc1aad05a9e65b23df8a3a31bc23d1948db7 Mon Sep 17 00:00:00 2001 From: Freeburn113 Date: Fri, 10 Dec 2021 05:39:04 +0100 Subject: [PATCH 05/42] woodcutting: update respawn times from wiki --- .../client/plugins/woodcutting/Tree.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index f6cc53254f..f87bcaeef3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -53,26 +53,27 @@ import static net.runelite.api.ObjectID.WILLOW_10833; import static net.runelite.api.ObjectID.YEW; import static net.runelite.api.NullObjectID.NULL_10823; import static net.runelite.api.ObjectID.YEW_36683; +import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter enum Tree { REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), - OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), - WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), - MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) + OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820), + WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), + MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681) { @Override Duration getRespawnTime(int region) { - return region == MISCELLANIA_REGION ? Duration.ofMillis(8500) : super.respawnTime; + return region == MISCELLANIA_REGION ? Duration.of(14, GAME_TICKS) : super.respawnTime; } }, - TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686), - MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), - YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), - MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), - REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); + TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686), + MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688), + YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683), + MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835), + REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670); @Nullable private final Duration respawnTime; From a585253d3628172ebbcdbedc655b9dc716365043 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Dec 2021 11:57:50 -0500 Subject: [PATCH 06/42] chatfilter: add clan message types --- .../runelite/client/plugins/chatfilter/ChatFilterPlugin.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index 39d736d4c5..a529800017 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -201,6 +201,9 @@ public class ChatFilterPlugin extends Plugin case NPC_EXAMINE: case OBJECT_EXAMINE: case SPAM: + case CLAN_MESSAGE: + case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: if (config.filterGameChat()) { message = censorMessage(null, message); From 4fe37f978cd72a4b31e3efaee73bbdf0fcae3b20 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 9 Dec 2021 18:55:07 -0500 Subject: [PATCH 07/42] friendslist: add option to hide per-friend login notifications --- .../main/java/net/runelite/api/Client.java | 2 +- .../net/runelite/api/FriendContainer.java | 37 +++++++++ .../java/net/runelite/api/PendingLogin.java | 45 +++++++++++ .../plugins/friendlist/FriendListConfig.java | 4 +- .../plugins/friendlist/FriendListPlugin.java | 76 +++++++++++++++++++ .../friendlist/FriendListPluginTest.java | 14 +++- 6 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/FriendContainer.java create mode 100644 runelite-api/src/main/java/net/runelite/api/PendingLogin.java diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index e53d03ec7f..91cf6a842c 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1276,7 +1276,7 @@ public interface Client extends GameEngine * * @return */ - NameableContainer getFriendContainer(); + FriendContainer getFriendContainer(); /** * Retrieve the nameable container containing ignores diff --git a/runelite-api/src/main/java/net/runelite/api/FriendContainer.java b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java new file mode 100644 index 0000000000..b288db028b --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Adam + * 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.api; + +/** + * A nameable container of friends + */ +public interface FriendContainer extends NameableContainer +{ + /** + * Get the recent logins/logouts of friends from the last few seconds + * @return + */ + Deque getPendingLogins(); +} diff --git a/runelite-api/src/main/java/net/runelite/api/PendingLogin.java b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java new file mode 100644 index 0000000000..c7c3a1d1a3 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Adam + * 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.api; + +/** + * A pending friend login/out. This is used to suppress world hop notifications + * by buffering the pending logins to try to match a pending logout with a pending + * login and cancel both. + */ +public interface PendingLogin +{ + /** + * The name of the player + * @return + */ + String getName(); + + /** + * The world the player logged into, or 0 if a logout. + * @return + */ + short getWorld(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java index 441820c465..9c556c3dec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java @@ -28,9 +28,11 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("friendlist") +@ConfigGroup(FriendListConfig.GROUP) public interface FriendListConfig extends Config { + String GROUP = "friendlist"; + @ConfigItem( keyName = "showWorldOnLogin", name = "Show world on login", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index da5ebda38b..b3d85305ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -26,30 +26,40 @@ package net.runelite.client.plugins.friendlist; import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.Iterator; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; +import net.runelite.api.MenuAction; import net.runelite.api.MessageNode; import net.runelite.api.NameableContainer; +import net.runelite.api.PendingLogin; import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; import net.runelite.client.util.Text; @PluginDescriptor( name = "Friend List", description = "Add extra information to the friend and ignore lists" ) +@Slf4j public class FriendListPlugin extends Plugin { private static final int MAX_FRIENDS_P2P = 400; @@ -58,12 +68,21 @@ public class FriendListPlugin extends Plugin private static final int MAX_IGNORES_P2P = 400; private static final int MAX_IGNORES_F2P = 100; + private static final String HIDE_NOTIFICATIONS = "Hide notifications"; + private static final String SHOW_NOTIFICATIONS = "Show notifications"; + @Inject private Client client; @Inject private FriendListConfig config; + @Inject + private ConfigManager configManager; + + @Inject + private ChatMessageManager chatMessageManager; + @Provides FriendListConfig getConfig(ConfigManager configManager) { @@ -144,6 +163,46 @@ public class FriendListPlugin extends Plugin } } + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + + // Look for "Message" on friends list + if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) + { + String friend = Text.toJagexName(Text.removeTags(event.getTarget())); + + client.createMenuEntry(-1) + .setOption(isHideNotification(friend) ? SHOW_NOTIFICATIONS : HIDE_NOTIFICATIONS) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + boolean hidden = isHideNotification(friend); + setHideNotifications(friend, !hidden); + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) + .build()); + }); + } + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void setHideNotifications() + { + for (Iterator it = client.getFriendContainer().getPendingLogins().iterator(); it.hasNext(); ) + { + PendingLogin pendingLogin = it.next(); + if (isHideNotification(Text.toJagexName(pendingLogin.getName()))) + { + log.debug("Removing login notification for {}", pendingLogin.getName()); + it.remove(); + } + } + } + private void setFriendsListTitle(final String title) { Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); @@ -173,4 +232,21 @@ public class FriendListPlugin extends Plugin return null; } + + private void setHideNotifications(String friend, boolean hide) + { + if (hide) + { + configManager.setConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, true); + } + else + { + configManager.unsetConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend); + } + } + + private boolean isHideNotification(String friend) + { + return configManager.getConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, Boolean.class) == Boolean.TRUE; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java index 4b3fd12f32..ee8b485b6a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java @@ -31,9 +31,11 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.MessageNode; -import net.runelite.api.NameableContainer; import net.runelite.api.events.ChatMessage; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +56,14 @@ public class FriendListPluginTest @Bind private FriendListConfig config; + @Mock + @Bind + private ConfigManager configManager; + + @Mock + @Bind + private ChatMessageManager chatMessageManager; + @Inject private FriendListPlugin friendListPlugin; @@ -78,7 +88,7 @@ public class FriendListPluginTest Friend friend = mock(Friend.class); when(friend.getWorld()).thenReturn(311); - NameableContainer friendContainer = mock(NameableContainer.class); + FriendContainer friendContainer = mock(FriendContainer.class); when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); when(client.getFriendContainer()).thenReturn(friendContainer); From 1d5c63bfacba94e6cf690f77451237fae01563ce Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Dec 2021 15:10:23 -0500 Subject: [PATCH 08/42] rl-client: build test jar --- runelite-client/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 46bd34a2b2..9b282461bb 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -330,6 +330,13 @@ + + + + test-jar + + + org.apache.maven.plugins From a0c14cf06afcdd133599d5926ded9c791b541a53 Mon Sep 17 00:00:00 2001 From: Ron Young Date: Sat, 11 Dec 2021 16:25:54 -0600 Subject: [PATCH 09/42] api: MenuEntry::setDeprioritized return self --- runelite-api/src/main/java/net/runelite/api/MenuEntry.java | 2 +- .../test/java/net/runelite/client/menus/TestMenuEntry.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 6891927c4b..5cdcfe3559 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -84,7 +84,7 @@ public interface MenuEntry * @return */ boolean isDeprioritized(); - void setDeprioritized(boolean deprioritized); + MenuEntry setDeprioritized(boolean deprioritized); /** * Set a callback to be called when this menu option is clicked diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java index 35ca935676..bdcf842040 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -138,7 +138,7 @@ public class TestMenuEntry implements MenuEntry } @Override - public void setDeprioritized(boolean deprioritized) + public MenuEntry setDeprioritized(boolean deprioritized) { if (deprioritized) { @@ -154,6 +154,8 @@ public class TestMenuEntry implements MenuEntry type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; } } + + return this; } @Override From e956ed1ba7bb5ea8eeda7a8c21e7b782fc6d6b27 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Dec 2021 21:12:51 -0500 Subject: [PATCH 10/42] ge plugin: compact buy offer examine text The examine text, buy limit, trade price, and fee info does not fit on the interface anymore since the addition of the fee info. This compacts the examine text as well as places the limit / trade price on the same line in order to prevent pushing the fee off of the bottom of the border. --- .../grandexchange/GrandExchangePlugin.java | 133 +++++++------- .../src/main/scripts/GeExamineInfoText.hash | 1 + .../src/main/scripts/GeExamineInfoText.rs2asm | 167 ++++++++++++++++++ 3 files changed, 233 insertions(+), 68 deletions(-) create mode 100644 runelite-client/src/main/scripts/GeExamineInfoText.hash create mode 100644 runelite-client/src/main/scripts/GeExamineInfoText.rs2asm 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 697bf0d43b..f5458b9562 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 @@ -66,6 +66,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.ScriptID; import net.runelite.api.VarClientStr; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; @@ -74,7 +75,6 @@ import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; -import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; @@ -120,10 +120,9 @@ public class GrandExchangePlugin extends Plugin @VisibleForTesting static final int GE_SLOTS = 8; 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 int GE_MAX_EXAMINE_LEN = 100; - private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; + private static final String BUY_LIMIT_GE_TEXT = "Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); @@ -182,9 +181,6 @@ public class GrandExchangePlugin extends Plugin @Inject private RuneLiteConfig runeLiteConfig; - private Widget grandExchangeText; - private String grandExchangeExamine; - @Inject private GrandExchangeClient grandExchangeClient; private int lastLoginTick; @@ -317,7 +313,6 @@ public class GrandExchangePlugin extends Plugin clientToolbar.removeNavigation(button); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); - grandExchangeText = null; lastUsername = machineUuid = null; tradeSeq = 0; } @@ -587,31 +582,10 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - switch (event.getGroupId()) - { - // Grand exchange was opened. - case WidgetID.GRAND_EXCHANGE_GROUP_ID: - grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT); - break; - // Grand exchange was closed (if it was open before). - case WidgetID.INVENTORY_GROUP_ID: - grandExchangeText = null; - break; - } - } - @Subscribe public void onScriptPostFired(ScriptPostFired event) { - // GE offers setup init - if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD) - { - rebuildGeText(); - } - else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) + if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) { highlightSearchMatches(); } @@ -738,7 +712,30 @@ public class GrandExchangePlugin extends Plugin @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { - if (!event.getEventName().equals("setGETitle") || !config.showTotal()) + switch (event.getEventName()) + { + case "setGETitle": + setGeTitle(); + break; + case "geExamineText": + { + String[] stack = client.getStringStack(); + int sz = client.getStringStackSize(); + String fee = stack[sz - 2]; + String examine = stack[sz - 3]; + String text = setExamineText(examine, fee); + if (text != null) + { + stack[sz - 1] = text; + } + break; + } + } + } + + private void setGeTitle() + { + if (!config.showTotal()) { return; } @@ -817,39 +814,10 @@ public class GrandExchangePlugin extends Plugin } } - private void rebuildGeText() + private String setExamineText(String examine, String fee) { - if (grandExchangeText == null) - { - return; - } - Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER); - if (grandExchangeOffer == null) - { - return; - } - Widget grandExchangeItem = grandExchangeOffer.getChild(OFFER_CONTAINER_ITEM); - if (grandExchangeItem == null || grandExchangeItem.isHidden()) - { - return; - } - - final Widget geText = grandExchangeText; - final int itemId = grandExchangeItem.getItemId(); - - if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1) - { - // This item is invalid/nothing has been searched for - return; - } - - if (geText.getText() == grandExchangeExamine) - { - // if we've already set the text, don't set it again - return; - } - - String text = geText.getText(); + final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM); + StringBuilder sb = new StringBuilder(); if (config.enableGELimits()) { @@ -858,7 +826,7 @@ public class GrandExchangePlugin extends Plugin // If we have item buy limit, append it if (itemStats != null && itemStats.getGeLimit() > 0) { - text += BUY_LIMIT_GE_TEXT + QuantityFormatter.formatNumber(itemStats.getGeLimit()); + sb.append(BUY_LIMIT_GE_TEXT).append(QuantityFormatter.formatNumber(itemStats.getGeLimit())); } } @@ -868,7 +836,7 @@ public class GrandExchangePlugin extends Plugin if (resetTime != null) { Duration remaining = Duration.between(Instant.now(), resetTime); - text += " (" + DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm") + ")"; + sb.append(" (").append(DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm")).append(")"); } } @@ -877,12 +845,41 @@ public class GrandExchangePlugin extends Plugin final int price = itemManager.getItemPriceWithSource(itemId, true); if (price > 0) { - text += "
Actively traded price: " + QuantityFormatter.formatNumber(price); + if (sb.length() > 0) + { + sb.append(" / "); + } + sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price)); } } - grandExchangeExamine = text; - geText.setText(text); + if (sb.length() == 0) + { + return null; + } + + return shortenExamine(examine) + "
" + sb + "
" + fee; + } + + private static String shortenExamine(String examine) + { + int from = 0; + int idx; + while (true) + { + idx = examine.indexOf(' ', from); + if (idx == -1) + { + return examine; + } + if (idx > GE_MAX_EXAMINE_LEN && from > 0) + { + break; // use from + } + from = idx + 1; + } + + return examine.substring(0, from - 1) + "..."; } void openGeLink(String name, int itemId) diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.hash b/runelite-client/src/main/scripts/GeExamineInfoText.hash new file mode 100644 index 0000000000..162121bd78 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.hash @@ -0,0 +1 @@ +157D0FE4248A0C0CAC825733A8DE7B0FA5A93451A9FCE3A4B1D8BFD54038B970 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm new file mode 100644 index 0000000000..20c53ea902 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm @@ -0,0 +1,167 @@ +; script used to position the ge buy offer "Convenience fee" info icon as well as set the +; examine text +; component0 = text component for the examine text +; component1 = parent of the info icon +; string0 = item examine +; string1 = Convenience fee text +.id 5730 +.int_stack_count 2 +.string_stack_count 2 +.int_var_count 5 +.string_var_count 3 + sconst "" + sstore 2 + iconst 0 + istore 2 + iconst 0 + istore 3 + iconst 0 + istore 4 + sload 1 + string_length + iconst 0 + if_icmpgt LABEL13 + jump LABEL118 +LABEL13: + sload 0 + sconst "
" + sconst "
" + sload 1 + join_string 4 + iload 0 + if_getwidth + istore 2 + sstore 2 + + sload 0 ; examine + sload 1 ; Convenience fee + sload 2 ; "<$string0>

<$string1>" + sconst "geExamineText" + runelite_callback + sstore 2 ; final text + pop_string ; Convenience fee + pop_string ; examine + + iload 0 + if_getx + sload 1 + iload 2 + iconst 494 + parawidth + add + iconst 5 + add + iload 0 + if_gety + sload 2 + iload 2 + iconst 494 + paraheight + iconst 15 + multiply + add + iconst 2 + add + istore 4 + istore 3 + iload 3 + iload 1 + if_getwidth + iconst 15 + sub + iconst 2 + div + sub + iload 4 + iconst 11 + iload 1 + if_getheight + iconst 2 + div + add + sub + istore 4 + istore 3 + iload 3 + iload 4 + iconst 0 + iconst 0 + iload 1 + if_setposition + iconst 0 + iload 1 + if_sethide + iload 1 + cc_deleteall + iload 1 + iconst 5 + iconst 0 + cc_create + iconst 15 + iconst 15 + iconst 0 + iconst 0 + cc_setsize + iconst 0 + iconst 0 + iconst 1 + iconst 1 + cc_setposition + iconst 1094 + cc_setgraphic + iconst 50 + cc_settrans + iconst 244 + iconst -2147483645 + cc_getid + iconst 0 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouserepeat + iconst 244 + iconst -2147483645 + cc_getid + iconst 50 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 2 + sconst "ii" + iload 1 + if_setonop + iconst 1 + sconst "Info" + iload 1 + if_setop + jump LABEL139 +LABEL118: + sload 0 + sstore 2 + iconst 1 + iload 1 + if_sethide + iload 1 + cc_deleteall + iconst -1 + sconst "" + iload 1 + if_setonmouserepeat + iconst -1 + sconst "" + iload 1 + if_setonmouseleave + iconst -1 + sconst "" + iload 1 + if_setonop + iload 1 + if_clearops +LABEL139: + sload 2 + iload 0 + if_settext + return From 24d0127e3d6f1211c2ef4058a1f08b5679a44b19 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 10 Dec 2021 19:45:25 -0700 Subject: [PATCH 11/42] rl-api: use less confusing names for model indices --- .../api/{Sequence.java => Animation.java} | 2 +- .../main/java/net/runelite/api/Client.java | 2 +- .../src/main/java/net/runelite/api/Model.java | 10 +++---- .../java/net/runelite/api/Perspective.java | 10 +++---- .../java/net/runelite/api/RuneLiteObject.java | 2 +- .../client/plugins/gpu/GpuPlugin.java | 4 +-- .../client/plugins/gpu/SceneUploader.java | 30 +++++++++---------- .../overlay/outline/ModelOutlineRenderer.java | 10 +++---- 8 files changed, 35 insertions(+), 35 deletions(-) rename runelite-api/src/main/java/net/runelite/api/{Sequence.java => Animation.java} (98%) diff --git a/runelite-api/src/main/java/net/runelite/api/Sequence.java b/runelite-api/src/main/java/net/runelite/api/Animation.java similarity index 98% rename from runelite-api/src/main/java/net/runelite/api/Sequence.java rename to runelite-api/src/main/java/net/runelite/api/Animation.java index e7e1c8fcb9..77c8a8af2e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Sequence.java +++ b/runelite-api/src/main/java/net/runelite/api/Animation.java @@ -27,6 +27,6 @@ package net.runelite.api; /** * Represents an animation of a renderable */ -public interface Sequence +public interface Animation { } diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 91cf6a842c..1699b5637d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1089,7 +1089,7 @@ public interface Client extends GameEngine * @param id the ID of the animation. Any int is allowed, but implementations in the client * should be defined in {@link AnimationID} */ - Sequence loadAnimation(int id); + Animation loadAnimation(int id); /** * Gets the music volume diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index e923cbd3d4..d3756ea727 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -37,13 +37,13 @@ public interface Model extends Renderable int[] getVerticesZ(); - int getTrianglesCount(); + int getFaceCount(); - int[] getTrianglesX(); + int[] getFaceIndices1(); - int[] getTrianglesY(); + int[] getFaceIndices2(); - int[] getTrianglesZ(); + int[] getFaceIndices3(); int[] getFaceColors1(); @@ -51,7 +51,7 @@ public interface Model extends Renderable int[] getFaceColors3(); - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); int getSceneId(); void setSceneId(int sceneId); diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index 75963a2486..e5f2262965 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -781,9 +781,9 @@ public class Perspective final int radius = 5; int[][] tris = new int[][]{ - m.getTrianglesX(), - m.getTrianglesY(), - m.getTrianglesZ() + m.getFaceIndices1(), + m.getFaceIndices2(), + m.getFaceIndices3() }; int vpX1 = client.getViewportXOffset(); @@ -791,10 +791,10 @@ public class Perspective int vpX2 = vpX1 + client.getViewportWidth(); int vpY2 = vpY1 + client.getViewportHeight(); - List rects = new ArrayList<>(m.getTrianglesCount()); + List rects = new ArrayList<>(m.getFaceCount()); nextTri: - for (int tri = 0; tri < m.getTrianglesCount(); tri++) + for (int tri = 0; tri < m.getFaceCount(); tri++) { if (faceColors3[tri] == -2) { diff --git a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java index 20f2fb001e..5fcd50c3e3 100644 --- a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java +++ b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java @@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject * Sets the animation of the RuneLiteObject * If animation is null model will be static */ - void setAnimation(Sequence animation); + void setAnimation(Animation animation); /** * Sets whether the animation of the RuneLiteObject should loop when the animation ends. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index b275fd7d4e..062c810ffa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -1608,7 +1608,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks modelY = y + client.getCameraY2(); modelZ = z + client.getCameraZ2(); modelOrientation = orientation; - int triangleCount = model.getTrianglesCount(); + int triangleCount = model.getFaceCount(); vertexBuffer.ensureCapacity(12 * triangleCount); uvBuffer.ensureCapacity(12 * triangleCount); @@ -1632,7 +1632,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks model.calculateExtreme(orientation); client.checkClickbox(model, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash); - int tc = Math.min(MAX_TRIANGLE, model.getTrianglesCount()); + int tc = Math.min(MAX_TRIANGLE, model.getFaceCount()); int uvOffset = model.getUvBufferOffset(); GpuIntBuffer b = bufferForTriangles(tc); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 910f8b3147..1bf9dcce63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -379,7 +379,7 @@ class SceneUploader public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) { - final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE); + final int triangleCount = Math.min(model.getFaceCount(), GpuPlugin.MAX_TRIANGLE); vertexBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12); @@ -388,15 +388,15 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); @@ -432,9 +432,9 @@ class SceneUploader int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1); vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2); @@ -458,21 +458,21 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java index e3528433cb..3047086dda 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java @@ -564,11 +564,11 @@ public class ModelOutlineRenderer */ private void simulateModelRasterizationForOutline(Model model) { - final int triangleCount = model.getTrianglesCount(); - final int[] indices1 = model.getTrianglesX(); - final int[] indices2 = model.getTrianglesY(); - final int[] indices3 = model.getTrianglesZ(); - final byte[] triangleTransparencies = model.getTriangleTransparencies(); + final int triangleCount = model.getFaceCount(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); + final byte[] triangleTransparencies = model.getFaceTransparencies(); for (int i = 0; i < triangleCount; i++) { From 02235d15846cb58a3a4cff347f14b4346904a2cd Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 8 Dec 2021 21:55:02 -0700 Subject: [PATCH 12/42] cache: add rev202 model formats --- .../cache/definitions/ModelDefinition.java | 179 +- .../definitions/loaders/ModelLoader.java | 1674 ++++++++++++----- .../cache/item/ItemSpriteFactory.java | 52 +- .../runelite/cache/models/ObjExporter.java | 16 +- 4 files changed, 1289 insertions(+), 632 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java index 2259026a4d..939fdf90da 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java @@ -12,45 +12,40 @@ public class ModelDefinition public int id; public int vertexCount = 0; - public int[] vertexPositionsX; - public int[] vertexPositionsY; - public int[] vertexPositionsZ; + public int[] vertexX; + public int[] vertexY; + public int[] vertexZ; public transient VertexNormal[] vertexNormals; public int faceCount; - public int[] faceVertexIndices1; - public int[] faceVertexIndices2; - public int[] faceVertexIndices3; - public byte[] faceAlphas; + public int[] faceIndices1; + public int[] faceIndices2; + public int[] faceIndices3; + public byte[] faceTransparencies; public short[] faceColors; public byte[] faceRenderPriorities; public byte[] faceRenderTypes; public transient FaceNormal[] faceNormals; - public int textureTriangleCount; - public short[] textureTriangleVertexIndices1; - public short[] textureTriangleVertexIndices2; - public short[] textureTriangleVertexIndices3; + public int numTextureFaces; + public short[] texIndices1; + public short[] texIndices2; + public short[] texIndices3; public transient float[][] faceTextureUCoordinates; public transient float[][] faceTextureVCoordinates; public short[] texturePrimaryColors; public short[] faceTextures; - public byte[] textureCoordinates; + public byte[] textureCoords; public byte[] textureRenderTypes; - public int[] vertexSkins; - public int[] faceSkins; + public int[] packedVertexGroups; + public int[] packedTransparencyVertexGroups; public byte priority; - public short[] aShortArray2574; - public short[] aShortArray2575; - public short[] aShortArray2577; - public short[] aShortArray2578; - public byte[] aByteArray2580; - public short[] aShortArray2586; - private transient int[][] vertexGroups; + public int[][] animayaGroups; + public int[][] animayaScales; private transient int[] origVX; private transient int[] origVY; @@ -77,17 +72,17 @@ public class ModelDefinition for (var1 = 0; var1 < this.faceCount; ++var1) { - int vertexA = this.faceVertexIndices1[var1]; - int vertexB = this.faceVertexIndices2[var1]; - int vertexC = this.faceVertexIndices3[var1]; + int vertexA = this.faceIndices1[var1]; + int vertexB = this.faceIndices2[var1]; + int vertexC = this.faceIndices3[var1]; - int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA]; - int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA]; - int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA]; + int xA = this.vertexX[vertexB] - this.vertexX[vertexA]; + int yA = this.vertexY[vertexB] - this.vertexY[vertexA]; + int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA]; - int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA]; - int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA]; - int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA]; + int xB = this.vertexX[vertexC] - this.vertexX[vertexA]; + int yB = this.vertexY[vertexC] - this.vertexY[vertexA]; + int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA]; // Compute cross product int var11 = yA * zB - yB * zA; @@ -168,13 +163,13 @@ public class ModelDefinition for (int i = 0; i < faceCount; i++) { int textureCoordinate; - if (textureCoordinates == null) + if (textureCoords == null) { textureCoordinate = -1; } else { - textureCoordinate = textureCoordinates[i]; + textureCoordinate = textureCoords[i]; } int textureIdx; @@ -215,33 +210,33 @@ public class ModelDefinition if (textureRenderType == 0) { - int faceVertexIdx1 = faceVertexIndices1[i]; - int faceVertexIdx2 = faceVertexIndices2[i]; - int faceVertexIdx3 = faceVertexIndices3[i]; + int faceVertexIdx1 = faceIndices1[i]; + int faceVertexIdx2 = faceIndices2[i]; + int faceVertexIdx3 = faceIndices3[i]; - short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate]; - short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate]; - short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate]; + short triangleVertexIdx1 = texIndices1[textureCoordinate]; + short triangleVertexIdx2 = texIndices2[textureCoordinate]; + short triangleVertexIdx3 = texIndices3[textureCoordinate]; - float triangleX = (float) vertexPositionsX[triangleVertexIdx1]; - float triangleY = (float) vertexPositionsY[triangleVertexIdx1]; - float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1]; + float triangleX = (float) vertexX[triangleVertexIdx1]; + float triangleY = (float) vertexY[triangleVertexIdx1]; + float triangleZ = (float) vertexZ[triangleVertexIdx1]; - float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX; - float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY; - float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ; - float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX; - float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY; - float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ; - float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX; - float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY; - float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ; - float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX; - float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY; - float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ; - float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX; - float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY; - float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ; + float f_882_ = (float) vertexX[triangleVertexIdx2] - triangleX; + float f_883_ = (float) vertexY[triangleVertexIdx2] - triangleY; + float f_884_ = (float) vertexZ[triangleVertexIdx2] - triangleZ; + float f_885_ = (float) vertexX[triangleVertexIdx3] - triangleX; + float f_886_ = (float) vertexY[triangleVertexIdx3] - triangleY; + float f_887_ = (float) vertexZ[triangleVertexIdx3] - triangleZ; + float f_888_ = (float) vertexX[faceVertexIdx1] - triangleX; + float f_889_ = (float) vertexY[faceVertexIdx1] - triangleY; + float f_890_ = (float) vertexZ[faceVertexIdx1] - triangleZ; + float f_891_ = (float) vertexX[faceVertexIdx2] - triangleX; + float f_892_ = (float) vertexY[faceVertexIdx2] - triangleY; + float f_893_ = (float) vertexZ[faceVertexIdx2] - triangleZ; + float f_894_ = (float) vertexX[faceVertexIdx3] - triangleX; + float f_895_ = (float) vertexY[faceVertexIdx3] - triangleY; + float f_896_ = (float) vertexZ[faceVertexIdx3] - triangleZ; float f_897_ = f_883_ * f_887_ - f_884_ * f_886_; float f_898_ = f_884_ * f_885_ - f_882_ * f_887_; @@ -274,7 +269,7 @@ public class ModelDefinition public void computeAnimationTables() { - if (this.vertexSkins != null) + if (this.packedVertexGroups != null) { int[] groupCounts = new int[256]; int numGroups = 0; @@ -282,7 +277,7 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; ++var3) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; ++groupCounts[var4]; if (var4 > numGroups) { @@ -300,10 +295,10 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; } - this.vertexSkins = null; + this.packedVertexGroups = null; } // triangleSkinValues is here @@ -314,13 +309,13 @@ public class ModelDefinition int sin = CircularAngle.SINE[orientation]; int cos = CircularAngle.COSINE[orientation]; - assert vertexPositionsX.length == vertexPositionsY.length; - assert vertexPositionsY.length == vertexPositionsZ.length; + assert vertexX.length == vertexY.length; + assert vertexY.length == vertexZ.length; - for (int i = 0; i < vertexPositionsX.length; ++i) + for (int i = 0; i < vertexX.length; ++i) { - vertexPositionsX[i] = vertexPositionsX[i] * cos + vertexPositionsZ[i] * sin >> 16; - vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16; + vertexX[i] = vertexX[i] * cos + vertexZ[i] * sin >> 16; + vertexZ[i] = vertexZ[i] * cos - vertexX[i] * sin >> 16; } reset(); @@ -333,23 +328,23 @@ public class ModelDefinition return; } - System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length); - System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length); - System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length); + System.arraycopy(origVX, 0, vertexX, 0, origVX.length); + System.arraycopy(origVY, 0, vertexY, 0, origVY.length); + System.arraycopy(origVZ, 0, vertexZ, 0, origVZ.length); } public void animate(int type, int[] frameMap, int dx, int dy, int dz) { if (origVX == null) { - origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length); - origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length); - origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length); + origVX = Arrays.copyOf(vertexX, vertexX.length); + origVY = Arrays.copyOf(vertexY, vertexY.length); + origVZ = Arrays.copyOf(vertexZ, vertexZ.length); } - final int[] verticesX = vertexPositionsX; - final int[] verticesY = vertexPositionsY; - final int[] verticesZ = vertexPositionsZ; + final int[] verticesX = vertexX; + final int[] verticesY = vertexY; + final int[] verticesZ = vertexZ; int var6 = frameMap.length; int var7; int var8; @@ -512,14 +507,14 @@ public class ModelDefinition int var1; for (var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } for (var1 = 0; var1 < this.faceCount; ++var1) { - int var2 = this.faceVertexIndices1[var1]; - this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1]; - this.faceVertexIndices3[var1] = var2; + int var2 = this.faceIndices1[var1]; + this.faceIndices1[var1] = this.faceIndices3[var1]; + this.faceIndices3[var1] = var2; } reset(); @@ -529,9 +524,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = -var2; + int var2 = this.vertexX[var1]; + this.vertexX[var1] = this.vertexZ[var1]; + this.vertexZ[var1] = -var2; } reset(); @@ -541,8 +536,8 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsX[var1] = -this.vertexPositionsX[var1]; - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexX[var1] = -this.vertexX[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } reset(); @@ -552,9 +547,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = -var2; + int var2 = this.vertexZ[var1]; + this.vertexZ[var1] = this.vertexX[var1]; + this.vertexX[var1] = -var2; } reset(); @@ -571,9 +566,9 @@ public class ModelDefinition { for (int var4 = 0; var4 < this.vertexCount; ++var4) { - this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128; - this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128; - this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128; + this.vertexX[var4] = this.vertexX[var4] * var1 / 128; + this.vertexY[var4] = var2 * this.vertexY[var4] / 128; + this.vertexZ[var4] = var3 * this.vertexZ[var4] / 128; } reset(); @@ -610,9 +605,9 @@ public class ModelDefinition { for (int i = 0; i < this.vertexCount; i++) { - this.vertexPositionsX[i] += xOffset; - this.vertexPositionsY[i] += yOffset; - this.vertexPositionsZ[i] += zOffset; + this.vertexX[i] += xOffset; + this.vertexY[i] += yOffset; + this.vertexZ[i] += zOffset; } this.reset(); } diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java index 4529f8a069..22226c3d8a 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java @@ -10,13 +10,21 @@ public class ModelLoader ModelDefinition def = new ModelDefinition(); def.id = modelId; - if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + if (b[b.length - 1] == -3 && b[b.length - 2] == -1) { - this.load1(def, b); + decodeType3(def, b); + } + else if (b[b.length - 1] == -2 && b[b.length - 2] == -1) + { + decodeType2(def, b); + } + else if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + { + decodeType1(def, b); } else { - this.load2(def, b); + decodeOldFormat(def, b); } def.computeNormals(); @@ -26,702 +34,1356 @@ public class ModelLoader return def; } - private void load1(ModelDefinition model, byte[] var1) + void decodeType3(ModelDefinition def, byte[] var1) { InputStream var2 = new InputStream(var1); - InputStream var24 = new InputStream(var1); InputStream var3 = new InputStream(var1); - InputStream var28 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); InputStream var6 = new InputStream(var1); - InputStream var55 = new InputStream(var1); - InputStream var51 = new InputStream(var1); - var2.setOffset(var1.length - 23); - int verticeCount = var2.readUnsignedShort(); - int triangleCount = var2.readUnsignedShort(); - int textureTriangleCount = var2.readUnsignedByte(); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 26); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); int var13 = var2.readUnsignedByte(); - int modelPriority = var2.readUnsignedByte(); - int var50 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); int var17 = var2.readUnsignedByte(); - int modelTexture = var2.readUnsignedByte(); - int modelVertexSkins = var2.readUnsignedByte(); + int var18 = var2.readUnsignedByte(); + int var19 = var2.readUnsignedShort(); int var20 = var2.readUnsignedShort(); int var21 = var2.readUnsignedShort(); - int var42 = var2.readUnsignedShort(); int var22 = var2.readUnsignedShort(); - int var38 = var2.readUnsignedShort(); - int textureAmount = 0; - int var7 = 0; - int var29 = 0; - int position; - if (textureTriangleCount > 0) + int var23 = var2.readUnsignedShort(); + int var24 = var2.readUnsignedShort(); + int var25 = 0; + int var26 = 0; + int var27 = 0; + int var28; + if (var11 > 0) { - model.textureRenderTypes = new byte[textureTriangleCount]; + def.textureRenderTypes = new byte[var11]; var2.setOffset(0); - for (position = 0; position < textureTriangleCount; ++position) + for (var28 = 0; var28 < var11; ++var28) { - byte renderType = model.textureRenderTypes[position] = var2.readByte(); - if (renderType == 0) + byte var29 = def.textureRenderTypes[var28] = var2.readByte(); + if (var29 == 0) { - ++textureAmount; + ++var25; } - if (renderType >= 1 && renderType <= 3) + if (var29 >= 1 && var29 <= 3) { - ++var7; + ++var26; } - if (renderType == 2) + if (var29 == 2) { - ++var29; + ++var27; } } } - position = textureTriangleCount + verticeCount; - int renderTypePos = position; - if (var13 == 1) + var28 = var11 + var9; + int var58 = var28; + if (var12 == 1) { - position += triangleCount; + var28 += var10; } - int var49 = position; - position += triangleCount; - int priorityPos = position; - if (modelPriority == 255) + int var30 = var28; + var28 += var10; + int var31 = var28; + if (var13 == 255) { - position += triangleCount; + var28 += var10; } - int triangleSkinPos = position; + int var32 = var28; + if (var15 == 1) + { + var28 += var10; + } + + int var33 = var28; + var28 += var24; + int var34 = var28; + if (var14 == 1) + { + var28 += var10; + } + + int var35 = var28; + var28 += var22; + int var36 = var28; + if (var16 == 1) + { + var28 += var10 * 2; + } + + int var37 = var28; + var28 += var23; + int var38 = var28; + var28 += var10 * 2; + int var39 = var28; + var28 += var19; + int var40 = var28; + var28 += var20; + int var41 = var28; + var28 += var21; + int var42 = var28; + var28 += var25 * 6; + int var43 = var28; + var28 += var26 * 6; + int var44 = var28; + var28 += var26 * 6; + int var45 = var28; + var28 += var26 * 2; + int var46 = var28; + var28 += var26; + int var47 = var28; + var28 = var28 + var26 * 2 + var27 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; if (var17 == 1) { - position += triangleCount; + def.packedVertexGroups = new int[var9]; } - int var35 = position; - if (modelVertexSkins == 1) + if (var12 == 1) { - position += verticeCount; + def.faceRenderTypes = new byte[var10]; } - int alphaPos = position; - if (var50 == 1) + if (var13 == 255) { - position += triangleCount; - } - - int var11 = position; - position += var22; - int texturePos = position; - if (modelTexture == 1) - { - position += triangleCount * 2; - } - - int textureCoordPos = position; - position += var38; - int colorPos = position; - position += triangleCount * 2; - int var40 = position; - position += var20; - int var41 = position; - position += var21; - int var8 = position; - position += var42; - int var43 = position; - position += textureAmount * 6; - int var37 = position; - position += var7 * 6; - int var48 = position; - position += var7 * 6; - int var56 = position; - position += var7 * 2; - int var45 = position; - position += var7; - int var46 = position; - position += var7 * 2 + var29 * 2; - model.vertexCount = verticeCount; - model.faceCount = triangleCount; - model.textureTriangleCount = textureTriangleCount; - model.vertexPositionsX = new int[verticeCount]; - model.vertexPositionsY = new int[verticeCount]; - model.vertexPositionsZ = new int[verticeCount]; - model.faceVertexIndices1 = new int[triangleCount]; - model.faceVertexIndices2 = new int[triangleCount]; - model.faceVertexIndices3 = new int[triangleCount]; - if (modelVertexSkins == 1) - { - model.vertexSkins = new int[verticeCount]; - } - - if (var13 == 1) - { - model.faceRenderTypes = new byte[triangleCount]; - } - - if (modelPriority == 255) - { - model.faceRenderPriorities = new byte[triangleCount]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) modelPriority; + def.priority = (byte) var13; } - if (var50 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[triangleCount]; + def.faceTransparencies = new byte[var10]; } - if (var17 == 1) + if (var15 == 1) { - model.faceSkins = new int[triangleCount]; + def.packedTransparencyVertexGroups = new int[var10]; } - if (modelTexture == 1) + if (var16 == 1) { - model.faceTextures = new short[triangleCount]; + def.faceTextures = new short[var10]; } - if (modelTexture == 1 && textureTriangleCount > 0) + if (var16 == 1 && var11 > 0) { - model.textureCoordinates = new byte[triangleCount]; + def.textureCoords = new byte[var10]; } - model.faceColors = new short[triangleCount]; - if (textureTriangleCount > 0) + if (var18 == 1) { - model.textureTriangleVertexIndices1 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices2 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices3 = new short[textureTriangleCount]; - if (var7 > 0) - { - model.aShortArray2574 = new short[var7]; - model.aShortArray2575 = new short[var7]; - model.aShortArray2586 = new short[var7]; - model.aShortArray2577 = new short[var7]; - model.aByteArray2580 = new byte[var7]; - model.aShortArray2578 = new short[var7]; - } - - if (var29 > 0) - { - model.texturePrimaryColors = new short[var29]; - } + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; } - var2.setOffset(textureTriangleCount); - var24.setOffset(var40); - var3.setOffset(var41); - var28.setOffset(var8); - var6.setOffset(var35); - int vX = 0; - int vY = 0; - int vZ = 0; - - int vertexZOffset; - int var10; - int vertexYOffset; - int var15; - int point; - for (point = 0; point < verticeCount; ++point) + def.faceColors = new short[var10]; + if (var11 > 0) { - int vertexFlags = var2.readUnsignedByte(); - int vertexXOffset = 0; - if ((vertexFlags & 1) != 0) - { - vertexXOffset = var24.readShortSmart(); - } - - vertexYOffset = 0; - if ((vertexFlags & 2) != 0) - { - vertexYOffset = var3.readShortSmart(); - } - - vertexZOffset = 0; - if ((vertexFlags & 4) != 0) - { - vertexZOffset = var28.readShortSmart(); - } - - model.vertexPositionsX[point] = vX + vertexXOffset; - model.vertexPositionsY[point] = vY + vertexYOffset; - model.vertexPositionsZ[point] = vZ + vertexZOffset; - vX = model.vertexPositionsX[point]; - vY = model.vertexPositionsY[point]; - vZ = model.vertexPositionsZ[point]; - if (modelVertexSkins == 1) - { - model.vertexSkins[point] = var6.readUnsignedByte(); - } - } - - var2.setOffset(colorPos); - var24.setOffset(renderTypePos); - var3.setOffset(priorityPos); - var28.setOffset(alphaPos); - var6.setOffset(triangleSkinPos); - var55.setOffset(texturePos); - var51.setOffset(textureCoordPos); - - for (point = 0; point < triangleCount; ++point) - { - model.faceColors[point] = (short) var2.readUnsignedShort(); - if (var13 == 1) - { - model.faceRenderTypes[point] = var24.readByte(); - } - - if (modelPriority == 255) - { - model.faceRenderPriorities[point] = var3.readByte(); - } - - if (var50 == 1) - { - model.faceAlphas[point] = var28.readByte(); - } - - if (var17 == 1) - { - model.faceSkins[point] = var6.readUnsignedByte(); - } - - if (modelTexture == 1) - { - model.faceTextures[point] = (short) (var55.readUnsignedShort() - 1); - } - - if (model.textureCoordinates != null && model.faceTextures[point] != -1) - { - model.textureCoordinates[point] = (byte) (var51.readUnsignedByte() - 1); - } + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } var2.setOffset(var11); - var24.setOffset(var49); - int trianglePointX = 0; - int trianglePointY = 0; - int trianglePointZ = 0; - vertexYOffset = 0; + var3.setOffset(var39); + var4.setOffset(var40); + var5.setOffset(var41); + var6.setOffset(var33); + int var48 = 0; + int var49 = 0; + int var50 = 0; - int var16; - for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset) + int var51; + int var52; + int var53; + int var54; + int var55; + for (var51 = 0; var51 < var9; ++var51) { - int numFaces = var24.readUnsignedByte(); - if (numFaces == 1) + var52 = var2.readUnsignedByte(); + var53 = 0; + if ((var52 & 1) != 0) { - trianglePointX = var2.readShortSmart() + vertexYOffset; - trianglePointY = var2.readShortSmart() + trianglePointX; - trianglePointZ = var2.readShortSmart() + trianglePointY; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var53 = var3.readShortSmart(); } - if (numFaces == 2) + var54 = 0; + if ((var52 & 2) != 0) { - trianglePointY = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var54 = var4.readShortSmart(); } - if (numFaces == 3) + var55 = 0; + if ((var52 & 4) != 0) { - trianglePointX = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var55 = var5.readShortSmart(); } - if (numFaces == 4) + def.vertexX[var51] = var48 + var53; + def.vertexY[var51] = var49 + var54; + def.vertexZ[var51] = var50 + var55; + var48 = def.vertexX[var51]; + var49 = def.vertexY[var51]; + var50 = def.vertexZ[var51]; + if (var17 == 1) { - int var57 = trianglePointX; - trianglePointX = trianglePointY; - trianglePointY = var57; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = var57; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + def.packedVertexGroups[var51] = var6.readUnsignedByte(); } } - var2.setOffset(var43); - var24.setOffset(var37); - var3.setOffset(var48); - var28.setOffset(var56); - var6.setOffset(var45); - var55.setOffset(var46); - - for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex) + if (var18 == 1) { - int type = model.textureRenderTypes[texIndex] & 255; - if (type == 0) + for (var51 = 0; var51 < var9; ++var51) { - model.textureTriangleVertexIndices1[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var2.readUnsignedShort(); - } + var52 = var6.readUnsignedByte(); + def.animayaGroups[var51] = new int[var52]; + def.animayaScales[var51] = new int[var52]; - if (type == 1) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 2) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - model.texturePrimaryColors[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 3) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); + for (var53 = 0; var53 < var52; ++var53) + { + def.animayaGroups[var51][var53] = var6.readUnsignedByte(); + def.animayaScales[var51][var53] = var6.readUnsignedByte(); + } } } - var2.setOffset(position); - vertexZOffset = var2.readUnsignedByte(); - if (vertexZOffset != 0) + var2.setOffset(var38); + var3.setOffset(var58); + var4.setOffset(var31); + var5.setOffset(var34); + var6.setOffset(var32); + var7.setOffset(var36); + var8.setOffset(var37); + + for (var51 = 0; var51 < var10; ++var51) + { + def.faceColors[var51] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var51] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var51] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var51] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var51] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var51] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var51] != -1) + { + def.textureCoords[var51] = (byte) (var8.readUnsignedByte() - 1); + } + } + + var2.setOffset(var35); + var3.setOffset(var30); + var51 = 0; + var52 = 0; + var53 = 0; + var54 = 0; + + int var56; + for (var55 = 0; var55 < var10; ++var55) + { + var56 = var3.readUnsignedByte(); + if (var56 == 1) + { + var51 = var2.readShortSmart() + var54; + var52 = var2.readShortSmart() + var51; + var53 = var2.readShortSmart() + var52; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 2) + { + var52 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 3) + { + var51 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 4) + { + int var57 = var51; + var51 = var52; + var52 = var57; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var57; + def.faceIndices3[var55] = var53; + } + } + + var2.setOffset(var42); + var3.setOffset(var43); + var4.setOffset(var44); + var5.setOffset(var45); + var6.setOffset(var46); + var7.setOffset(var47); + + for (var55 = 0; var55 < var11; ++var55) + { + var56 = def.textureRenderTypes[var55] & 255; + if (var56 == 0) + { + def.texIndices1[var55] = (short) var2.readUnsignedShort(); + def.texIndices2[var55] = (short) var2.readUnsignedShort(); + def.texIndices3[var55] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var28); + var55 = var2.readUnsignedByte(); + if (var55 != 0) { - //new Class41(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readInt(); } + } - private void load2(ModelDefinition model, byte[] var1) + void decodeType2(ModelDefinition def, byte[] var1) { boolean var2 = false; - boolean var43 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); InputStream var5 = new InputStream(var1); - InputStream var39 = new InputStream(var1); - InputStream var26 = new InputStream(var1); - InputStream var9 = new InputStream(var1); - InputStream var3 = new InputStream(var1); - var5.setOffset(var1.length - 18); - int var10 = var5.readUnsignedShort(); - int var11 = var5.readUnsignedShort(); - int var12 = var5.readUnsignedByte(); - int var13 = var5.readUnsignedByte(); - int var14 = var5.readUnsignedByte(); - int var30 = var5.readUnsignedByte(); - int var15 = var5.readUnsignedByte(); - int var28 = var5.readUnsignedByte(); - int var27 = var5.readUnsignedShort(); - int var20 = var5.readUnsignedShort(); - int var36 = var5.readUnsignedShort(); - int var23 = var5.readUnsignedShort(); - byte var16 = 0; - int var46 = var16 + var10; - int var24 = var46; - var46 += var11; - int var25 = var46; - if (var14 == 255) + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 23); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedByte(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + int var21 = var4.readUnsignedShort(); + int var22 = var4.readUnsignedShort(); + byte var23 = 0; + int var24 = var23 + var9; + int var25 = var24; + var24 += var10; + int var26 = var24; + if (var13 == 255) { - var46 += var11; + var24 += var10; } - int var4 = var46; + int var27 = var24; if (var15 == 1) { - var46 += var11; + var24 += var10; } - int var42 = var46; - if (var13 == 1) + int var28 = var24; + if (var12 == 1) { - var46 += var11; + var24 += var10; } - int var37 = var46; - if (var28 == 1) + int var29 = var24; + var24 += var22; + int var30 = var24; + if (var14 == 1) { - var46 += var10; + var24 += var10; } - int var29 = var46; - if (var30 == 1) + int var31 = var24; + var24 += var21; + int var32 = var24; + var24 += var10 * 2; + int var33 = var24; + var24 += var11 * 6; + int var34 = var24; + var24 += var18; + int var35 = var24; + var24 += var19; + int var10000 = var24 + var20; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) { - var46 += var11; + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } - int var44 = var46; - var46 += var23; - int var17 = var46; - var46 += var11 * 2; - int var32 = var46; - var46 += var12 * 6; - int var34 = var46; - var46 += var27; - int var35 = var46; - var46 += var20; - int var10000 = var46 + var36; - model.vertexCount = var10; - model.faceCount = var11; - model.textureTriangleCount = var12; - model.vertexPositionsX = new int[var10]; - model.vertexPositionsY = new int[var10]; - model.vertexPositionsZ = new int[var10]; - model.faceVertexIndices1 = new int[var11]; - model.faceVertexIndices2 = new int[var11]; - model.faceVertexIndices3 = new int[var11]; - if (var12 > 0) + if (var16 == 1) { - model.textureRenderTypes = new byte[var12]; - model.textureTriangleVertexIndices1 = new short[var12]; - model.textureTriangleVertexIndices2 = new short[var12]; - model.textureTriangleVertexIndices3 = new short[var12]; + def.packedVertexGroups = new int[var9]; } - if (var28 == 1) + if (var12 == 1) { - model.vertexSkins = new int[var10]; + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; } - if (var13 == 1) + if (var13 == 255) { - model.faceRenderTypes = new byte[var11]; - model.textureCoordinates = new byte[var11]; - model.faceTextures = new short[var11]; - } - - if (var14 == 255) - { - model.faceRenderPriorities = new byte[var11]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) var14; + def.priority = (byte) var13; } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[var11]; + def.faceTransparencies = new byte[var10]; } if (var15 == 1) { - model.faceSkins = new int[var11]; + def.packedTransparencyVertexGroups = new int[var10]; } - model.faceColors = new short[var11]; - var5.setOffset(var16); - var39.setOffset(var34); - var26.setOffset(var35); - var9.setOffset(var46); - var3.setOffset(var37); - int var41 = 0; - int var33 = 0; - int var19 = 0; - - int var6; - int var7; - int var8; - int var18; - int var31; - for (var18 = 0; var18 < var10; ++var18) + if (var17 == 1) { - var8 = var5.readUnsignedByte(); - var31 = 0; - if ((var8 & 1) != 0) + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var23); + var5.setOffset(var34); + var6.setOffset(var35); + var7.setOffset(var24); + var8.setOffset(var29); + int var37 = 0; + int var38 = 0; + int var39 = 0; + + int var40; + int var41; + int var42; + int var43; + int var44; + for (var40 = 0; var40 < var9; ++var40) + { + var41 = var4.readUnsignedByte(); + var42 = 0; + if ((var41 & 1) != 0) { - var31 = var39.readShortSmart(); + var42 = var5.readShortSmart(); } - var6 = 0; - if ((var8 & 2) != 0) + var43 = 0; + if ((var41 & 2) != 0) { - var6 = var26.readShortSmart(); + var43 = var6.readShortSmart(); } - var7 = 0; - if ((var8 & 4) != 0) + var44 = 0; + if ((var41 & 4) != 0) { - var7 = var9.readShortSmart(); + var44 = var7.readShortSmart(); } - model.vertexPositionsX[var18] = var41 + var31; - model.vertexPositionsY[var18] = var33 + var6; - model.vertexPositionsZ[var18] = var19 + var7; - var41 = model.vertexPositionsX[var18]; - var33 = model.vertexPositionsY[var18]; - var19 = model.vertexPositionsZ[var18]; - if (var28 == 1) + def.vertexX[var40] = var37 + var42; + def.vertexY[var40] = var38 + var43; + def.vertexZ[var40] = var39 + var44; + var37 = def.vertexX[var40]; + var38 = def.vertexY[var40]; + var39 = def.vertexZ[var40]; + if (var16 == 1) { - model.vertexSkins[var18] = var3.readUnsignedByte(); + def.packedVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var17); - var39.setOffset(var42); - var26.setOffset(var25); - var9.setOffset(var29); - var3.setOffset(var4); - - for (var18 = 0; var18 < var11; ++var18) + if (var17 == 1) { - model.faceColors[var18] = (short) var5.readUnsignedShort(); - if (var13 == 1) + for (var40 = 0; var40 < var9; ++var40) { - var8 = var39.readUnsignedByte(); - if ((var8 & 1) == 1) + var41 = var8.readUnsignedByte(); + def.animayaGroups[var40] = new int[var41]; + def.animayaScales[var40] = new int[var41]; + + for (var42 = 0; var42 < var41; ++var42) { - model.faceRenderTypes[var18] = 1; + def.animayaGroups[var40][var42] = var8.readUnsignedByte(); + def.animayaScales[var40][var42] = var8.readUnsignedByte(); + } + } + } + + var4.setOffset(var32); + var5.setOffset(var28); + var6.setOffset(var26); + var7.setOffset(var30); + var8.setOffset(var27); + + for (var40 = 0; var40 < var10; ++var40) + { + def.faceColors[var40] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var41 = var5.readUnsignedByte(); + if ((var41 & 1) == 1) + { + def.faceRenderTypes[var40] = 1; var2 = true; } else { - model.faceRenderTypes[var18] = 0; + def.faceRenderTypes[var40] = 0; } - if ((var8 & 2) == 2) + if ((var41 & 2) == 2) { - model.textureCoordinates[var18] = (byte) (var8 >> 2); - model.faceTextures[var18] = model.faceColors[var18]; - model.faceColors[var18] = 127; - if (model.faceTextures[var18] != -1) + def.textureCoords[var40] = (byte) (var41 >> 2); + def.faceTextures[var40] = def.faceColors[var40]; + def.faceColors[var40] = 127; + if (def.faceTextures[var40] != -1) { - var43 = true; + var3 = true; } } else { - model.textureCoordinates[var18] = -1; - model.faceTextures[var18] = -1; + def.textureCoords[var40] = -1; + def.faceTextures[var40] = -1; } } - if (var14 == 255) + if (var13 == 255) { - model.faceRenderPriorities[var18] = var26.readByte(); + def.faceRenderPriorities[var40] = var6.readByte(); } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas[var18] = var9.readByte(); + def.faceTransparencies[var40] = var7.readByte(); } if (var15 == 1) { - model.faceSkins[var18] = var3.readUnsignedByte(); + def.packedTransparencyVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var44); - var39.setOffset(var24); - var18 = 0; - var8 = 0; - var31 = 0; - var6 = 0; + var4.setOffset(var31); + var5.setOffset(var25); + var40 = 0; + var41 = 0; + var42 = 0; + var43 = 0; - int var21; - int var22; - for (var7 = 0; var7 < var11; ++var7) + int var45; + int var46; + for (var44 = 0; var44 < var10; ++var44) { - var22 = var39.readUnsignedByte(); - if (var22 == 1) + var45 = var5.readUnsignedByte(); + if (var45 == 1) { - var18 = var5.readShortSmart() + var6; - var8 = var5.readShortSmart() + var18; - var31 = var5.readShortSmart() + var8; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var4.readShortSmart() + var43; + var41 = var4.readShortSmart() + var40; + var42 = var4.readShortSmart() + var41; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 2) + if (var45 == 2) { - var8 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var41 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 3) + if (var45 == 3) { - var18 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 4) + if (var45 == 4) { - var21 = var18; - var18 = var8; - var8 = var21; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var21; - model.faceVertexIndices3[var7] = var31; + var46 = var40; + var40 = var41; + var41 = var46; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var46; + def.faceIndices3[var44] = var42; } } + var4.setOffset(var33); + + for (var44 = 0; var44 < var11; ++var44) + { + def.textureRenderTypes[var44] = 0; + def.texIndices1[var44] = (short) var4.readUnsignedShort(); + def.texIndices2[var44] = (short) var4.readUnsignedShort(); + def.texIndices3[var44] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) + { + boolean var47 = false; + + for (var45 = 0; var45 < var10; ++var45) + { + var46 = def.textureCoords[var45] & 255; + if (var46 != 255) + { + if (def.faceIndices1[var45] == (def.texIndices1[var46] & '\uffff') && def.faceIndices2[var45] == (def.texIndices2[var46] & '\uffff') && def.faceIndices3[var45] == (def.texIndices3[var46] & '\uffff')) + { + def.textureCoords[var45] = -1; + } + else + { + var47 = true; + } + } + } + + if (!var47) + { + def.textureCoords = null; + } + } + + if (!var3) + { + def.faceTextures = null; + } + + if (!var2) + { + def.faceRenderTypes = null; + } + + } + + void decodeType1(ModelDefinition def, byte[] var1) + { + InputStream var2 = new InputStream(var1); + InputStream var3 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 23); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); + int var13 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); + int var17 = var2.readUnsignedByte(); + int var18 = var2.readUnsignedShort(); + int var19 = var2.readUnsignedShort(); + int var20 = var2.readUnsignedShort(); + int var21 = var2.readUnsignedShort(); + int var22 = var2.readUnsignedShort(); + int var23 = 0; + int var24 = 0; + int var25 = 0; + int var26; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + var2.setOffset(0); + + for (var26 = 0; var26 < var11; ++var26) + { + byte var27 = def.textureRenderTypes[var26] = var2.readByte(); + if (var27 == 0) + { + ++var23; + } + + if (var27 >= 1 && var27 <= 3) + { + ++var24; + } + + if (var27 == 2) + { + ++var25; + } + } + } + + var26 = var11 + var9; + int var56 = var26; + if (var12 == 1) + { + var26 += var10; + } + + int var28 = var26; + var26 += var10; + int var29 = var26; + if (var13 == 255) + { + var26 += var10; + } + + int var30 = var26; + if (var15 == 1) + { + var26 += var10; + } + + int var31 = var26; + if (var17 == 1) + { + var26 += var9; + } + + int var32 = var26; + if (var14 == 1) + { + var26 += var10; + } + + int var33 = var26; + var26 += var21; + int var34 = var26; + if (var16 == 1) + { + var26 += var10 * 2; + } + + int var35 = var26; + var26 += var22; + int var36 = var26; + var26 += var10 * 2; + int var37 = var26; + var26 += var18; + int var38 = var26; + var26 += var19; + int var39 = var26; + var26 += var20; + int var40 = var26; + var26 += var23 * 6; + int var41 = var26; + var26 += var24 * 6; + int var42 = var26; + var26 += var24 * 6; + int var43 = var26; + var26 += var24 * 2; + int var44 = var26; + var26 += var24; + int var45 = var26; + var26 = var26 + var24 * 2 + var25 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var17 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + if (var16 == 1) + { + def.faceTextures = new short[var10]; + } + + if (var16 == 1 && var11 > 0) + { + def.textureCoords = new byte[var10]; + } + + def.faceColors = new short[var10]; + if (var11 > 0) + { + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + var2.setOffset(var11); + var3.setOffset(var37); + var4.setOffset(var38); + var5.setOffset(var39); + var6.setOffset(var31); + int var46 = 0; + int var47 = 0; + int var48 = 0; + + int var49; + int var50; + int var51; + int var52; + int var53; + for (var49 = 0; var49 < var9; ++var49) + { + var50 = var2.readUnsignedByte(); + var51 = 0; + if ((var50 & 1) != 0) + { + var51 = var3.readShortSmart(); + } + + var52 = 0; + if ((var50 & 2) != 0) + { + var52 = var4.readShortSmart(); + } + + var53 = 0; + if ((var50 & 4) != 0) + { + var53 = var5.readShortSmart(); + } + + def.vertexX[var49] = var46 + var51; + def.vertexY[var49] = var47 + var52; + def.vertexZ[var49] = var48 + var53; + var46 = def.vertexX[var49]; + var47 = def.vertexY[var49]; + var48 = def.vertexZ[var49]; + if (var17 == 1) + { + def.packedVertexGroups[var49] = var6.readUnsignedByte(); + } + } + + var2.setOffset(var36); + var3.setOffset(var56); + var4.setOffset(var29); var5.setOffset(var32); + var6.setOffset(var30); + var7.setOffset(var34); + var8.setOffset(var35); - for (var7 = 0; var7 < var12; ++var7) + for (var49 = 0; var49 < var10; ++var49) { - model.textureRenderTypes[var7] = 0; - model.textureTriangleVertexIndices1[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices2[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices3[var7] = (short) var5.readUnsignedShort(); + def.faceColors[var49] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var49] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var49] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var49] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var49] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var49] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var49] != -1) + { + def.textureCoords[var49] = (byte) (var8.readUnsignedByte() - 1); + } } - if (model.textureCoordinates != null) + var2.setOffset(var33); + var3.setOffset(var28); + var49 = 0; + var50 = 0; + var51 = 0; + var52 = 0; + + int var54; + for (var53 = 0; var53 < var10; ++var53) + { + var54 = var3.readUnsignedByte(); + if (var54 == 1) + { + var49 = var2.readShortSmart() + var52; + var50 = var2.readShortSmart() + var49; + var51 = var2.readShortSmart() + var50; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 2) + { + var50 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 3) + { + var49 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 4) + { + int var55 = var49; + var49 = var50; + var50 = var55; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var55; + def.faceIndices3[var53] = var51; + } + } + + var2.setOffset(var40); + var3.setOffset(var41); + var4.setOffset(var42); + var5.setOffset(var43); + var6.setOffset(var44); + var7.setOffset(var45); + + for (var53 = 0; var53 < var11; ++var53) + { + var54 = def.textureRenderTypes[var53] & 255; + if (var54 == 0) + { + def.texIndices1[var53] = (short) var2.readUnsignedShort(); + def.texIndices2[var53] = (short) var2.readUnsignedShort(); + def.texIndices3[var53] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var26); + var53 = var2.readUnsignedByte(); + if (var53 != 0) + { + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readInt(); + } + + } + + void decodeOldFormat(ModelDefinition def, byte[] var1) + { + boolean var2 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 18); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedShort(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + byte var21 = 0; + int var22 = var21 + var9; + int var23 = var22; + var22 += var10; + int var24 = var22; + if (var13 == 255) + { + var22 += var10; + } + + int var25 = var22; + if (var15 == 1) + { + var22 += var10; + } + + int var26 = var22; + if (var12 == 1) + { + var22 += var10; + } + + int var27 = var22; + if (var16 == 1) + { + var22 += var9; + } + + int var28 = var22; + if (var14 == 1) + { + var22 += var10; + } + + int var29 = var22; + var22 += var20; + int var30 = var22; + var22 += var10 * 2; + int var31 = var22; + var22 += var11 * 6; + int var32 = var22; + var22 += var17; + int var33 = var22; + var22 += var18; + int var10000 = var22 + var19; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + if (var16 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var21); + var5.setOffset(var32); + var6.setOffset(var33); + var7.setOffset(var22); + var8.setOffset(var27); + int var35 = 0; + int var36 = 0; + int var37 = 0; + + int var38; + int var39; + int var40; + int var41; + int var42; + for (var38 = 0; var38 < var9; ++var38) + { + var39 = var4.readUnsignedByte(); + var40 = 0; + if ((var39 & 1) != 0) + { + var40 = var5.readShortSmart(); + } + + var41 = 0; + if ((var39 & 2) != 0) + { + var41 = var6.readShortSmart(); + } + + var42 = 0; + if ((var39 & 4) != 0) + { + var42 = var7.readShortSmart(); + } + + def.vertexX[var38] = var35 + var40; + def.vertexY[var38] = var36 + var41; + def.vertexZ[var38] = var37 + var42; + var35 = def.vertexX[var38]; + var36 = def.vertexY[var38]; + var37 = def.vertexZ[var38]; + if (var16 == 1) + { + def.packedVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var30); + var5.setOffset(var26); + var6.setOffset(var24); + var7.setOffset(var28); + var8.setOffset(var25); + + for (var38 = 0; var38 < var10; ++var38) + { + def.faceColors[var38] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var39 = var5.readUnsignedByte(); + if ((var39 & 1) == 1) + { + def.faceRenderTypes[var38] = 1; + var2 = true; + } + else + { + def.faceRenderTypes[var38] = 0; + } + + if ((var39 & 2) == 2) + { + def.textureCoords[var38] = (byte) (var39 >> 2); + def.faceTextures[var38] = def.faceColors[var38]; + def.faceColors[var38] = 127; + if (def.faceTextures[var38] != -1) + { + var3 = true; + } + } + else + { + def.textureCoords[var38] = -1; + def.faceTextures[var38] = -1; + } + } + + if (var13 == 255) + { + def.faceRenderPriorities[var38] = var6.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var38] = var7.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var29); + var5.setOffset(var23); + var38 = 0; + var39 = 0; + var40 = 0; + var41 = 0; + + int var43; + int var44; + for (var42 = 0; var42 < var10; ++var42) + { + var43 = var5.readUnsignedByte(); + if (var43 == 1) + { + var38 = var4.readShortSmart() + var41; + var39 = var4.readShortSmart() + var38; + var40 = var4.readShortSmart() + var39; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 2) + { + var39 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 3) + { + var38 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 4) + { + var44 = var38; + var38 = var39; + var39 = var44; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var44; + def.faceIndices3[var42] = var40; + } + } + + var4.setOffset(var31); + + for (var42 = 0; var42 < var11; ++var42) + { + def.textureRenderTypes[var42] = 0; + def.texIndices1[var42] = (short) var4.readUnsignedShort(); + def.texIndices2[var42] = (short) var4.readUnsignedShort(); + def.texIndices3[var42] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) { boolean var45 = false; - for (var22 = 0; var22 < var11; ++var22) + for (var43 = 0; var43 < var10; ++var43) { - var21 = model.textureCoordinates[var22] & 255; - if (var21 != 255) + var44 = def.textureCoords[var43] & 255; + if (var44 != 255) { - if ((model.textureTriangleVertexIndices1[var21] & '\uffff') == model.faceVertexIndices1[var22] && (model.textureTriangleVertexIndices2[var21] & '\uffff') == model.faceVertexIndices2[var22] && (model.textureTriangleVertexIndices3[var21] & '\uffff') == model.faceVertexIndices3[var22]) + if (def.faceIndices1[var43] == (def.texIndices1[var44] & '\uffff') && def.faceIndices2[var43] == (def.texIndices2[var44] & '\uffff') && def.faceIndices3[var43] == (def.texIndices3[var44] & '\uffff')) { - model.textureCoordinates[var22] = -1; + def.textureCoords[var43] = -1; } else { @@ -732,19 +1394,19 @@ public class ModelLoader if (!var45) { - model.textureCoordinates = null; + def.textureCoords = null; } } - if (!var43) + if (!var3) { - model.faceTextures = null; + def.faceTextures = null; } if (!var2) { - model.faceRenderTypes = null; + def.faceRenderTypes = null; } - } + } } diff --git a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java index c93edf3611..cd70e9b218 100644 --- a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java +++ b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java @@ -227,22 +227,22 @@ public class ItemSpriteFactory litModel.field1856 = new int[def.faceCount]; litModel.field1854 = new int[def.faceCount]; litModel.field1823 = new int[def.faceCount]; - if (def.textureTriangleCount > 0 && def.textureCoordinates != null) + if (def.numTextureFaces > 0 && def.textureCoords != null) { - int[] var9 = new int[def.textureTriangleCount]; + int[] var9 = new int[def.numTextureFaces]; int var10; for (var10 = 0; var10 < def.faceCount; ++var10) { - if (def.textureCoordinates[var10] != -1) + if (def.textureCoords[var10] != -1) { - ++var9[def.textureCoordinates[var10] & 255]; + ++var9[def.textureCoords[var10] & 255]; } } litModel.field1852 = 0; - for (var10 = 0; var10 < def.textureTriangleCount; ++var10) + for (var10 = 0; var10 < def.numTextureFaces; ++var10) { if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0) { @@ -256,13 +256,13 @@ public class ItemSpriteFactory var10 = 0; - for (int i = 0; i < def.textureTriangleCount; ++i) + for (int i = 0; i < def.numTextureFaces; ++i) { if (var9[i] > 0 && def.textureRenderTypes[i] == 0) { - litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff'; - litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff'; - litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff'; + litModel.field1844[var10] = def.texIndices1[i] & '\uffff'; + litModel.field1865[var10] = def.texIndices2[i] & '\uffff'; + litModel.field1846[var10] = def.texIndices3[i] & '\uffff'; var9[i] = var10++; } else @@ -275,9 +275,9 @@ public class ItemSpriteFactory for (int i = 0; i < def.faceCount; ++i) { - if (def.textureCoordinates[i] != -1) + if (def.textureCoords[i] != -1) { - litModel.field1840[i] = (byte) var9[def.textureCoordinates[i] & 255]; + litModel.field1840[i] = (byte) var9[def.textureCoords[i] & 255]; } else { @@ -299,13 +299,13 @@ public class ItemSpriteFactory } byte faceAlpha; - if (def.faceAlphas == null) + if (def.faceTransparencies == null) { faceAlpha = 0; } else { - faceAlpha = def.faceAlphas[faceIdx]; + faceAlpha = def.faceTransparencies[faceIdx]; } short faceTexture; @@ -355,15 +355,15 @@ public class ItemSpriteFactory else { int var15 = def.faceColors[faceIdx] & '\uffff'; - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = method2608(var15, tmp); @@ -385,15 +385,15 @@ public class ItemSpriteFactory } else { - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = bound2to126(tmp); @@ -401,15 +401,15 @@ public class ItemSpriteFactory } litModel.verticesCount = def.vertexCount; - litModel.verticesX = def.vertexPositionsX; - litModel.verticesY = def.vertexPositionsY; - litModel.verticesZ = def.vertexPositionsZ; + litModel.verticesX = def.vertexX; + litModel.verticesY = def.vertexY; + litModel.verticesZ = def.vertexZ; litModel.indicesCount = def.faceCount; - litModel.indices1 = def.faceVertexIndices1; - litModel.indices2 = def.faceVertexIndices2; - litModel.indices3 = def.faceVertexIndices3; + litModel.indices1 = def.faceIndices1; + litModel.indices2 = def.faceIndices2; + litModel.indices3 = def.faceIndices3; litModel.field1838 = def.faceRenderPriorities; - litModel.field1882 = def.faceAlphas; + litModel.field1882 = def.faceTransparencies; litModel.field1842 = def.priority; litModel.field1841 = def.faceTextures; return litModel; diff --git a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java index fb65f99972..75b67f689f 100644 --- a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java +++ b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java @@ -53,9 +53,9 @@ public class ObjExporter for (int i = 0; i < model.vertexCount; ++i) { - objWriter.println("v " + model.vertexPositionsX[i] + " " - + model.vertexPositionsY[i] * -1 + " " - + model.vertexPositionsZ[i] * -1); + objWriter.println("v " + model.vertexX[i] + " " + + model.vertexY[i] * -1 + " " + + model.vertexZ[i] * -1); } if (model.faceTextures != null) @@ -78,9 +78,9 @@ public class ObjExporter for (int i = 0; i < model.faceCount; ++i) { - int x = model.faceVertexIndices1[i] + 1; - int y = model.faceVertexIndices2[i] + 1; - int z = model.faceVertexIndices3[i] + 1; + int x = model.faceIndices1[i] + 1; + int y = model.faceIndices2[i] + 1; + int z = model.faceIndices3[i] + 1; objWriter.println("usemtl m" + i); if (model.faceTextures != null) @@ -129,9 +129,9 @@ public class ObjExporter int alpha = 0; - if (model.faceAlphas != null) + if (model.faceTransparencies != null) { - alpha = model.faceAlphas[i] & 0xFF; + alpha = model.faceTransparencies[i] & 0xFF; } if (alpha != 0) From a3ed6c089f420642fe55e765b183cbe2be2dbc9a Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Dec 2021 11:00:45 -0500 Subject: [PATCH 13/42] gpu: add model hsl override support --- .../src/main/java/net/runelite/api/Model.java | 5 ++ .../client/plugins/gpu/SceneUploader.java | 60 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index d3756ea727..03045dac2c 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -89,4 +89,9 @@ public interface Model extends Renderable int[] getVertexNormalsX(); int[] getVertexNormalsY(); int[] getVertexNormalsZ(); + + byte getOverrideAmount(); + byte getOverrideHue(); + byte getOverrideSaturation(); + byte getOverrideLuminance(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 1bf9dcce63..82f8676ce5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -402,6 +402,11 @@ class SceneUploader float[] uv = model.getFaceTextureUVCoordinates(); + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int len = 0; for (int face = 0; face < triangleCount; ++face) { @@ -429,6 +434,16 @@ class SceneUploader len += 3; continue; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); @@ -470,14 +485,19 @@ class SceneUploader final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = indices1[face]; - int triangleB = indices2[face]; - int triangleC = indices3[face]; + final int triangleA = indices1[face]; + final int triangleB = indices2[face]; + final int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; int color3 = color3s[face]; + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); int sin = 0, cos = 0; @@ -505,6 +525,16 @@ class SceneUploader } return 3; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int a, b, c; @@ -605,4 +635,28 @@ class SceneUploader uvBuffer.put(0, 0, 0, 0); } } + + private static int interpolateHSL(int hsl, byte hue2, byte sat2, byte lum2, byte lerp) + { + int hue = hsl >> 10 & 63; + int sat = hsl >> 7 & 7; + int lum = hsl & 127; + int var9 = lerp & 255; + if (hue2 != -1) + { + hue += var9 * (hue2 - hue) >> 7; + } + + if (sat2 != -1) + { + sat += var9 * (sat2 - sat) >> 7; + } + + if (lum2 != -1) + { + lum += var9 * (lum2 - lum) >> 7; + } + + return (hue << 10 | sat << 7 | lum) & 65535; + } } From 51cab2a3d80158fa0da57e6573b5c92f4762e2c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Dec 2021 13:17:04 -0500 Subject: [PATCH 14/42] nmz: fix point overlay flickering with unlocked fps --- .../nightmarezone/NightmareZoneOverlay.java | 7 ------- .../nightmarezone/NightmareZonePlugin.java | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 679f773913..4ad21005b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -91,13 +91,6 @@ class NightmareZoneOverlay extends OverlayPanel return null; } - Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); - - if (nmzWidget != null) - { - nmzWidget.setHidden(true); - } - renderAbsorptionCounter(); final int currentPoints = client.getVar(Varbits.NMZ_POINTS); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index ccd2a775c0..f95e2ab8a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -33,6 +33,7 @@ import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Varbits; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ChatMessage; import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.GameTick; @@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin return configManager.getConfig(NightmareZoneConfig.class); } + @Subscribe + public void onBeforeRender(BeforeRender beforeRender) + { + if (!isInNightmareZone() || !config.moveOverlay()) + { + return; + } + + Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); + if (nmzWidget != null) + { + nmzWidget.setHidden(true); + } + } + @Subscribe public void onGameTick(GameTick event) { From 0c76977381ade2a8d5d74a8fb593d51717461326 Mon Sep 17 00:00:00 2001 From: Wayne Li Date: Sun, 12 Dec 2021 17:26:49 -0800 Subject: [PATCH 15/42] hiscores: fix npe --- .../net/runelite/client/plugins/hiscore/NameAutocompleter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java index 00cadc1e22..3870803490 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java @@ -242,6 +242,7 @@ class NameAutocompleter implements KeyListener autocompleteName = Arrays.stream(cachedPlayers) .filter(Objects::nonNull) .map(Player::getName) + .filter(Objects::nonNull) .filter(n -> pattern.matcher(n).matches()) .findFirst(); } From 36e670112ee7fc8d808b17f46d9989dd0cc0851f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 13 Dec 2021 17:35:39 -0500 Subject: [PATCH 16/42] widget inspector: add listeners --- .../plugins/devtools/WidgetInfoTableModel.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java index 5e5e9a6011..ed99e6ef70 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java @@ -48,16 +48,16 @@ public class WidgetInfoTableModel extends AbstractTableModel private static final int COL_FIELD = 0; private static final int COL_VALUE = 1; - private final List fields = populateWidgetFields(); + private final List> fields = populateWidgetFields(); private Widget widget = null; - private Map values = null; + private Map, Object> values = null; public void setWidget(Widget w) { clientThread.invoke(() -> { - Map newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( + Map, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( Function.identity(), i -> i.getValue(w) )); @@ -137,9 +137,9 @@ public class WidgetInfoTableModel extends AbstractTableModel }); } - private List populateWidgetFields() + private List> populateWidgetFields() { - List out = new ArrayList<>(); + List> out = new ArrayList<>(); out.add(new WidgetField<>("Id", Widget::getId)); out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class)); @@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel } return null; })); + out.add(new WidgetField<>("OnOpListener", Widget::getOnOpListener)); + out.add(new WidgetField<>("OnKeyListener", Widget::getOnKeyListener)); + out.add(new WidgetField<>("OnLoadListener", Widget::getOnLoadListener)); + out.add(new WidgetField<>("OnInvTransmitListener", Widget::getOnInvTransmitListener)); + out.add(new WidgetField<>("OnVarTransmitListener", Widget::getOnVarTransmitListener)); return out; } From 62bb21a5169ebf38eb4691ff8187ae40a89f5a24 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 13 Dec 2021 17:38:30 -0500 Subject: [PATCH 17/42] chatchannels: display online member count Co-authored-by: Dasgust --- .../main/java/net/runelite/api/ScriptID.java | 6 +++ .../net/runelite/api/widgets/WidgetID.java | 4 ++ .../net/runelite/api/widgets/WidgetInfo.java | 5 ++ .../chatchannel/ChatChannelConfig.java | 24 ++++++++++ .../chatchannel/ChatChannelPlugin.java | 48 +++++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java index 099ebc1537..c2762be1a3 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -199,6 +199,12 @@ public final class ScriptID @ScriptArguments(integer = 15) public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658; + /** + * Builds the widget that holds all of the players inside a clan chat + */ + @ScriptArguments(integer = 7) + public static final int CLAN_SIDEPANEL_DRAW = 4396; + /** * Builds the widget for making an offer in Grand Exchange */ diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 7e4588ace8..0b69d793ab 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -921,11 +921,15 @@ public final class WidgetID static class Clan { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } static class ClanGuest { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 8e43b14e66..b5b91a7827 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -552,7 +552,12 @@ public enum WidgetInfo TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), + CLAN_LAYER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.LAYER), + CLAN_HEADER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.HEADER), CLAN_MEMBER_LIST(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.MEMBERS), + + CLAN_GUEST_LAYER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.LAYER), + CLAN_GUEST_HEADER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.HEADER), CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS), POH_TREASURE_CHEST_INVENTORY_CONTAINER(WidgetID.POH_TREASURE_CHEST_INVENTORY_GROUP_ID, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java index eeffc30f4d..66739bf5a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java @@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config return false; } + @ConfigItem( + keyName = "clanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online clan members at the end of the clan's name.", + position = 1, + section = clanChatSection + ) + default boolean clanChatShowOnlineMemberCount() + { + return false; + } + @ConfigItem( keyName = "guestClanChatShowJoinLeave", name = "Show Join/Leave", @@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config { return false; } + + @ConfigItem( + keyName = "guestClanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online guest clan members at the end of the clan's name.", + position = 1, + section = guestClanChatSection + ) + default boolean guestClanChatShowOnlineMemberCount() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 25ac07f449..d1277b981d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin { clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor())); } + + rebuildClanTitle(); } @Override @@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin chats = null; clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE)); rebuildFriendsChat(); + rebuildClanTitle(); } @Subscribe @@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE; clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor)); + + rebuildClanTitle(); } } @@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); } } + else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) + { + if (config.clanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_HEADER, client.getClanChannel()); + } + + if (config.guestClanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_GUEST_HEADER, client.getGuestClanChannel()); + } + } } private void insertRankIcon(final ChatMessage message) @@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin listWidget.setTextColor(ignoreColor.getRGB()); } } + + private void rebuildClanTitle() + { + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_GUEST_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + } + + private void updateClanTitle(WidgetInfo widget, ClanChannel channel) + { + Widget header = client.getWidget(widget); + if (header != null && channel != null) + { + Widget title = header.getChild(0); + title.setText(title.getText() + " (" + channel.getMembers().size() + ")"); + } + } } From be56010800a12782b2a8308930e9d90cd4e2572e Mon Sep 17 00:00:00 2001 From: Alan Baumgartner Date: Wed, 13 Oct 2021 17:39:38 -0500 Subject: [PATCH 18/42] party: add option to join previous party and join party by id Co-authored-by: Adam --- .../client/plugins/party/PartyConfig.java | 19 ++++ .../client/plugins/party/PartyPanel.java | 103 +++++++++++++++++- .../client/plugins/party/PartyPlugin.java | 7 +- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java index 5d38da1b3d..4d484f4cdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java @@ -99,4 +99,23 @@ public interface PartyConfig extends Config { return false; } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + default String previousPartyId() + { + return ""; + } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + void setPreviousPartyId(String id); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 3c3c1bba95..52d4799e95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -26,6 +26,12 @@ package net.runelite.client.plugins.party; import com.google.inject.Inject; import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel private final Map memberBoxes = new HashMap<>(); private final JButton startButton = new JButton(); + private final JButton joinPartyButton = new JButton(); + private final JButton rejoinPartyButton = new JButton(); + private final JButton copyPartyIdButton = new JButton(); private final PluginErrorPanel noPartyPanel = new PluginErrorPanel(); private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel(); @@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel final JPanel topPanel = new JPanel(); - topPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - topPanel.setLayout(new BorderLayout()); + topPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); + topPanel.setLayout(new GridBagLayout()); - topPanel.add(startButton, BorderLayout.CENTER); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(0, 2, 4, 2); + + c.gridx = 0; + c.gridy = 0; + topPanel.add(startButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(joinPartyButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(copyPartyIdButton, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 2; + topPanel.add(rejoinPartyButton, c); layoutPanel.add(topPanel); layoutPanel.add(requestBoxPanel); @@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); startButton.setFocusable(false); - topPanel.add(startButton); + joinPartyButton.setText("Join party"); + joinPartyButton.setFocusable(false); + + rejoinPartyButton.setText("Join previous party"); + rejoinPartyButton.setFocusable(false); + + copyPartyIdButton.setText("Copy party id"); + copyPartyIdButton.setFocusable(false); startButton.addActionListener(e -> { @@ -115,6 +150,63 @@ class PartyPanel extends PluginPanel } }); + joinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + String s = (String) JOptionPane.showInputDialog( + joinPartyButton, + "Please enter the party id:", + "Party Id", + JOptionPane.PLAIN_MESSAGE, + null, + null, + ""); + + if (s == null) + { + return; + } + + try + { + party.changeParty(UUID.fromString(s)); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + rejoinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + try + { + party.changeParty(UUID.fromString(config.previousPartyId())); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(rejoinPartyButton, + "Failed to join your previous party, create a new party or join a new one.", + "Failed to Join Party", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + copyPartyIdButton.addActionListener(e -> + { + if (party.isInParty()) + { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null); + } + }); + noPartyPanel.setContent("Not in a party", "Create a party to begin."); partyEmptyPanel.setContent("Party created", "You can now invite friends!"); @@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel remove(partyEmptyPanel); startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); + joinPartyButton.setVisible(!party.isInParty()); + rejoinPartyButton.setVisible(!party.isInParty()); + copyPartyIdButton.setVisible(party.isInParty()); if (!party.isInParty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index e9287210a8..ae13a4a22f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -66,8 +66,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.plugins.Plugin; @@ -585,6 +585,11 @@ public class PartyPlugin extends Plugin pendingTilePings.clear(); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); + if (event.getPartyId() != null) + { + config.setPreviousPartyId(String.valueOf(event.getPartyId())); + } + SwingUtilities.invokeLater(() -> { panel.removeAllMembers(); From 9e06f8d5c2a36b819582214db38606e57008bc90 Mon Sep 17 00:00:00 2001 From: Logan Date: Mon, 13 Dec 2021 16:06:58 -0800 Subject: [PATCH 19/42] emoji: add rocketship emoji --- .../net/runelite/client/plugins/emojis/Emoji.java | 1 + .../runelite/client/plugins/emojis/rocketship.png | Bin 0 -> 789 bytes 2 files changed, 1 insertion(+) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.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 8eb163ba53..8d64881631 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 @@ -93,6 +93,7 @@ enum Emoji XD("Xd"), SPOON("--o"), WEARY_FACE("Dx"), + ROCKETSHIP("=="), // >==> ; private static final Map emojiMap; diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png new file mode 100644 index 0000000000000000000000000000000000000000..62bb05ace924be1046e3851718eab7c6a34e1d6b GIT binary patch literal 789 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D2fox}&cn1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKhU=$DV32_A~2wn3oY~9EC z?1~Fm?-L>bCqEn2hmX+7E3n6PigsgcNwDhT>b4k ztN%SuYhGS$&U9Kgpc<&3G0EHACFa!)hUq{Kdx@v7EBjL(R(4ji^B=u_1BEttx;Tb# zT-QB!RjkQD#Nnc~)ix!uGNrE0yM}BlJUV3m|CfIhHE;XhGKMn(PGa&;mowM1I6piw z=|aNM8)@l_HeRjT{I&V8q`ykA%apR;Cae~d&pzc}R5K-vRepo3tLm(}Nk=12FvYAq zBmKNvZ&HRpcptHiD0_Lb%CKn)C@u6{1- HoD!M Date: Sun, 12 Dec 2021 21:04:55 -0500 Subject: [PATCH 20/42] hiscore: add nex --- .../runelite/http/api/hiscore/HiscoreResult.java | 3 +++ .../http/api/hiscore/HiscoreResultBuilder.java | 4 ++++ .../runelite/http/api/hiscore/HiscoreSkill.java | 1 + .../http/service/hiscore/HiscoreServiceTest.java | 4 +++- .../client/plugins/hiscore/HiscorePanel.java | 14 +++++++------- .../client/plugins/hiscore/bosses/nex.png | Bin 0 -> 585 bytes 6 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java index de52f5c5aa..af6c461562 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java @@ -93,6 +93,7 @@ public class HiscoreResult private Skill kreearra; private Skill krilTsutsaroth; private Skill mimic; + private Skill nex; private Skill nightmare; private Skill phosanisNightmare; private Skill obor; @@ -244,6 +245,8 @@ public class HiscoreResult return krilTsutsaroth; case MIMIC: return mimic; + case NEX: + return nex; case NIGHTMARE: return nightmare; case PHOSANIS_NIGHTMARE: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java index 6c88ebcd18..ee8504bc8a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java @@ -118,6 +118,10 @@ class HiscoreResultBuilder hiscoreResult.setKreearra(skills.get(index++)); hiscoreResult.setKrilTsutsaroth(skills.get(index++)); hiscoreResult.setMimic(skills.get(index++)); + if (skills.size() > 83) + { + hiscoreResult.setNex(skills.get(index++)); + } hiscoreResult.setNightmare(skills.get(index++)); hiscoreResult.setPhosanisNightmare(skills.get(index++)); hiscoreResult.setObor(skills.get(index++)); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java index 698bd34e8e..0856e9270a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java @@ -97,6 +97,7 @@ public enum HiscoreSkill KREEARRA("Kree'Arra", BOSS), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS), MIMIC("Mimic", BOSS), + NEX("Nex", BOSS), NIGHTMARE("Nightmare", BOSS), PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS), OBOR("Obor", BOSS), diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java index a301e694d9..798116e7ee 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java @@ -98,7 +98,8 @@ public class HiscoreServiceTest + "702,6495\n" + "10170,184\n" + "8064,202\n" - + "6936,2\n" + + "6936,2\n" // Mimic + + "1,4920\n" // Nex + "2335,9\n" // Nightmare + "2336,10\n" // Phosanis Nightmare + "-1,-1\n" @@ -151,6 +152,7 @@ public class HiscoreServiceTest Assert.assertEquals(2460, result.getLeaguePoints().getLevel()); Assert.assertEquals(37, result.getAbyssalSire().getLevel()); Assert.assertEquals(92357, result.getCallisto().getRank()); + Assert.assertEquals(4920, result.getNex().getLevel()); Assert.assertEquals(2336, result.getPhosanisNightmare().getRank()); Assert.assertEquals(5678, result.getTempoross().getLevel()); Assert.assertEquals(42, result.getTheatreOfBloodHardMode().getLevel()); 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 56673629e4..b823a57f62 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 @@ -105,13 +105,13 @@ public class HiscorePanel extends PluginPanel GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI, KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN, KREEARRA, KRIL_TSUTSAROTH, MIMIC, - NIGHTMARE, PHOSANIS_NIGHTMARE, OBOR, SARACHNIS, - SCORPIA, SKOTIZO, TEMPOROSS, - THE_GAUNTLET, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, - THEATRE_OF_BLOOD_HARD_MODE, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, - TZTOK_JAD, VENENATIS, VETION, - VORKATH, WINTERTODT, ZALCANO, - ZULRAH + NEX, NIGHTMARE, PHOSANIS_NIGHTMARE, + OBOR, SARACHNIS, SCORPIA, + SKOTIZO, TEMPOROSS, THE_GAUNTLET, + THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, THEATRE_OF_BLOOD_HARD_MODE, + THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, TZTOK_JAD, + VENENATIS, VETION, VORKATH, + WINTERTODT, ZALCANO, ZULRAH ); private static final HiscoreEndpoint[] ENDPOINTS = { diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png new file mode 100644 index 0000000000000000000000000000000000000000..eaaa147d0f4bb2ecba686578ed85a56723553de6 GIT binary patch literal 585 zcmV-P0=E5$P)FeMme`J~Ts&d7*S*e^W+V zg>8|CZ@EQEE9eL2zAqT}@^B`S|7H;7veN!L_ugqnb1R0d!JMQvg8b*k%9#0NP1JK~yNuwb5H! z0bvjaaQ~LbuB`NKn`Oz`RwtyQoXSh(oX8=i@BcCEg^SsTOZ~6rncp)PGvjjoM_^}r zcTdwOZu5}u2pIQxFbhTb(JsIUJe8mq%9U!`P=OkO=NHsD*A>ni zK$F1h8(>+Szqi^zhXA@jPwNjphMySG4KW7lU;W8+HpjPPb32R0&+l~kx8;oM?EarC Xzmpf%HB?FZ00000NkvXXu0mjfRDSB` literal 0 HcmV?d00001 From 9e7f7d97ef1525c1beb892dea8e7f83cf34ba364 Mon Sep 17 00:00:00 2001 From: Zach Date: Tue, 14 Dec 2021 00:53:50 -0800 Subject: [PATCH 21/42] widget item overlay: add group storage to showOnBank --- .../src/main/java/net/runelite/api/widgets/WidgetID.java | 6 ++++++ .../src/main/java/net/runelite/api/widgets/WidgetInfo.java | 2 ++ .../net/runelite/client/ui/overlay/WidgetItemOverlay.java | 1 + 3 files changed, 9 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 0b69d793ab..fbac727d36 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -171,6 +171,7 @@ public final class WidgetID public static final int GRAVESTONE_GROUP_ID = 672; public static final int POH_TREASURE_CHEST_INVENTORY_GROUP_ID = 674; public static final int GROUP_IRON_GROUP_ID = 726; + public static final int GROUP_STORAGE_GROUP_ID = 724; static class WorldMap { @@ -294,6 +295,11 @@ public final class WidgetID static final int EQUIPMENT_BUTTON = 113; } + static class GroupStorage + { + static final int ITEM_CONTAINER = 10; + } + static class GrandExchange { static final int WINDOW_CONTAINER = 0; diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index b5b91a7827..70a9d221fd 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -153,6 +153,8 @@ public enum WidgetInfo BANK_SETTINGS_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.SETTINGS_BUTTON), BANK_TUTORIAL_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.TUTORIAL_BUTTON), + GROUP_STORAGE_ITEM_CONTAINER(WidgetID.GROUP_STORAGE_GROUP_ID, WidgetID.GroupStorage.ITEM_CONTAINER), + GRAND_EXCHANGE_WINDOW_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.WINDOW_CONTAINER), GRAND_EXCHANGE_OFFER_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONTAINER), GRAND_EXCHANGE_OFFER_TEXT(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_DESCRIPTION), diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java index 0233b3856a..5151b60e42 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java @@ -135,6 +135,7 @@ public abstract class WidgetItemOverlay extends Overlay protected void showOnBank() { drawAfterLayer(WidgetInfo.BANK_ITEM_CONTAINER); + drawAfterLayer(WidgetInfo.GROUP_STORAGE_ITEM_CONTAINER); } protected void showOnEquipment() From e04a6becd2ac5535e97c4ae01f72bad8af2f9187 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 14 Dec 2021 18:48:37 -0500 Subject: [PATCH 22/42] grandexchange: remove osb ge client --- .../client/plugins/grandexchange/GrandExchangePlugin.java | 7 ------- .../plugins/grandexchange/GrandExchangePluginTest.java | 5 ----- 2 files changed, 12 deletions(-) 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 f5458b9562..c1c92c2f38 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 @@ -103,7 +103,6 @@ import net.runelite.client.util.Text; 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.worlds.WorldType; import okhttp3.OkHttpClient; import org.apache.commons.lang3.time.DurationFormatUtils; @@ -260,12 +259,6 @@ public class GrandExchangePlugin extends Plugin return configManager.getConfig(GrandExchangeConfig.class); } - @Provides - OSBGrandExchangeClient provideOsbGrandExchangeClient(OkHttpClient okHttpClient) - { - return new OSBGrandExchangeClient(okHttpClient); - } - @Provides GrandExchangeClient provideGrandExchangeClient(OkHttpClient okHttpClient) { 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 8624a9017a..b6139cc265 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 @@ -53,7 +53,6 @@ import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.find import static net.runelite.http.api.RuneLiteAPI.GSON; import net.runelite.http.api.ge.GrandExchangeClient; import net.runelite.http.api.ge.GrandExchangeTrade; -import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -112,10 +111,6 @@ public class GrandExchangePluginTest @Bind private GrandExchangeClient grandExchangeClient; - @Mock - @Bind - private OSBGrandExchangeClient osbGrandExchangeClient; - @Mock @Bind private Client client; From b3c4465e73240daf8f31f27b6fa1eb0a2c9c1ba2 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 14 Dec 2021 19:26:47 -0500 Subject: [PATCH 23/42] Move hiscore client to rl-client Thie removes the http-service hiscore api, which we haven't used in awhile and doesn't work in practice due to upstream rate limits, as well as the xp tracker which also hasn't been used in a long time since there are now multiple quality community run xptrackers. --- http-api/pom.xml | 5 - .../api/hiscore/SingleHiscoreSkillResult.java | 111 ------- .../net/runelite/http/api/hiscore/Skill.java | 101 ------ .../java/net/runelite/http/api/xp/XpData.java | 85 ----- http-service/pom.xml | 31 -- .../service/SpringBootWebApplication.java | 19 -- .../service/hiscore/HiscoreController.java | 96 ------ .../http/service/hiscore/HiscoreKey.java | 36 -- .../http/service/hiscore/HiscoreService.java | 68 ---- .../service/util/HiscoreEndpointEditor.java | 40 --- .../runelite/http/service/xp/XpMapper.java | 92 ------ .../http/service/xp/XpTrackerController.java | 59 ---- .../http/service/xp/XpTrackerService.java | 307 ------------------ .../http/service/xp/beans/XpEntity.java | 85 ----- .../src/main/resources/application-dev.yaml | 7 - .../src/main/resources/application.yaml | 2 - .../net/runelite/http/service/xp/schema.sql | 135 -------- .../service/hiscore/HiscoreServiceTest.java | 162 --------- .../service/hiscore/HiscoreTestService.java | 46 --- .../http/service/xp/XpMapperTest.java | 59 ---- runelite-client/pom.xml | 47 +-- .../client}/hiscore/HiscoreClient.java | 30 +- .../client}/hiscore/HiscoreEndpoint.java | 5 +- .../{game => hiscore}/HiscoreLoader.java | 9 +- .../{game => hiscore}/HiscoreManager.java | 7 +- .../client}/hiscore/HiscoreResult.java | 74 ++--- .../client}/hiscore/HiscoreResultBuilder.java | 11 +- .../client}/hiscore/HiscoreSkill.java | 8 +- .../client}/hiscore/HiscoreSkillType.java | 2 +- .../net/runelite/client/hiscore/Skill.java | 19 +- .../chatcommands/ChatCommandsPlugin.java | 17 +- .../client/plugins/hiscore/HiscorePanel.java | 14 +- .../client/plugins/hiscore/HiscorePlugin.java | 2 +- .../opponentinfo/OpponentInfoOverlay.java | 4 +- .../opponentinfo/OpponentInfoPlugin.java | 2 +- .../opponentinfo/PlayerComparisonOverlay.java | 8 +- .../client/plugins/poh/PohPlugin.java | 8 +- .../client/hiscore/HiscoreClientTest.java | 160 +++++++++ .../chatcommands/ChatCommandsPluginTest.java | 18 +- .../plugins/hiscore/HiscorePanelTest.java | 2 +- 40 files changed, 289 insertions(+), 1704 deletions(-) delete mode 100644 http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java delete mode 100644 http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java delete mode 100644 http-api/src/main/java/net/runelite/http/api/xp/XpData.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreKey.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/util/HiscoreEndpointEditor.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/xp/beans/XpEntity.java delete mode 100644 http-service/src/main/resources/net/runelite/http/service/xp/schema.sql delete mode 100644 http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java delete mode 100644 http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java delete mode 100644 http-service/src/test/java/net/runelite/http/service/xp/XpMapperTest.java rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreClient.java (86%) rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreEndpoint.java (96%) rename runelite-client/src/main/java/net/runelite/client/{game => hiscore}/HiscoreLoader.java (90%) rename runelite-client/src/main/java/net/runelite/client/{game => hiscore}/HiscoreManager.java (93%) rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreResult.java (86%) rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreResultBuilder.java (97%) rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreSkill.java (95%) rename {http-api/src/main/java/net/runelite/http/api => runelite-client/src/main/java/net/runelite/client}/hiscore/HiscoreSkillType.java (97%) rename http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java => runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java (81%) create mode 100644 runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java diff --git a/http-api/pom.xml b/http-api/pom.xml index cbb637626e..bba80a65f8 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -58,11 +58,6 @@ lombok provided - - org.apache.commons - commons-csv - 1.4 - junit diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java deleted file mode 100644 index c2ab3407a1..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2017. l2- - * 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.http.api.hiscore; - -import java.util.Objects; - -public class SingleHiscoreSkillResult -{ - private String player; - private String skillName; - private Skill skill; - - public String getPlayer() - { - return player; - } - - public void setPlayer(String player) - { - this.player = player; - } - - public String getSkillName() - { - return skillName; - } - - public void setSkillName(String skillName) - { - this.skillName = skillName; - } - - public Skill getSkill() - { - return skill; - } - - public void setSkill(Skill skill) - { - this.skill = skill; - } - - @Override - public int hashCode() - { - int hash = 7; - hash = 37 * hash + Objects.hashCode(this.player); - hash = 37 * hash + Objects.hashCode(this.skillName); - hash = 37 * hash + Objects.hashCode(this.skill); - return hash; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final SingleHiscoreSkillResult other = (SingleHiscoreSkillResult) obj; - if (!Objects.equals(this.player, other.player)) - { - return false; - } - if (!Objects.equals(this.skillName, other.skillName)) - { - return false; - } - if (!Objects.equals(this.skill, other.skill)) - { - return false; - } - return true; - } - - @Override - public String toString() - { - return "SingleHiscoreSkillResult{" + "player=" + player + ", skillName=" + skillName + ", skill=" + skill + '}'; - } -} diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java deleted file mode 100644 index fa779381bc..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.http.api.hiscore; - -public class Skill -{ - private final int rank; - private final int level; - private final long experience; - - public Skill(int rank, int level, long experience) - { - this.rank = rank; - this.level = level; - this.experience = experience; - } - - public int getRank() - { - return rank; - } - - public int getLevel() - { - return level; - } - - public long getExperience() - { - return experience; - } - - @Override - public int hashCode() - { - int hash = 3; - hash = 59 * hash + this.rank; - hash = 59 * hash + this.level; - hash = 59 * hash + (int) (this.experience ^ (this.experience >>> 32)); - return hash; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final Skill other = (Skill) obj; - if (this.rank != other.rank) - { - return false; - } - if (this.level != other.level) - { - return false; - } - if (this.experience != other.experience) - { - return false; - } - return true; - } - - @Override - public String toString() - { - return "Skill{" + "rank=" + rank + ", level=" + level + ", experience=" + experience + '}'; - } -} diff --git a/http-api/src/main/java/net/runelite/http/api/xp/XpData.java b/http-api/src/main/java/net/runelite/http/api/xp/XpData.java deleted file mode 100644 index 348faa5c78..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/xp/XpData.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.api.xp; - -import java.time.Instant; -import lombok.Data; -import lombok.EqualsAndHashCode; - -@Data -@EqualsAndHashCode(exclude = "time") -public class XpData -{ - private Instant time; - - private int attack_xp; - private int defence_xp; - private int strength_xp; - private int hitpoints_xp; - private int ranged_xp; - private int prayer_xp; - private int magic_xp; - private int cooking_xp; - private int woodcutting_xp; - private int fletching_xp; - private int fishing_xp; - private int firemaking_xp; - private int crafting_xp; - private int smithing_xp; - private int mining_xp; - private int herblore_xp; - private int agility_xp; - private int thieving_xp; - private int slayer_xp; - private int farming_xp; - private int runecraft_xp; - private int hunter_xp; - private int construction_xp; - - private int overall_rank; - private int attack_rank; - private int defence_rank; - private int strength_rank; - private int hitpoints_rank; - private int ranged_rank; - private int prayer_rank; - private int magic_rank; - private int cooking_rank; - private int woodcutting_rank; - private int fletching_rank; - private int fishing_rank; - private int firemaking_rank; - private int crafting_rank; - private int smithing_rank; - private int mining_rank; - private int herblore_rank; - private int agility_rank; - private int thieving_rank; - private int slayer_rank; - private int farming_rank; - private int runecraft_rank; - private int hunter_rank; - private int construction_rank; -} diff --git a/http-service/pom.xml b/http-service/pom.xml index 9c34fb8984..2664f354a4 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -37,7 +37,6 @@ 1.5.6.RELEASE - 1.4.2.Final @@ -60,11 +59,6 @@ spring-jdbc - - org.mapstruct - mapstruct - ${mapstruct.version} - org.projectlombok lombok @@ -163,31 +157,6 @@ runelite-${project.version} - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - - - org.projectlombok - lombok - ${lombok.version} - - - - org.apache.maven.plugins maven-war-plugin diff --git a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java index 177561cf59..c4d46210b8 100644 --- a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java +++ b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java @@ -118,13 +118,6 @@ public class SpringBootWebApplication extends SpringBootServletInitializer return new DataSourceProperties(); } - @ConfigurationProperties(prefix = "datasource.runelite-tracker") - @Bean("dataSourceRuneLiteTracker") - public DataSourceProperties dataSourcePropertiesTracker() - { - return new DataSourceProperties(); - } - @Bean(value = "runelite", destroyMethod = "") public DataSource runeliteDataSource(@Qualifier("dataSourceRuneLite") DataSourceProperties dataSourceProperties) { @@ -137,12 +130,6 @@ public class SpringBootWebApplication extends SpringBootServletInitializer return getDataSource(dataSourceProperties); } - @Bean(value = "runelite-tracker", destroyMethod = "") - public DataSource runeliteTrackerDataSource(@Qualifier("dataSourceRuneLiteTracker") DataSourceProperties dataSourceProperties) - { - return getDataSource(dataSourceProperties); - } - @Bean("Runelite SQL2O") public Sql2o sql2o(@Qualifier("runelite") DataSource dataSource) { @@ -155,12 +142,6 @@ public class SpringBootWebApplication extends SpringBootServletInitializer return createSql2oFromDataSource(dataSource); } - @Bean("Runelite XP Tracker SQL2O") - public Sql2o trackerSql2o(@Qualifier("runelite-tracker") DataSource dataSource) - { - return createSql2oFromDataSource(dataSource); - } - @Bean(destroyMethod = "") public MongoClient mongoClient(@Value("${mongo.host:}") String host, @Value("${mongo.jndiName:}") String jndiName) throws NamingException { diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java deleted file mode 100644 index 25a89e6a8d..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.http.service.hiscore; - -import java.util.concurrent.ExecutionException; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; -import net.runelite.http.api.hiscore.Skill; -import net.runelite.http.service.util.HiscoreEndpointEditor; -import net.runelite.http.service.xp.XpTrackerService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/hiscore") -public class HiscoreController -{ - @Autowired - private HiscoreService hiscoreService; - - @Autowired - private XpTrackerService xpTrackerService; - - @GetMapping("/{endpoint}") - public HiscoreResult lookup(@PathVariable HiscoreEndpoint endpoint, @RequestParam String username) throws ExecutionException - { - HiscoreResult result = hiscoreService.lookupUsername(username, endpoint); - - // Submit to xp tracker? - switch (endpoint) - { - case NORMAL: - case IRONMAN: - case ULTIMATE_IRONMAN: - case HARDCORE_IRONMAN: - xpTrackerService.update(username, result); - } - - return result; - } - - @GetMapping("/{endpoint}/{skillName}") - public SingleHiscoreSkillResult singleSkillLookup(@PathVariable HiscoreEndpoint endpoint, @PathVariable String skillName, @RequestParam String username) throws ExecutionException - { - HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase()); - - // RS api only supports looking up all stats - HiscoreResult result = hiscoreService.lookupUsername(username, endpoint); - - // Find the skill to return - Skill requested = result.getSkill(skill); - - SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); - skillResult.setPlayer(username); - skillResult.setSkillName(skillName); - skillResult.setSkill(requested); - - return skillResult; - } - - @InitBinder - public void initBinder(WebDataBinder binder) - { - binder.registerCustomEditor(HiscoreEndpoint.class, new HiscoreEndpointEditor()); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreKey.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreKey.java deleted file mode 100644 index b15603a224..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreKey.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 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 HOLDER 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.http.service.hiscore; - -import lombok.Value; -import net.runelite.http.api.hiscore.HiscoreEndpoint; - -@Value -class HiscoreKey -{ - String username; - HiscoreEndpoint endpoint; -} diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java deleted file mode 100644 index fd73e17359..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.http.service.hiscore; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import net.runelite.http.api.RuneLiteAPI; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import okhttp3.HttpUrl; -import org.springframework.stereotype.Service; - -@Service -public class HiscoreService -{ - private final HiscoreClient hiscoreClient = new HiscoreClient(RuneLiteAPI.CLIENT); - private final LoadingCache hiscoreCache = CacheBuilder.newBuilder() - .maximumSize(128) - .expireAfterWrite(1, TimeUnit.MINUTES) - .build( - new CacheLoader() - { - @Override - public HiscoreResult load(HiscoreKey key) throws IOException - { - return hiscoreClient.lookup(key.getUsername(), key.getEndpoint()); - } - }); - - @VisibleForTesting - HiscoreResult lookupUsername(String username, HttpUrl httpUrl) throws IOException - { - return hiscoreClient.lookup(username, httpUrl); - } - - public HiscoreResult lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException - { - return hiscoreCache.get(new HiscoreKey(username, endpoint)); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/util/HiscoreEndpointEditor.java b/http-service/src/main/java/net/runelite/http/service/util/HiscoreEndpointEditor.java deleted file mode 100644 index 816981f99a..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/util/HiscoreEndpointEditor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 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 HOLDER 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.http.service.util; - -import net.runelite.http.api.hiscore.HiscoreEndpoint; - -import java.beans.PropertyEditorSupport; - -public class HiscoreEndpointEditor extends PropertyEditorSupport -{ - @Override - public void setAsText(String text) throws IllegalArgumentException - { - setValue(HiscoreEndpoint.valueOf(text.toUpperCase())); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java b/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java deleted file mode 100644 index 068c6e5438..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.service.xp; - -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.xp.XpData; -import net.runelite.http.service.xp.beans.XpEntity; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface XpMapper -{ - XpMapper INSTANCE = Mappers.getMapper(XpMapper.class); - - XpData xpEntityToXpData(XpEntity xpEntity); - - @Mapping(target = "time", ignore = true) - - @Mapping(source = "attack.experience", target = "attack_xp") - @Mapping(source = "defence.experience", target = "defence_xp") - @Mapping(source = "strength.experience", target = "strength_xp") - @Mapping(source = "hitpoints.experience", target = "hitpoints_xp") - @Mapping(source = "ranged.experience", target = "ranged_xp") - @Mapping(source = "prayer.experience", target = "prayer_xp") - @Mapping(source = "magic.experience", target = "magic_xp") - @Mapping(source = "cooking.experience", target = "cooking_xp") - @Mapping(source = "woodcutting.experience", target = "woodcutting_xp") - @Mapping(source = "fletching.experience", target = "fletching_xp") - @Mapping(source = "fishing.experience", target = "fishing_xp") - @Mapping(source = "firemaking.experience", target = "firemaking_xp") - @Mapping(source = "crafting.experience", target = "crafting_xp") - @Mapping(source = "smithing.experience", target = "smithing_xp") - @Mapping(source = "mining.experience", target = "mining_xp") - @Mapping(source = "herblore.experience", target = "herblore_xp") - @Mapping(source = "agility.experience", target = "agility_xp") - @Mapping(source = "thieving.experience", target = "thieving_xp") - @Mapping(source = "slayer.experience", target = "slayer_xp") - @Mapping(source = "farming.experience", target = "farming_xp") - @Mapping(source = "runecraft.experience", target = "runecraft_xp") - @Mapping(source = "hunter.experience", target = "hunter_xp") - @Mapping(source = "construction.experience", target = "construction_xp") - - @Mapping(source = "overall.rank", target = "overall_rank") - @Mapping(source = "attack.rank", target = "attack_rank") - @Mapping(source = "defence.rank", target = "defence_rank") - @Mapping(source = "strength.rank", target = "strength_rank") - @Mapping(source = "hitpoints.rank", target = "hitpoints_rank") - @Mapping(source = "ranged.rank", target = "ranged_rank") - @Mapping(source = "prayer.rank", target = "prayer_rank") - @Mapping(source = "magic.rank", target = "magic_rank") - @Mapping(source = "cooking.rank", target = "cooking_rank") - @Mapping(source = "woodcutting.rank", target = "woodcutting_rank") - @Mapping(source = "fletching.rank", target = "fletching_rank") - @Mapping(source = "fishing.rank", target = "fishing_rank") - @Mapping(source = "firemaking.rank", target = "firemaking_rank") - @Mapping(source = "crafting.rank", target = "crafting_rank") - @Mapping(source = "smithing.rank", target = "smithing_rank") - @Mapping(source = "mining.rank", target = "mining_rank") - @Mapping(source = "herblore.rank", target = "herblore_rank") - @Mapping(source = "agility.rank", target = "agility_rank") - @Mapping(source = "thieving.rank", target = "thieving_rank") - @Mapping(source = "slayer.rank", target = "slayer_rank") - @Mapping(source = "farming.rank", target = "farming_rank") - @Mapping(source = "runecraft.rank", target = "runecraft_rank") - @Mapping(source = "hunter.rank", target = "hunter_rank") - @Mapping(source = "construction.rank", target = "construction_rank") - XpData hiscoreResultToXpData(HiscoreResult hiscoreResult); -} diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java deleted file mode 100644 index d247d735a4..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.service.xp; - -import java.time.Instant; -import net.runelite.http.api.xp.XpData; -import net.runelite.http.service.xp.beans.XpEntity; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/xp") -public class XpTrackerController -{ - @Autowired - private XpTrackerService xpTrackerService; - - @GetMapping("/update") - public void update(@RequestParam String username) - { - xpTrackerService.tryUpdate(username); - } - - @GetMapping("/get") - public XpData get(@RequestParam String username, @RequestParam(required = false) Instant time) - { - if (time == null) - { - time = Instant.now(); - } - XpEntity xpEntity = xpTrackerService.findXpAtTime(username, time); - return XpMapper.INSTANCE.xpEntityToXpData(xpEntity); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java deleted file mode 100644 index 9e8e0a5e06..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.service.xp; - -import com.google.common.hash.BloomFilter; -import com.google.common.hash.Funnels; -import java.nio.charset.Charset; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayDeque; -import java.util.Queue; -import java.util.concurrent.ExecutionException; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.xp.XpData; -import net.runelite.http.service.hiscore.HiscoreService; -import net.runelite.http.service.xp.beans.PlayerEntity; -import net.runelite.http.service.xp.beans.XpEntity; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.sql2o.Connection; -import org.sql2o.Sql2o; - -@Service -@Slf4j -public class XpTrackerService -{ - private static final int QUEUE_LIMIT = 32768; - private static final int BLOOMFILTER_EXPECTED_INSERTIONS = 100_000; - - @Autowired - @Qualifier("Runelite XP Tracker SQL2O") - private Sql2o sql2o; - - @Autowired - private HiscoreService hiscoreService; - - private final Queue usernameUpdateQueue = new ArrayDeque<>(); - private BloomFilter usernameFilter = createFilter(); - - public void update(String username) throws ExecutionException - { - HiscoreResult hiscoreResult = hiscoreService.lookupUsername(username, HiscoreEndpoint.NORMAL); - update(username, hiscoreResult); - } - - public void tryUpdate(String username) - { - if (usernameFilter.mightContain(username)) - { - return; - } - - try (Connection con = sql2o.open()) - { - PlayerEntity playerEntity = findOrCreatePlayer(con, username); - Duration frequency = updateFrequency(playerEntity); - Instant now = Instant.now(); - Duration timeSinceLastUpdate = Duration.between(playerEntity.getLast_updated(), now); - if (timeSinceLastUpdate.toMillis() < frequency.toMillis()) - { - log.debug("User {} updated too recently", username); - usernameFilter.put(username); - return; - } - - synchronized (usernameUpdateQueue) - { - if (usernameUpdateQueue.size() >= QUEUE_LIMIT) - { - log.warn("Username update queue is full ({})", QUEUE_LIMIT); - return; - } - - usernameUpdateQueue.add(username); - } - } - - usernameFilter.put(username); - } - - public void update(String username, HiscoreResult hiscoreResult) - { - try (Connection con = sql2o.open()) - { - PlayerEntity playerEntity = findOrCreatePlayer(con, username); - - Instant now = Instant.now(); - XpEntity currentXp = findXpAtTime(con, username, now); - if (currentXp != null) - { - XpData hiscoreData = XpMapper.INSTANCE.hiscoreResultToXpData(hiscoreResult); - XpData existingData = XpMapper.INSTANCE.xpEntityToXpData(currentXp); - - if (hiscoreData.equals(existingData)) - { - log.debug("Hiscore for {} already up to date", username); - return; - } - } - - con.createQuery("insert into xp (player,attack_xp,defence_xp,strength_xp,hitpoints_xp,ranged_xp,prayer_xp,magic_xp,cooking_xp,woodcutting_xp," - + "fletching_xp,fishing_xp,firemaking_xp,crafting_xp,smithing_xp,mining_xp,herblore_xp,agility_xp,thieving_xp,slayer_xp,farming_xp," - + "runecraft_xp,hunter_xp,construction_xp,attack_rank,defence_rank,strength_rank,hitpoints_rank,ranged_rank,prayer_rank,magic_rank," - + "cooking_rank,woodcutting_rank,fletching_rank,fishing_rank,firemaking_rank,crafting_rank,smithing_rank,mining_rank,herblore_rank," - + "agility_rank,thieving_rank,slayer_rank,farming_rank,runecraft_rank,hunter_rank,construction_rank,overall_rank) values (:player,:attack_xp,:defence_xp," - + ":strength_xp,:hitpoints_xp,:ranged_xp,:prayer_xp,:magic_xp,:cooking_xp,:woodcutting_xp,:fletching_xp,:fishing_xp,:firemaking_xp," - + ":crafting_xp,:smithing_xp,:mining_xp,:herblore_xp,:agility_xp,:thieving_xp,:slayer_xp,:farming_xp,:runecraft_xp,:hunter_xp," - + ":construction_xp,:attack_rank,:defence_rank,:strength_rank,:hitpoints_rank,:ranged_rank,:prayer_rank,:magic_rank,:cooking_rank," - + ":woodcutting_rank,:fletching_rank,:fishing_rank,:firemaking_rank,:crafting_rank,:smithing_rank,:mining_rank,:herblore_rank," - + ":agility_rank,:thieving_rank,:slayer_rank,:farming_rank,:runecraft_rank,:hunter_rank,:construction_rank,:overall_rank)") - .addParameter("player", playerEntity.getId()) - .addParameter("attack_xp", hiscoreResult.getAttack().getExperience()) - .addParameter("defence_xp", hiscoreResult.getDefence().getExperience()) - .addParameter("strength_xp", hiscoreResult.getStrength().getExperience()) - .addParameter("hitpoints_xp", hiscoreResult.getHitpoints().getExperience()) - .addParameter("ranged_xp", hiscoreResult.getRanged().getExperience()) - .addParameter("prayer_xp", hiscoreResult.getPrayer().getExperience()) - .addParameter("magic_xp", hiscoreResult.getMagic().getExperience()) - .addParameter("cooking_xp", hiscoreResult.getCooking().getExperience()) - .addParameter("woodcutting_xp", hiscoreResult.getWoodcutting().getExperience()) - .addParameter("fletching_xp", hiscoreResult.getFletching().getExperience()) - .addParameter("fishing_xp", hiscoreResult.getFishing().getExperience()) - .addParameter("firemaking_xp", hiscoreResult.getFiremaking().getExperience()) - .addParameter("crafting_xp", hiscoreResult.getCrafting().getExperience()) - .addParameter("smithing_xp", hiscoreResult.getSmithing().getExperience()) - .addParameter("mining_xp", hiscoreResult.getMining().getExperience()) - .addParameter("herblore_xp", hiscoreResult.getHerblore().getExperience()) - .addParameter("agility_xp", hiscoreResult.getAgility().getExperience()) - .addParameter("thieving_xp", hiscoreResult.getThieving().getExperience()) - .addParameter("slayer_xp", hiscoreResult.getSlayer().getExperience()) - .addParameter("farming_xp", hiscoreResult.getFarming().getExperience()) - .addParameter("runecraft_xp", hiscoreResult.getRunecraft().getExperience()) - .addParameter("hunter_xp", hiscoreResult.getHunter().getExperience()) - .addParameter("construction_xp", hiscoreResult.getConstruction().getExperience()) - .addParameter("attack_rank", hiscoreResult.getAttack().getRank()) - .addParameter("defence_rank", hiscoreResult.getDefence().getRank()) - .addParameter("strength_rank", hiscoreResult.getStrength().getRank()) - .addParameter("hitpoints_rank", hiscoreResult.getHitpoints().getRank()) - .addParameter("ranged_rank", hiscoreResult.getRanged().getRank()) - .addParameter("prayer_rank", hiscoreResult.getPrayer().getRank()) - .addParameter("magic_rank", hiscoreResult.getMagic().getRank()) - .addParameter("cooking_rank", hiscoreResult.getCooking().getRank()) - .addParameter("woodcutting_rank", hiscoreResult.getWoodcutting().getRank()) - .addParameter("fletching_rank", hiscoreResult.getFletching().getRank()) - .addParameter("fishing_rank", hiscoreResult.getFishing().getRank()) - .addParameter("firemaking_rank", hiscoreResult.getFiremaking().getRank()) - .addParameter("crafting_rank", hiscoreResult.getCrafting().getRank()) - .addParameter("smithing_rank", hiscoreResult.getSmithing().getRank()) - .addParameter("mining_rank", hiscoreResult.getMining().getRank()) - .addParameter("herblore_rank", hiscoreResult.getHerblore().getRank()) - .addParameter("agility_rank", hiscoreResult.getAgility().getRank()) - .addParameter("thieving_rank", hiscoreResult.getThieving().getRank()) - .addParameter("slayer_rank", hiscoreResult.getSlayer().getRank()) - .addParameter("farming_rank", hiscoreResult.getFarming().getRank()) - .addParameter("runecraft_rank", hiscoreResult.getRunecraft().getRank()) - .addParameter("hunter_rank", hiscoreResult.getHunter().getRank()) - .addParameter("construction_rank", hiscoreResult.getConstruction().getRank()) - .addParameter("overall_rank", hiscoreResult.getOverall().getRank()) - .executeUpdate(); - - con.createQuery("update player set rank = :rank, last_updated = CURRENT_TIMESTAMP where id = :id") - .addParameter("id", playerEntity.getId()) - .addParameter("rank", hiscoreResult.getOverall().getRank()) - .executeUpdate(); - } - } - - private synchronized PlayerEntity findOrCreatePlayer(Connection con, String username) - { - PlayerEntity playerEntity = con.createQuery("select * from player where name = :name") - .addParameter("name", username) - .executeAndFetchFirst(PlayerEntity.class); - if (playerEntity != null) - { - return playerEntity; - } - - Instant now = Instant.now(); - - int id = con.createQuery("insert into player (name, tracked_since) values (:name, :tracked_since)") - .addParameter("name", username) - .addParameter("tracked_since", now) - .executeUpdate() - .getKey(int.class); - - playerEntity = new PlayerEntity(); - playerEntity.setId(id); - playerEntity.setName(username); - playerEntity.setTracked_since(now); - playerEntity.setLast_updated(now); - return playerEntity; - } - - private XpEntity findXpAtTime(Connection con, String username, Instant time) - { - return con.createQuery("select * from xp join player on player.id=xp.player where player.name = :username and time <= :time order by time desc limit 1") - .throwOnMappingFailure(false) - .addParameter("username", username) - .addParameter("time", time) - .executeAndFetchFirst(XpEntity.class); - } - - public XpEntity findXpAtTime(String username, Instant time) - { - try (Connection con = sql2o.open()) - { - return findXpAtTime(con, username, time); - } - } - - @Scheduled(fixedDelay = 1000) - public void update() throws ExecutionException - { - String next; - synchronized (usernameUpdateQueue) - { - next = usernameUpdateQueue.poll(); - } - - if (next == null) - { - return; - } - - update(next); - } - - @Scheduled(fixedDelay = 6 * 60 * 60 * 1000) // 6 hours - public void clearFilter() - { - usernameFilter = createFilter(); - } - - private BloomFilter createFilter() - { - final BloomFilter filter = BloomFilter.create( - Funnels.stringFunnel(Charset.defaultCharset()), - BLOOMFILTER_EXPECTED_INSERTIONS - ); - - synchronized (usernameUpdateQueue) - { - for (String toUpdate : usernameUpdateQueue) - { - filter.put(toUpdate); - } - } - - return filter; - } - - /** - * scale how often to check hiscore updates for players based on their rank - * @param playerEntity - * @return - */ - private static Duration updateFrequency(PlayerEntity playerEntity) - { - Integer rank = playerEntity.getRank(); - if (rank == null || rank == -1) - { - return Duration.ofDays(7); - } - else if (rank < 10_000) - { - return Duration.ofHours(6); - } - else if (rank < 50_000) - { - return Duration.ofDays(2); - } - else if (rank < 100_000) - { - return Duration.ofDays(5); - } - else - { - return Duration.ofDays(7); - } - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/xp/beans/XpEntity.java b/http-service/src/main/java/net/runelite/http/service/xp/beans/XpEntity.java deleted file mode 100644 index acab775873..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/xp/beans/XpEntity.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.service.xp.beans; - -import java.time.Instant; -import lombok.Data; - -@Data -public class XpEntity -{ - private Integer id; - private Instant time; - private Integer player; - private int overall_xp; - private int attack_xp; - private int defence_xp; - private int strength_xp; - private int hitpoints_xp; - private int ranged_xp; - private int prayer_xp; - private int magic_xp; - private int cooking_xp; - private int woodcutting_xp; - private int fletching_xp; - private int fishing_xp; - private int firemaking_xp; - private int crafting_xp; - private int smithing_xp; - private int mining_xp; - private int herblore_xp; - private int agility_xp; - private int thieving_xp; - private int slayer_xp; - private int farming_xp; - private int runecraft_xp; - private int hunter_xp; - private int construction_xp; - - private int overall_rank; - private int attack_rank; - private int defence_rank; - private int strength_rank; - private int hitpoints_rank; - private int ranged_rank; - private int prayer_rank; - private int magic_rank; - private int cooking_rank; - private int woodcutting_rank; - private int fletching_rank; - private int fishing_rank; - private int firemaking_rank; - private int crafting_rank; - private int smithing_rank; - private int mining_rank; - private int herblore_rank; - private int agility_rank; - private int thieving_rank; - private int slayer_rank; - private int farming_rank; - private int runecraft_rank; - private int hunter_rank; - private int construction_rank; -} diff --git a/http-service/src/main/resources/application-dev.yaml b/http-service/src/main/resources/application-dev.yaml index 9397951858..2b24790c51 100644 --- a/http-service/src/main/resources/application-dev.yaml +++ b/http-service/src/main/resources/application-dev.yaml @@ -18,13 +18,6 @@ datasource: url: jdbc:mariadb://localhost:3306/cache username: runelite password: runelite - runelite-tracker: - jndiName: - driverClassName: org.mariadb.jdbc.Driver - type: org.mariadb.jdbc.MariaDbDataSource - url: jdbc:mariadb://localhost:3306/xptracker - username: runelite - password: runelite # Development mongo mongo: diff --git a/http-service/src/main/resources/application.yaml b/http-service/src/main/resources/application.yaml index e573e9ae2a..9eedd33c01 100644 --- a/http-service/src/main/resources/application.yaml +++ b/http-service/src/main/resources/application.yaml @@ -3,8 +3,6 @@ datasource: jndiName: java:comp/env/jdbc/runelite runelite-cache: jndiName: java:comp/env/jdbc/runelite-cache2 - runelite-tracker: - jndiName: java:comp/env/jdbc/runelite-tracker # By default Spring tries to register the datasource as an MXBean, # so if multiple apis are deployed on one web container with diff --git a/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql b/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql deleted file mode 100644 index 70f83a30fd..0000000000 --- a/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql +++ /dev/null @@ -1,135 +0,0 @@ --- MySQL dump 10.16 Distrib 10.2.18-MariaDB, for Linux (x86_64) --- --- Host: localhost Database: xptracker --- ------------------------------------------------------ --- Server version 10.2.18-MariaDB - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `player` --- - -DROP TABLE IF EXISTS `player`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `player` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(32) NOT NULL, - `tracked_since` timestamp NOT NULL DEFAULT current_timestamp(), - `last_updated` timestamp NOT NULL DEFAULT current_timestamp(), - `rank` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `xp` --- - -DROP TABLE IF EXISTS `xp`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `xp` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `time` timestamp NOT NULL DEFAULT current_timestamp(), - `player` int(11) NOT NULL, - `attack_xp` int(11) NOT NULL, - `defence_xp` int(11) NOT NULL, - `strength_xp` int(11) NOT NULL, - `hitpoints_xp` int(11) NOT NULL, - `ranged_xp` int(11) NOT NULL, - `prayer_xp` int(11) NOT NULL, - `magic_xp` int(11) NOT NULL, - `cooking_xp` int(11) NOT NULL, - `woodcutting_xp` int(11) NOT NULL, - `fletching_xp` int(11) NOT NULL, - `fishing_xp` int(11) NOT NULL, - `firemaking_xp` int(11) NOT NULL, - `crafting_xp` int(11) NOT NULL, - `smithing_xp` int(11) NOT NULL, - `mining_xp` int(11) NOT NULL, - `herblore_xp` int(11) NOT NULL, - `agility_xp` int(11) NOT NULL, - `thieving_xp` int(11) NOT NULL, - `slayer_xp` int(11) NOT NULL, - `farming_xp` int(11) NOT NULL, - `runecraft_xp` int(11) NOT NULL, - `hunter_xp` int(11) NOT NULL, - `construction_xp` int(11) NOT NULL, - `overall_xp` int(11) GENERATED ALWAYS AS (`attack_xp` + `defence_xp` + `strength_xp` + `hitpoints_xp` + `ranged_xp` + `prayer_xp` + `magic_xp` + `cooking_xp` + `woodcutting_xp` + `fletching_xp` + `fishing_xp` + `firemaking_xp` + `crafting_xp` + `smithing_xp` + `mining_xp` + `herblore_xp` + `agility_xp` + `thieving_xp` + `slayer_xp` + `farming_xp` + `runecraft_xp` + `hunter_xp` + `construction_xp`) VIRTUAL, - `attack_level` int(11) GENERATED ALWAYS AS (level_for_xp(`attack_xp` AS `attack_xp`)) VIRTUAL, - `defence_level` int(11) GENERATED ALWAYS AS (level_for_xp(`defence_xp` AS `defence_xp`)) VIRTUAL, - `strength_level` int(11) GENERATED ALWAYS AS (level_for_xp(`strength_xp` AS `strength_xp`)) VIRTUAL, - `hitpoints_level` int(11) GENERATED ALWAYS AS (level_for_xp(`hitpoints_xp` AS `hitpoints_xp`)) VIRTUAL, - `ranged_level` int(11) GENERATED ALWAYS AS (level_for_xp(`ranged_xp` AS `ranged_xp`)) VIRTUAL, - `prayer_level` int(11) GENERATED ALWAYS AS (level_for_xp(`prayer_xp` AS `prayer_xp`)) VIRTUAL, - `magic_level` int(11) GENERATED ALWAYS AS (level_for_xp(`magic_xp` AS `magic_xp`)) VIRTUAL, - `cooking_level` int(11) GENERATED ALWAYS AS (level_for_xp(`cooking_xp` AS `cooking_xp`)) VIRTUAL, - `woodcutting_level` int(11) GENERATED ALWAYS AS (level_for_xp(`woodcutting_xp` AS `woodcutting_xp`)) VIRTUAL, - `fletching_level` int(11) GENERATED ALWAYS AS (level_for_xp(`fletching_xp` AS `fletching_xp`)) VIRTUAL, - `fishing_level` int(11) GENERATED ALWAYS AS (level_for_xp(`fishing_xp` AS `fishing_xp`)) VIRTUAL, - `firemaking_level` int(11) GENERATED ALWAYS AS (level_for_xp(`firemaking_xp` AS `firemaking_xp`)) VIRTUAL, - `crafting_level` int(11) GENERATED ALWAYS AS (level_for_xp(`crafting_xp` AS `crafting_xp`)) VIRTUAL, - `smithing_level` int(11) GENERATED ALWAYS AS (level_for_xp(`smithing_xp` AS `smithing_xp`)) VIRTUAL, - `mining_level` int(11) GENERATED ALWAYS AS (level_for_xp(`mining_xp` AS `mining_xp`)) VIRTUAL, - `herblore_level` int(11) GENERATED ALWAYS AS (level_for_xp(`herblore_xp` AS `herblore_xp`)) VIRTUAL, - `agility_level` int(11) GENERATED ALWAYS AS (level_for_xp(`agility_xp` AS `agility_xp`)) VIRTUAL, - `thieving_level` int(11) GENERATED ALWAYS AS (level_for_xp(`thieving_xp` AS `thieving_xp`)) VIRTUAL, - `slayer_level` int(11) GENERATED ALWAYS AS (level_for_xp(`slayer_xp` AS `slayer_xp`)) VIRTUAL, - `farming_level` int(11) GENERATED ALWAYS AS (level_for_xp(`farming_xp` AS `farming_xp`)) VIRTUAL, - `runecraft_level` int(11) GENERATED ALWAYS AS (level_for_xp(`runecraft_xp` AS `runecraft_xp`)) VIRTUAL, - `hunter_level` int(11) GENERATED ALWAYS AS (level_for_xp(`hunter_xp` AS `hunter_xp`)) VIRTUAL, - `construction_level` int(11) GENERATED ALWAYS AS (level_for_xp(`construction_xp` AS `construction_xp`)) VIRTUAL, - `overall_level` int(11) GENERATED ALWAYS AS (`attack_level` + `defence_level` + `strength_level` + `hitpoints_level` + `ranged_level` + `prayer_level` + `magic_level` + `cooking_level` + `woodcutting_level` + `fletching_level` + `fishing_level` + `firemaking_level` + `crafting_level` + `smithing_level` + `mining_level` + `herblore_level` + `agility_level` + `thieving_level` + `slayer_level` + `farming_level` + `runecraft_level` + `hunter_level` + `construction_level`) VIRTUAL, - `attack_rank` int(11) NOT NULL, - `defence_rank` int(11) NOT NULL, - `strength_rank` int(11) NOT NULL, - `hitpoints_rank` int(11) NOT NULL, - `ranged_rank` int(11) NOT NULL, - `prayer_rank` int(11) NOT NULL, - `magic_rank` int(11) NOT NULL, - `cooking_rank` int(11) NOT NULL, - `woodcutting_rank` int(11) NOT NULL, - `fletching_rank` int(11) NOT NULL, - `fishing_rank` int(11) NOT NULL, - `firemaking_rank` int(11) NOT NULL, - `crafting_rank` int(11) NOT NULL, - `smithing_rank` int(11) NOT NULL, - `mining_rank` int(11) NOT NULL, - `herblore_rank` int(11) NOT NULL, - `agility_rank` int(11) NOT NULL, - `thieving_rank` int(11) NOT NULL, - `slayer_rank` int(11) NOT NULL, - `farming_rank` int(11) NOT NULL, - `runecraft_rank` int(11) NOT NULL, - `hunter_rank` int(11) NOT NULL, - `construction_rank` int(11) NOT NULL, - `overall_rank` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `player_time` (`player`,`time`), - KEY `idx_time` (`time`), - CONSTRAINT `fk_player` FOREIGN KEY (`player`) REFERENCES `player` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2019-02-15 21:01:17 \ No newline at end of file diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java deleted file mode 100644 index 798116e7ee..0000000000 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.http.service.hiscore; - -import java.io.IOException; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class HiscoreServiceTest -{ - private static final String RESPONSE = "654683,705,1304518\n" - + "679419,50,107181\n" - + "550667,48,85764\n" - + "861497,50,101366\n" - + "891591,48,87843\n" - + "-1,1,4\n" - + "840255,27,10073\n" - + "1371912,10,1310\n" - + "432193,56,199795\n" - + "495638,56,198304\n" - + "514466,37,27502\n" - + "456981,54,159727\n" - + "459159,49,93010\n" - + "1028855,8,823\n" - + "862906,29,12749\n" - + "795020,31,16097\n" - + "673591,5,495\n" - + "352676,51,112259\n" - + "428419,40,37235\n" - + "461887,43,51971\n" - + "598582,1,10\n" - + "638177,1,0\n" - + "516239,9,1000\n" - + "492790,1,0\n" - + "2,2460\n" // leagues - + "-1,-1\n" - + "73,1738\n" - + "531,1432\n" - + "324,212\n" - + "8008,131\n" - + "1337,911\n" - + "42,14113\n" - + "1,777\n" - + "254,92\n" - + "-1,-1\n" // lms - + "1,241\n" // soul wars - + "24870,37\n" - + "15020,388\n" - + "50463,147\n" - + "-1,-1\n" - + "92357,1\n" - + "22758,637\n" - + "22744,107\n" - + "-1,-1\n" - + "20150,17\n" - + "29400,18\n" - + "13465,172\n" - + "1889,581\n" - + "42891,11\n" - + "1624,1957\n" - + "1243,2465\n" - + "1548,2020\n" - + "-1,-1\n" - + "16781,327\n" - + "19004,149\n" - + "-1,-1\n" - + "72046,5\n" - + "5158,374\n" - + "20902,279\n" - + "702,6495\n" - + "10170,184\n" - + "8064,202\n" - + "6936,2\n" // Mimic - + "1,4920\n" // Nex - + "2335,9\n" // Nightmare - + "2336,10\n" // Phosanis Nightmare - + "-1,-1\n" - + "-1,-1\n" - + "19779,22\n" - + "58283,10\n" - + "1234,5678\n" // Tempoross - + "-1,-1\n" - + "-1,-1\n" - + "-1,-1\n" // TOB - + "42,42\n" // TOB: Hard Mode - + "29347,130\n" - + "723,4\n" - + "1264,38\n" - + "44595,4\n" - + "24820,4\n" - + "12116,782\n" - + "2299,724\n" - + "19301,62\n" - + "1498,5847\n"; - - @Rule - public final MockWebServer server = new MockWebServer(); - - @Before - public void before() throws IOException - { - server.enqueue(new MockResponse().setBody(RESPONSE)); - } - - @Test - public void testNormalLookup() throws Exception - { - HiscoreTestService hiscores = new HiscoreTestService(server.url("/")); - - HiscoreResult result = hiscores.lookupUsername("zezima", HiscoreEndpoint.NORMAL.getHiscoreURL()); - - Assert.assertEquals(50, result.getAttack().getLevel()); - Assert.assertEquals(159727L, result.getFishing().getExperience()); - Assert.assertEquals(492790, result.getConstruction().getRank()); - Assert.assertEquals(1432, result.getClueScrollAll().getLevel()); - Assert.assertEquals(324, result.getClueScrollBeginner().getRank()); - Assert.assertEquals(8008, result.getClueScrollEasy().getRank()); - Assert.assertEquals(911, result.getClueScrollMedium().getLevel()); - Assert.assertEquals(42, result.getClueScrollHard().getRank()); - Assert.assertEquals(777, result.getClueScrollElite().getLevel()); - Assert.assertEquals(254, result.getClueScrollMaster().getRank()); - Assert.assertEquals(-1, result.getLastManStanding().getLevel()); - Assert.assertEquals(241, result.getSoulWarsZeal().getLevel()); - Assert.assertEquals(2460, result.getLeaguePoints().getLevel()); - Assert.assertEquals(37, result.getAbyssalSire().getLevel()); - Assert.assertEquals(92357, result.getCallisto().getRank()); - Assert.assertEquals(4920, result.getNex().getLevel()); - Assert.assertEquals(2336, result.getPhosanisNightmare().getRank()); - Assert.assertEquals(5678, result.getTempoross().getLevel()); - Assert.assertEquals(42, result.getTheatreOfBloodHardMode().getLevel()); - Assert.assertEquals(5847, result.getZulrah().getLevel()); - } - -} diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java deleted file mode 100644 index bdd59b077a..0000000000 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 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 HOLDER 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.http.service.hiscore; - -import java.io.IOException; -import net.runelite.http.api.hiscore.HiscoreResult; -import okhttp3.HttpUrl; - -class HiscoreTestService extends HiscoreService -{ - private final HttpUrl testUrl; - - HiscoreTestService(HttpUrl testUrl) - { - this.testUrl = testUrl; - } - - @Override - public HiscoreResult lookupUsername(String username, HttpUrl endpoint) throws IOException - { - return super.lookupUsername(username, testUrl); - } -} diff --git a/http-service/src/test/java/net/runelite/http/service/xp/XpMapperTest.java b/http-service/src/test/java/net/runelite/http/service/xp/XpMapperTest.java deleted file mode 100644 index f337cb635d..0000000000 --- a/http-service/src/test/java/net/runelite/http/service/xp/XpMapperTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.http.service.xp; - -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.Skill; -import net.runelite.http.api.xp.XpData; -import net.runelite.http.service.xp.beans.XpEntity; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class XpMapperTest -{ - @Test - public void testXpEntityToXpData() - { - XpEntity xpEntity = new XpEntity(); - xpEntity.setAgility_rank(42); - xpEntity.setAgility_xp(9001); - - XpData xpData = XpMapper.INSTANCE.xpEntityToXpData(xpEntity); - assertEquals(42, xpData.getAgility_rank()); - assertEquals(9001, xpData.getAgility_xp()); - } - - @Test - public void testHiscoreResultToXpData() - { - HiscoreResult hiscoreResult = new HiscoreResult(); - hiscoreResult.setAgility(new Skill(42, 9, 9001)); - - XpData xpData = XpMapper.INSTANCE.hiscoreResultToXpData(hiscoreResult); - assertEquals(42, xpData.getAgility_rank()); - assertEquals(9001, xpData.getAgility_xp()); - } - -} diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 9b282461bb..95b36353c8 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -110,6 +110,32 @@ commons-text 1.2 + + org.apache.commons + commons-csv + 1.4 + + + net.runelite + archive-patcher + 1.0 + + + net.java.dev.jna + jna + 5.9.0 + + + net.java.dev.jna + jna-platform + 5.9.0 + + + com.google.code.findbugs + jsr305 + + + net.runelite.jogl jogl-all @@ -174,6 +200,8 @@ 2.4.0-rc-20210117 runtime + + net.runelite.jocl jocl @@ -193,25 +221,6 @@ macos-arm64 runtime - - net.runelite - archive-patcher - 1.0 - - - net.java.dev.jna - jna - 5.9.0 - - - net.java.dev.jna - jna-platform - 5.9.0 - - - com.google.code.findbugs - jsr305 - net.runelite diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.java similarity index 86% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.java index cad7b00094..d6c2db19ea 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.java @@ -22,7 +22,7 @@ * (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.http.api.hiscore; +package net.runelite.client.hiscore; import java.io.IOException; import java.util.concurrent.CompletableFuture; @@ -64,28 +64,6 @@ public class HiscoreClient return lookup(username, HiscoreEndpoint.NORMAL); } - public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException - { - HiscoreResult result = lookupSync(username, endpoint.getHiscoreURL()); - - if (result == null) - { - return null; - } - - Skill requested = result.getSkill(skill); - SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); - skillResult.setPlayer(username); - skillResult.setSkillName(skill.getName()); - skillResult.setSkill(requested); - return skillResult; - } - - public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException - { - return lookup(username, skill, HiscoreEndpoint.NORMAL); - } - private HiscoreResult lookupSync(String username, HttpUrl hiscoreUrl) throws IOException { try (Response response = client.newCall(buildRequest(username, hiscoreUrl)).execute()) @@ -109,7 +87,7 @@ public class HiscoreClient @Override public void onResponse(Call call, Response response) throws IOException { - try + try // NOPMD: UseTryWithResources { future.complete(processResponse(username, response)); } @@ -156,9 +134,7 @@ public class HiscoreClient { CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT); - HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(); - hiscoreBuilder.setPlayer(username); - + HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(username); int count = 0; for (CSVRecord record : parser.getRecords()) diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java similarity index 96% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java index 6edfdda64b..6f1c7e8b8b 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java @@ -23,8 +23,7 @@ * 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.http.api.hiscore; +package net.runelite.client.hiscore; import lombok.Getter; import okhttp3.HttpUrl; @@ -46,6 +45,6 @@ public enum HiscoreEndpoint HiscoreEndpoint(String name, String hiscoreURL) { this.name = name; - this.hiscoreURL = HttpUrl.parse(hiscoreURL); + this.hiscoreURL = HttpUrl.get(hiscoreURL); } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.java similarity index 90% rename from runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.java index 36b6024e35..97a1b26ee0 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.java @@ -22,7 +22,7 @@ * (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.game; +package net.runelite.client.hiscore; import com.google.common.cache.CacheLoader; import com.google.common.util.concurrent.ListenableFuture; @@ -31,11 +31,8 @@ import com.google.common.util.concurrent.MoreExecutors; import java.io.IOException; import java.util.concurrent.ScheduledExecutorService; import lombok.extern.slf4j.Slf4j; -import static net.runelite.client.game.HiscoreManager.EMPTY; -import static net.runelite.client.game.HiscoreManager.NONE; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; +import static net.runelite.client.hiscore.HiscoreManager.EMPTY; +import static net.runelite.client.hiscore.HiscoreManager.NONE; @Slf4j class HiscoreLoader extends CacheLoader diff --git a/runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.java similarity index 93% rename from runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.java index 9e05b20373..cf8ef66bdd 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.java @@ -22,7 +22,7 @@ * (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.game; +package net.runelite.client.hiscore; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; @@ -33,9 +33,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.AllArgsConstructor; import lombok.Data; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; import okhttp3.OkHttpClient; @Singleton @@ -56,7 +53,7 @@ public class HiscoreManager private final HiscoreClient hiscoreClient; @Inject - public HiscoreManager(ScheduledExecutorService executor, OkHttpClient okHttpClient) + private HiscoreManager(ScheduledExecutorService executor, OkHttpClient okHttpClient) { hiscoreClient = new HiscoreClient(okHttpClient); hiscoreCache = CacheBuilder.newBuilder() diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.java similarity index 86% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.java index af6c461562..bfc6d46b6e 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.java @@ -22,7 +22,7 @@ * (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.http.api.hiscore; +package net.runelite.client.hiscore; import lombok.Data; @@ -120,77 +120,77 @@ public class HiscoreResult switch (skill) { case ATTACK: - return getAttack(); + return attack; case DEFENCE: - return getDefence(); + return defence; case STRENGTH: - return getStrength(); + return strength; case HITPOINTS: - return getHitpoints(); + return hitpoints; case RANGED: - return getRanged(); + return ranged; case PRAYER: - return getPrayer(); + return prayer; case MAGIC: - return getMagic(); + return magic; case COOKING: - return getCooking(); + return cooking; case WOODCUTTING: - return getWoodcutting(); + return woodcutting; case FLETCHING: - return getFletching(); + return fletching; case FISHING: - return getFishing(); + return fishing; case FIREMAKING: - return getFiremaking(); + return firemaking; case CRAFTING: - return getCrafting(); + return crafting; case SMITHING: - return getSmithing(); + return smithing; case MINING: - return getMining(); + return mining; case HERBLORE: - return getHerblore(); + return herblore; case AGILITY: - return getAgility(); + return agility; case THIEVING: - return getThieving(); + return thieving; case SLAYER: - return getSlayer(); + return slayer; case FARMING: - return getFarming(); + return farming; case RUNECRAFT: - return getRunecraft(); + return runecraft; case HUNTER: - return getHunter(); + return hunter; case CONSTRUCTION: - return getConstruction(); + return construction; case LEAGUE_POINTS: - return getLeaguePoints(); + return leaguePoints; case OVERALL: - return getOverall(); + return overall; case BOUNTY_HUNTER_HUNTER: - return getBountyHunterHunter(); + return bountyHunterHunter; case BOUNTY_HUNTER_ROGUE: - return getBountyHunterRogue(); + return bountyHunterRogue; case CLUE_SCROLL_ALL: - return getClueScrollAll(); + return clueScrollAll; case CLUE_SCROLL_BEGINNER: - return getClueScrollBeginner(); + return clueScrollBeginner; case CLUE_SCROLL_EASY: - return getClueScrollEasy(); + return clueScrollEasy; case CLUE_SCROLL_MEDIUM: - return getClueScrollMedium(); + return clueScrollMedium; case CLUE_SCROLL_HARD: - return getClueScrollHard(); + return clueScrollHard; case CLUE_SCROLL_ELITE: - return getClueScrollElite(); + return clueScrollElite; case CLUE_SCROLL_MASTER: - return getClueScrollMaster(); + return clueScrollMaster; case LAST_MAN_STANDING: - return getLastManStanding(); + return lastManStanding; case SOUL_WARS_ZEAL: - return getSoulWarsZeal(); + return soulWarsZeal; case ABYSSAL_SIRE: return abyssalSire; case ALCHEMICAL_HYDRA: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java similarity index 97% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java index ee8504bc8a..e5a7ec20eb 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java @@ -22,21 +22,18 @@ * (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.http.api.hiscore; +package net.runelite.client.hiscore; import java.util.ArrayList; import java.util.List; +import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor class HiscoreResultBuilder { - private String player; + private final String player; private final List skills = new ArrayList<>(); - public void setPlayer(String player) - { - this.player = player; - } - void setNextSkill(Skill skill) { skills.add(skill); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java similarity index 95% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java index 0856e9270a..6cf3dc94ca 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java @@ -22,13 +22,13 @@ * (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.http.api.hiscore; +package net.runelite.client.hiscore; import lombok.AllArgsConstructor; import lombok.Getter; -import static net.runelite.http.api.hiscore.HiscoreSkillType.SKILL; -import static net.runelite.http.api.hiscore.HiscoreSkillType.ACTIVITY; -import static net.runelite.http.api.hiscore.HiscoreSkillType.BOSS; +import static net.runelite.client.hiscore.HiscoreSkillType.SKILL; +import static net.runelite.client.hiscore.HiscoreSkillType.ACTIVITY; +import static net.runelite.client.hiscore.HiscoreSkillType.BOSS; @AllArgsConstructor @Getter diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.java similarity index 97% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.java index 67e695364b..9adc4fac0d 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.java @@ -22,7 +22,7 @@ * (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.http.api.hiscore; +package net.runelite.client.hiscore; public enum HiscoreSkillType { diff --git a/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java b/runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java similarity index 81% rename from http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java index 11bec532d7..137f8a6750 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Adam + * Copyright (c) 2021, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,17 +22,14 @@ * (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.http.service.xp.beans; +package net.runelite.client.hiscore; -import java.time.Instant; -import lombok.Data; +import lombok.Value; -@Data -public class PlayerEntity +@Value +public class Skill { - private Integer id; - private String name; - private Instant tracked_since; - private Instant last_updated; - private Integer rank; + int rank; + int level; + long experience; } 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 b15cebb7e4..4105a926a5 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 @@ -82,6 +82,11 @@ import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; import net.runelite.client.game.ItemManager; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; +import net.runelite.client.hiscore.Skill; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -90,12 +95,6 @@ import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; import net.runelite.http.api.chat.ChatClient; import net.runelite.http.api.chat.Duels; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; -import net.runelite.http.api.hiscore.Skill; import net.runelite.http.api.item.ItemPrice; import okhttp3.OkHttpClient; import org.apache.commons.text.WordUtils; @@ -1372,16 +1371,14 @@ public class ChatCommandsPlugin extends Plugin try { - final SingleHiscoreSkillResult result = hiscoreClient.lookup(lookup.getName(), skill, lookup.getEndpoint()); - + final HiscoreResult result = hiscoreClient.lookup(lookup.getName(), lookup.getEndpoint()); if (result == null) { log.warn("unable to look up skill {} for {}: not found", skill, search); return; } - final Skill hiscoreSkill = result.getSkill(); - + final Skill hiscoreSkill = result.getSkill(skill); ChatMessageBuilder chatMessageBuilder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) .append("Level ") 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 b823a57f62..8f529b7834 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 @@ -61,13 +61,13 @@ import net.runelite.client.ui.components.materialtabs.MaterialTab; import net.runelite.client.ui.components.materialtabs.MaterialTabGroup; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.QuantityFormatter; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; -import static net.runelite.http.api.hiscore.HiscoreSkill.*; -import net.runelite.http.api.hiscore.HiscoreSkillType; -import net.runelite.http.api.hiscore.Skill; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; +import static net.runelite.client.hiscore.HiscoreSkill.*; +import net.runelite.client.hiscore.HiscoreSkillType; +import net.runelite.client.hiscore.Skill; import okhttp3.OkHttpClient; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; 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 6123055d1c..8e567d37d7 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 @@ -56,7 +56,7 @@ import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreEndpoint; @PluginDescriptor( name = "HiScore", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java index 672ab50e16..48989d2d29 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java @@ -42,7 +42,7 @@ import net.runelite.api.ParamID; import net.runelite.api.Player; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.game.NPCManager; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; @@ -53,7 +53,7 @@ import net.runelite.client.ui.overlay.components.ComponentConstants; import net.runelite.client.ui.overlay.components.ProgressBarComponent; import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreResult; class OpponentInfoOverlay extends OverlayPanel { 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 330f4dfb42..855ac8953c 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 @@ -49,7 +49,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreEndpoint; @PluginDescriptor( name = "Opponent Information", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java index 840e4cae0e..03dc34f883 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java @@ -34,7 +34,7 @@ import net.runelite.api.Client; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.api.Player; import net.runelite.api.Skill; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; @@ -44,8 +44,8 @@ import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; class PlayerComparisonOverlay extends Overlay { @@ -153,7 +153,7 @@ class PlayerComparisonOverlay extends Overlay final HiscoreSkill hiscoreSkill = HISCORE_COMBAT_SKILLS[i]; final Skill skill = COMBAT_SKILLS[i]; - final net.runelite.http.api.hiscore.Skill opponentSkill = opponentSkills.getSkill(hiscoreSkill); + final net.runelite.client.hiscore.Skill opponentSkill = opponentSkills.getSkill(hiscoreSkill); if (opponentSkill == null || opponentSkill.getLevel() == -1) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java index 1cb0a21044..8572cacbe7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java @@ -58,13 +58,13 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.Skill; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.Skill; @PluginDescriptor( name = "Player-owned House", diff --git a/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java b/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java new file mode 100644 index 0000000000..fbc2e7b48f --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021, Adam + * 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.hiscore; + +import java.io.IOException; +import net.runelite.http.api.RuneLiteAPI; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class HiscoreClientTest +{ + private static final String RESPONSE = "654683,705,1304518\n" + + "679419,50,107181\n" + + "550667,48,85764\n" + + "861497,50,101366\n" + + "891591,48,87843\n" + + "-1,1,4\n" + + "840255,27,10073\n" + + "1371912,10,1310\n" + + "432193,56,199795\n" + + "495638,56,198304\n" + + "514466,37,27502\n" + + "456981,54,159727\n" + + "459159,49,93010\n" + + "1028855,8,823\n" + + "862906,29,12749\n" + + "795020,31,16097\n" + + "673591,5,495\n" + + "352676,51,112259\n" + + "428419,40,37235\n" + + "461887,43,51971\n" + + "598582,1,10\n" + + "638177,1,0\n" + + "516239,9,1000\n" + + "492790,1,0\n" + + "2,2460\n" // leagues + + "-1,-1\n" + + "73,1738\n" + + "531,1432\n" + + "324,212\n" + + "8008,131\n" + + "1337,911\n" + + "42,14113\n" + + "1,777\n" + + "254,92\n" + + "-1,-1\n" // lms + + "1,241\n" // soul wars + + "24870,37\n" + + "15020,388\n" + + "50463,147\n" + + "-1,-1\n" + + "92357,1\n" + + "22758,637\n" + + "22744,107\n" + + "-1,-1\n" + + "20150,17\n" + + "29400,18\n" + + "13465,172\n" + + "1889,581\n" + + "42891,11\n" + + "1624,1957\n" + + "1243,2465\n" + + "1548,2020\n" + + "-1,-1\n" + + "16781,327\n" + + "19004,149\n" + + "-1,-1\n" + + "72046,5\n" + + "5158,374\n" + + "20902,279\n" + + "702,6495\n" + + "10170,184\n" + + "8064,202\n" + + "6936,2\n" // Mimic + + "1,4920\n" // Nex + + "2335,9\n" // Nightmare + + "2336,10\n" // Phosanis Nightmare + + "-1,-1\n" + + "-1,-1\n" + + "19779,22\n" + + "58283,10\n" + + "1234,5678\n" // Tempoross + + "-1,-1\n" + + "-1,-1\n" + + "-1,-1\n" // TOB + + "42,42\n" // TOB: Hard Mode + + "29347,130\n" + + "723,4\n" + + "1264,38\n" + + "44595,4\n" + + "24820,4\n" + + "12116,782\n" + + "2299,724\n" + + "19301,62\n" + + "1498,5847\n"; + + @Rule + public final MockWebServer server = new MockWebServer(); + + @Before + public void before() throws IOException + { + server.enqueue(new MockResponse().setBody(RESPONSE)); + } + + @Test + public void testNormalLookup() throws Exception + { + HiscoreClient hiscoreClient = new HiscoreClient(RuneLiteAPI.CLIENT); + + HiscoreResult result = hiscoreClient.lookup("zezima", server.url("/")); + + assertEquals(50, result.getAttack().getLevel()); + assertEquals(159727L, result.getFishing().getExperience()); + assertEquals(492790, result.getConstruction().getRank()); + assertEquals(1432, result.getClueScrollAll().getLevel()); + assertEquals(324, result.getClueScrollBeginner().getRank()); + assertEquals(8008, result.getClueScrollEasy().getRank()); + assertEquals(911, result.getClueScrollMedium().getLevel()); + assertEquals(42, result.getClueScrollHard().getRank()); + assertEquals(777, result.getClueScrollElite().getLevel()); + assertEquals(254, result.getClueScrollMaster().getRank()); + assertEquals(-1, result.getLastManStanding().getLevel()); + assertEquals(241, result.getSoulWarsZeal().getLevel()); + assertEquals(2460, result.getLeaguePoints().getLevel()); + assertEquals(37, result.getAbyssalSire().getLevel()); + assertEquals(92357, result.getCallisto().getRank()); + assertEquals(4920, result.getNex().getLevel()); + assertEquals(2336, result.getPhosanisNightmare().getRank()); + assertEquals(5678, result.getTempoross().getLevel()); + assertEquals(42, result.getTheatreOfBloodHardMode().getLevel()); + assertEquals(5847, result.getZulrah().getLevel()); + } +} \ No newline at end of file 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 ab2ec35046..8ac44d3a6a 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 @@ -54,17 +54,19 @@ 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.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.Skill; import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.chat.ChatClient; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; -import net.runelite.http.api.hiscore.Skill; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; import org.mockito.Mock; import static org.mockito.Mockito.any; import static org.mockito.Mockito.atLeastOnce; @@ -545,11 +547,11 @@ public class ChatCommandsPluginTest { when(chatCommandsConfig.lvl()).thenReturn(true); - SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); - skillResult.setPlayer(PLAYER_NAME); - skillResult.setSkill(new Skill(10, 1000, -1)); + HiscoreResult hiscoreResult = new HiscoreResult(); + hiscoreResult.setPlayer(PLAYER_NAME); + hiscoreResult.setZulrah(new Skill(10, 1000, -1)); - when(hiscoreClient.lookup(PLAYER_NAME, HiscoreSkill.ZULRAH, null)).thenReturn(skillResult); + when(hiscoreClient.lookup(eq(PLAYER_NAME), nullable(HiscoreEndpoint.class))).thenReturn(hiscoreResult); MessageNode messageNode = mock(MessageNode.class); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java index 3b130c2b81..06f811a785 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java @@ -25,7 +25,7 @@ package net.runelite.client.plugins.hiscore; import static net.runelite.client.plugins.hiscore.HiscorePanel.formatLevel; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreEndpoint; import okhttp3.OkHttpClient; import static org.junit.Assert.assertEquals; import org.junit.Test; From 6b133497df9fee648b6630d3da3dcef367b23a96 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 05:39:57 +0100 Subject: [PATCH 24/42] project: Injector and mixins --- .../com/openosrs/injector/InjectUtil.java | 48 +++++-- .../java/com/openosrs/injector/Injector.java | 4 +- .../injector/injectors/RSApiInjector.java | 2 +- .../injectors/raw/CopyRuneLiteClasses.java | 5 +- .../raw/RuneLiteIterableHashTable.java | 61 --------- .../injectors/raw/RuneLiteIterables.java | 124 ++++++++++++++++++ .../com/openosrs/injector/rsapi/RSApi.java | 14 +- .../net/runelite/mixins/ClickboxMixin.java | 8 +- .../net/runelite/mixins/RSClientMixin.java | 23 +++- .../mixins/RSFriendLoginUpdatesMixin.java | 55 ++++++++ .../net/runelite/mixins/RSLinkDequeMixin.java | 51 +++++++ .../net/runelite/mixins/RSModelMixin.java | 24 ++-- .../net/runelite/mixins/RSPlayerMixin.java | 10 +- .../runelite/mixins/RuneLiteObjectMixin.java | 4 +- .../runelite/rs/api/RSFriendLoginUpdate.java | 12 +- .../net/runelite/rs/api/RSFriendSystem.java | 3 +- .../net/runelite/rs/api/RSFriendsList.java | 12 +- .../main/java/net/runelite/rs/api/RSLink.java | 14 +- .../java/net/runelite/rs/api/RSLinkDeque.java | 24 +++- .../java/net/runelite/rs/api/RSModel.java | 26 +++- .../net/runelite/rs/api/RSObjectSound.java | 3 +- .../rs/api/RSRuneLiteIterableLinkDeque.java | 4 + .../rs/api/RSRuneLiteIterableNodeDeque.java | 4 + .../runelite/rs/api/RSSequenceDefinition.java | 19 +-- runescape-client/src/main/java/Model.java | 22 ++-- runescape-client/src/main/java/NPC.java | 10 +- runescape-client/src/main/java/Player.java | 10 +- .../main/java/RuneLiteIterableLinkDeque.java | 49 +++++++ .../main/java/RuneLiteIterableNodeDeque.java | 49 +++++++ ...ava => RuneLiteIterableNodeHashTable.java} | 4 +- 30 files changed, 530 insertions(+), 168 deletions(-) delete mode 100644 injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java create mode 100644 injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java create mode 100644 runescape-client/src/main/java/RuneLiteIterableLinkDeque.java create mode 100644 runescape-client/src/main/java/RuneLiteIterableNodeDeque.java rename runescape-client/src/main/java/{RuneLiteIterableHashTable.java => RuneLiteIterableNodeHashTable.java} (89%) diff --git a/injector/src/main/java/com/openosrs/injector/InjectUtil.java b/injector/src/main/java/com/openosrs/injector/InjectUtil.java index d8c9fbd7c2..f4ff0ff3ac 100644 --- a/injector/src/main/java/com/openosrs/injector/InjectUtil.java +++ b/injector/src/main/java/com/openosrs/injector/InjectUtil.java @@ -13,6 +13,7 @@ import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE; import com.openosrs.injector.rsapi.RSApiClass; import com.openosrs.injector.rsapi.RSApiMethod; import java.util.List; +import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -340,6 +341,11 @@ public interface InjectUtil } static Type apiToDeob(InjectData data, Type api) + { + return apiToDeob(data, api, null); + } + + static Type apiToDeob(InjectData data, Type api, Type deobType) { if (api.isPrimitive()) { @@ -354,29 +360,43 @@ public interface InjectUtil else if (internalName.startsWith(RL_API_BASE)) { Class rlApiC = new Class(internalName); - RSApiClass highestKnown = data.getRsApi().withInterface(rlApiC); + Set allClasses = data.getRsApi().withInterface(rlApiC); // Cheeky unchecked exception - assert highestKnown != null : "No rs api class implements rl api class " + rlApiC.toString(); + assert allClasses.size() > 0 : "No rs api class implements rl api class " + rlApiC.toString(); - boolean changed; - do + if (allClasses.size() == 1) { - changed = false; - - for (RSApiClass interf : highestKnown.getApiInterfaces()) + RSApiClass highestKnown = allClasses.stream().findFirst().get(); + boolean changed; + do { - if (interf.getInterfaces().contains(rlApiC)) + changed = false; + + for (RSApiClass interf : highestKnown.getApiInterfaces()) { - highestKnown = interf; - changed = true; - break; + if (interf.getInterfaces().contains(rlApiC)) + { + highestKnown = interf; + changed = true; + break; + } + } + } + while (changed); + + return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions())); + } + else + { + for (RSApiClass rsApiClass : allClasses) + { + if (rsApiClass.getName().contains(deobType.getInternalName())) + { + return apiToDeob(data, Type.getType(rsApiClass.getName(), api.getDimensions())); } } } - while (changed); - - return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions())); } return api; diff --git a/injector/src/main/java/com/openosrs/injector/Injector.java b/injector/src/main/java/com/openosrs/injector/Injector.java index 5216adae21..643bd17886 100644 --- a/injector/src/main/java/com/openosrs/injector/Injector.java +++ b/injector/src/main/java/com/openosrs/injector/Injector.java @@ -23,7 +23,7 @@ import com.openosrs.injector.injectors.raw.Occluder; import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; import com.openosrs.injector.injectors.raw.CopyRuneLiteClasses; -import com.openosrs.injector.injectors.raw.RuneLiteIterableHashTable; +import com.openosrs.injector.injectors.raw.RuneLiteIterables; import com.openosrs.injector.injectors.raw.RuneliteObject; import com.openosrs.injector.injectors.raw.ScriptVM; import com.openosrs.injector.rsapi.RSApi; @@ -117,7 +117,7 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new CopyRuneLiteClasses(this)); - inject(new RuneLiteIterableHashTable(this)); + inject(new RuneLiteIterables(this)); inject(new RuneliteObject(this)); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java b/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java index c469542463..fb02f3079e 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java @@ -131,7 +131,7 @@ public class RSApiInjector extends AbstractInjector } else if (sig.size() == 0) { - Type type = InjectUtil.apiToDeob(inject, sig.getReturnValue()); + Type type = InjectUtil.apiToDeob(inject, sig.getReturnValue(), deobType); if (deobType.equals(type)) { continue; diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java index 72fdf81ea4..5875671232 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -19,6 +19,7 @@ import net.runelite.asm.Type; import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.CheckCast; import net.runelite.asm.attributes.code.instructions.GetField; import net.runelite.asm.attributes.code.instructions.GetStatic; import net.runelite.asm.attributes.code.instructions.InvokeSpecial; @@ -35,7 +36,9 @@ public class CopyRuneLiteClasses extends AbstractInjector { private static final List RUNELITE_OBJECTS = List.of( "RuneLiteObject", - "RuneLiteIterableHashTable" + "RuneLiteIterableLinkDeque", + "RuneLiteIterableNodeDeque", + "RuneLiteIterableNodeHashTable" ); public CopyRuneLiteClasses(InjectData inject) diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java deleted file mode 100644 index a8c63dd97b..0000000000 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021, Owain van Brakel - * All rights reserved. - * - * This code is licensed under GPL3, see the complete license in - * the LICENSE file in the root directory of this submodule. - */ -package com.openosrs.injector.injectors.raw; - -import com.openosrs.injector.injection.InjectData; -import com.openosrs.injector.injectors.AbstractInjector; -import java.util.List; -import net.runelite.asm.ClassFile; -import net.runelite.asm.Method; -import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.code.Instruction; -import net.runelite.asm.attributes.code.InstructionType; -import net.runelite.asm.attributes.code.Instructions; -import net.runelite.asm.attributes.code.instructions.ALoad; -import net.runelite.asm.attributes.code.instructions.Dup; -import net.runelite.asm.attributes.code.instructions.InvokeSpecial; -import net.runelite.asm.attributes.code.instructions.New; -import net.runelite.asm.attributes.code.instructions.Return; -import net.runelite.asm.signature.Signature; - -public class RuneLiteIterableHashTable extends AbstractInjector -{ - private static final String RUNELITE_ITERABLE_HASHTABLE = "RuneLiteIterableHashTable"; - - public RuneLiteIterableHashTable(InjectData inject) - { - super(inject); - } - - public void inject() - { - ClassFile runeliteIterableHashTableVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_HASHTABLE); - - final ClassFile nodeHashTableVanilla = inject.toVanilla( - inject.getDeobfuscated() - .findClass("NodeHashTable") - ); - - Method copy = new Method(nodeHashTableVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); - copy.setPublic(); - - final Code code = new Code(copy); - code.setMaxStack(3); - copy.setCode(code); - nodeHashTableVanilla.addMethod(copy); - - final Instructions instructions = code.getInstructions(); - final List ins = instructions.getInstructions(); - - ins.add(new New(instructions, runeliteIterableHashTableVanilla.getPoolClass())); - ins.add(new Dup(instructions)); - ins.add(new ALoad(instructions, 0)); - ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableHashTableVanilla.getPoolClass(), "", new Signature("(L" + nodeHashTableVanilla.getName() + ";)V")))); - ins.add(new Return(instructions, InstructionType.ARETURN)); - } -} diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java new file mode 100644 index 0000000000..42fc49f5da --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.ALoad; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneLiteIterables extends AbstractInjector +{ + private static final String RUNELITE_ITERABLE_HASHTABLE = "RuneLiteIterableNodeHashTable"; + private static final String RUNELITE_ITERABLE_NODE_DEQUE = "RuneLiteIterableNodeDeque"; + private static final String RUNELITE_ITERABLE_LINK_DEQUE = "RuneLiteIterableLinkDeque"; + + public RuneLiteIterables(InjectData inject) + { + super(inject); + } + + public void inject() + { + injectHashTable(); + injectNodeDeque(); + injectLinkDeque(); + } + + public void injectHashTable() + { + ClassFile runeliteIterableHashTableVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_HASHTABLE); + + final ClassFile nodeHashTableVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_HASHTABLE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(nodeHashTableVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + nodeHashTableVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableHashTableVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableHashTableVanilla.getPoolClass(), "", new Signature("(L" + nodeHashTableVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + public void injectNodeDeque() + { + ClassFile runeliteIterableNodeDequeVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_NODE_DEQUE); + + final ClassFile nodeDequeVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_NODE_DEQUE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(nodeDequeVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + nodeDequeVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableNodeDequeVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableNodeDequeVanilla.getPoolClass(), "", new Signature("(L" + nodeDequeVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + public void injectLinkDeque() + { + ClassFile runeliteIterableLinkDequeVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_LINK_DEQUE); + + final ClassFile linkDequeVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_LINK_DEQUE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(linkDequeVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + linkDequeVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableLinkDequeVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableLinkDequeVanilla.getPoolClass(), "", new Signature("(L" + linkDequeVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } +} diff --git a/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java b/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java index def5997c75..cbcbdf9744 100644 --- a/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java +++ b/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java @@ -15,8 +15,10 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import lombok.Getter; import lombok.NoArgsConstructor; import net.runelite.asm.Type; @@ -111,23 +113,19 @@ public class RSApi implements Iterable return findClass(name) != null; } - public RSApiClass withInterface(Class interf) + public Set withInterface(Class interf) { - RSApiClass clazz = findClass(interf.getName()); - if (clazz != null) - { - return clazz; - } + Set classes = new HashSet<>(); for (RSApiClass apiC : this) { if (apiC.getInterfaces().contains(interf)) { - return apiC; + classes.add(apiC); } } - return null; + return classes; } @NotNull diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java index 30854ef800..86e44fc473 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java @@ -59,15 +59,15 @@ public abstract class ClickboxMixin implements RSClient // otherwise we must check if the mouse is in a triangle final int vertexCount = model.getVerticesCount(); - final int triangleCount = model.getTrianglesCount(); + final int triangleCount = model.getFaceCount(); final int[] vertexX = model.getVerticesX(); final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] triangleX = model.getTrianglesX(); - final int[] triangleY = model.getTrianglesY(); - final int[] triangleZ = model.getTrianglesZ(); + final int[] triangleX = model.getFaceIndices1(); + final int[] triangleY = model.getFaceIndices2(); + final int[] triangleZ = model.getFaceIndices3(); final int[] color3 = model.getFaceColors3(); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 1885cb949f..06bea2ec7d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -39,9 +39,10 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import net.runelite.api.Animation; import net.runelite.api.ChatMessageType; import net.runelite.api.EnumComposition; -import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; import net.runelite.api.GraphicsObject; @@ -79,7 +80,6 @@ import net.runelite.api.Point; import net.runelite.api.Prayer; import net.runelite.api.Projectile; import net.runelite.api.ScriptEvent; -import net.runelite.api.Sequence; import net.runelite.api.Skill; import net.runelite.api.SpritePixels; import net.runelite.api.StructComposition; @@ -789,6 +789,15 @@ public abstract class RSClientMixin implements RSClient setChatCycle(getCycleCntr()); } + @Inject + @Override + public MenuEntry createMenuEntry(int idx) + { + // TODO: Implement this + + return new MenuEntry(); + } + @Inject @Override public MenuEntry[] getMenuEntries() @@ -887,9 +896,9 @@ public abstract class RSClientMixin implements RSClient options[oldCount] = event.getOption(); targets[oldCount] = event.getTarget(); identifiers[oldCount] = event.getIdentifier(); - opcodes[oldCount] = event.getOpcode(); - arguments1[oldCount] = event.getParam0(); - arguments2[oldCount] = event.getParam1(); + opcodes[oldCount] = event.getType(); + arguments1[oldCount] = event.getActionParam0(); + arguments2[oldCount] = event.getActionParam1(); forceLeftClick[oldCount] = event.isForceLeftClick(); } } @@ -999,7 +1008,7 @@ public abstract class RSClientMixin implements RSClient @Inject @Override - public NameableContainer getFriendContainer() + public FriendContainer getFriendContainer() { return getFriendManager().getFriendContainer(); } @@ -2427,7 +2436,7 @@ public abstract class RSClientMixin implements RSClient } @Inject - public Sequence loadAnimation(int id) + public Animation loadAnimation(int id) { return client.getSequenceDefinition(id); } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java new file mode 100644 index 0000000000..8df78b44c4 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016-2017, Adam + * 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.mixins; + +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSFriendLoginUpdate; +import net.runelite.rs.api.RSUsername; + +@Mixin(RSFriendLoginUpdate.class) +public abstract class RSFriendLoginUpdatesMixin implements RSFriendLoginUpdate +{ + @Inject + @Override + public String getName() + { + final RSUsername rsName = getRsName(); + + if (rsName == null) + { + return null; + } + + String name = rsName.getName(); + + if (name == null) + { + return null; + } + + return name.replace('\u00A0', ' '); + } +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java new file mode 100644 index 0000000000..1ab3935574 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2017, Adam + * 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.mixins; + +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSLink; +import net.runelite.rs.api.RSLinkDeque; + +@Mixin(RSLinkDeque.class) +public abstract class RSLinkDequeMixin implements RSLinkDeque +{ + @Inject + @Override + public void clear() + { + while (true) + { + RSLink rsLink = getSentinel().getPrevious(); + if (rsLink == getSentinel()) + { + setCurrent(null); + return; + } + + rsLink.remove(); + } + } +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java index f17215d244..c18e32c59d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java @@ -78,7 +78,7 @@ public abstract class RSModelMixin implements RSModel { if (getFaceTextures() != null) { - int count = getTrianglesCount(); + int count = getFaceCount(); float[] uv = new float[count * 6]; int idx = 0; @@ -91,10 +91,10 @@ public abstract class RSModelMixin implements RSModel if (modelUV != null) { - System.arraycopy(modelUV, 0, uv, idx, model.getTrianglesCount() * 6); + System.arraycopy(modelUV, 0, uv, idx, model.getFaceCount() * 6); } - idx += model.getTrianglesCount() * 6; + idx += model.getFaceCount() * 6; } } @@ -131,14 +131,14 @@ public abstract class RSModelMixin implements RSModel @Inject public List getTriangles() { - int[] trianglesX = getTrianglesX(); - int[] trianglesY = getTrianglesY(); - int[] trianglesZ = getTrianglesZ(); + int[] trianglesX = getFaceIndices1(); + int[] trianglesY = getFaceIndices2(); + int[] trianglesZ = getFaceIndices3(); List vertices = getVertices(); - List triangles = new ArrayList<>(getTrianglesCount()); + List triangles = new ArrayList<>(getFaceCount()); - for (int i = 0; i < getTrianglesCount(); ++i) + for (int i = 0; i < getFaceCount(); ++i) { int triangleX = trianglesX[i]; int triangleY = trianglesY[i]; @@ -408,14 +408,14 @@ public abstract class RSModelMixin implements RSModel rl$vertexNormalsY = new int[verticesCount]; rl$vertexNormalsZ = new int[verticesCount]; - int[] trianglesX = getTrianglesX(); - int[] trianglesY = getTrianglesY(); - int[] trianglesZ = getTrianglesZ(); + int[] trianglesX = getFaceIndices1(); + int[] trianglesY = getFaceIndices2(); + int[] trianglesZ = getFaceIndices3(); int[] verticesX = getVerticesX(); int[] verticesY = getVerticesY(); int[] verticesZ = getVerticesZ(); - for (int i = 0; i < getTrianglesCount(); ++i) + for (int i = 0; i < getFaceCount(); ++i) { int var9 = trianglesX[i]; int var10 = trianglesY[i]; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java index 2fd8f9b6a4..661f076b0c 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java @@ -181,13 +181,13 @@ public abstract class RSPlayerMixin implements RSPlayer final int tileHeight = Perspective.getTileHeight(client, new LocalPoint(localX, localY), client.getPlane()); Perspective.modelToCanvas(client, model.getVerticesCount(), localX, localY, tileHeight, getOrientation(), model.getVerticesX(), model.getVerticesZ(), model.getVerticesY(), x2d, y2d); - ArrayList polys = new ArrayList(model.getTrianglesCount()); + ArrayList polys = new ArrayList(model.getFaceCount()); - int[] trianglesX = model.getTrianglesX(); - int[] trianglesY = model.getTrianglesY(); - int[] trianglesZ = model.getTrianglesZ(); + int[] trianglesX = model.getFaceIndices1(); + int[] trianglesY = model.getFaceIndices2(); + int[] trianglesZ = model.getFaceIndices3(); - for (int triangle = 0; triangle < model.getTrianglesCount(); ++triangle) + for (int triangle = 0; triangle < model.getFaceCount(); ++triangle) { int[] xx = { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java index b4db85cf4e..788eeaf7f5 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java @@ -24,9 +24,9 @@ */ package net.runelite.mixins; +import net.runelite.api.Animation; import net.runelite.api.Model; import net.runelite.api.Perspective; -import net.runelite.api.Sequence; import net.runelite.api.coords.LocalPoint; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; @@ -55,7 +55,7 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject } @Inject - public void setAnimation(Sequence var1) + public void setAnimation(Animation var1) { setFrame(0); setFrameCycle(0); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java index b8de44e8a9..2a7721cdf3 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java @@ -1,3 +1,13 @@ package net.runelite.rs.api; -public interface RSFriendLoginUpdate {} +import net.runelite.api.PendingLogin; +import net.runelite.mapping.Import; + +public interface RSFriendLoginUpdate extends PendingLogin +{ + @Import("username") + RSUsername getRsName(); + + @Import("world") + short getWorld(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java index 87bd7ed14e..ad77d41299 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java @@ -1,11 +1,12 @@ package net.runelite.rs.api; +import net.runelite.api.FriendContainer; import net.runelite.mapping.Import; public interface RSFriendSystem { @Import("friendsList") - RSFriendsList getFriendContainer(); + FriendContainer getFriendContainer(); @Import("ignoreList") RSIgnoreList getIgnoreContainer(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java index 68eddcc8a1..25666db7ff 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java @@ -1,6 +1,12 @@ package net.runelite.rs.api; -import net.runelite.api.Friend; -import net.runelite.api.NameableContainer; +import net.runelite.api.Deque; +import net.runelite.api.FriendContainer; +import net.runelite.api.PendingLogin; +import net.runelite.mapping.Import; -public interface RSFriendsList extends NameableContainer {} +public interface RSFriendsList extends FriendContainer +{ + @Import("friendLoginUpdates") + Deque getPendingLogins(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java b/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java index 3ff6db1a48..800b172b12 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java @@ -1,3 +1,15 @@ package net.runelite.rs.api; -public interface RSLink {} +import net.runelite.mapping.Import; + +public interface RSLink +{ + @Import("previous") + RSLink getPrevious(); + + @Import("next") + RSLink next(); + + @Import("remove") + void remove(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java index b55e7e1632..8610c54b61 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java @@ -1,3 +1,25 @@ package net.runelite.rs.api; -public interface RSLinkDeque {} +import net.runelite.api.Deque; +import net.runelite.mapping.Import; + +public interface RSLinkDeque extends Deque +{ + @Import("current") + RSLink getCurrent(); + + @Import("current") + void setCurrent(RSLink link); + + @Import("sentinel") + RSLink getSentinel(); + + @Import("last") + RSLink last(); + + @Import("previous") + RSLink previous(); + + @Import("addFirst") + void addFirst(RSLink val); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java index de2835e5f2..afeacaabe9 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java @@ -48,19 +48,19 @@ public interface RSModel extends RSRenderable, Model @Import("indicesCount") @Override - int getTrianglesCount(); + int getFaceCount(); @Import("indices1") @Override - int[] getTrianglesX(); + int[] getFaceIndices1(); @Import("indices2") @Override - int[] getTrianglesY(); + int[] getFaceIndices2(); @Import("indices3") @Override - int[] getTrianglesZ(); + int[] getFaceIndices3(); @Import("faceColors1") @Override @@ -76,7 +76,7 @@ public interface RSModel extends RSRenderable, Model @Import("faceAlphas") @Override - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); @Import("faceRenderPriorities") @Override @@ -184,4 +184,20 @@ public interface RSModel extends RSRenderable, Model int[] getVertexNormalsZ(); void setVertexNormalsZ(int[] vertexNormalsZ); + + @Import("overrideAmount") + @Override + byte getOverrideAmount(); + + @Import("overrideHue") + @Override + byte getOverrideHue(); + + @Import("overrideSaturation") + @Override + byte getOverrideSaturation(); + + @Import("overrideLuminance") + @Override + byte getOverrideLuminance(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java b/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java index 3be4aba4d0..68e2aa226b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java @@ -1,8 +1,9 @@ package net.runelite.rs.api; +import net.runelite.api.AmbientSoundEffect; import net.runelite.mapping.Import; -public interface RSObjectSound +public interface RSObjectSound extends AmbientSoundEffect { @Import("x") int getX(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java new file mode 100644 index 0000000000..0d63db74fe --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableLinkDeque +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java new file mode 100644 index 0000000000..9816004c85 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableNodeDeque +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java b/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java index 8436ba4d11..79e4ef0ace 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java @@ -1,26 +1,11 @@ package net.runelite.rs.api; -import net.runelite.api.Sequence; +import net.runelite.api.Animation; import net.runelite.api.SequenceDefinition; import net.runelite.mapping.Import; -public interface RSSequenceDefinition extends RSNode, SequenceDefinition, Sequence +public interface RSSequenceDefinition extends RSNode, SequenceDefinition, Animation { -// @Import("stretches") -// boolean getStretches(); -// -// @Import("maxLoops") -// int getMaxLoops(); -// -// @Import("precedenceAnimating") --- All unused -// int getPrecedenceAnimating(); -// -// @Import("replyMode") -// int getReplyMode(); -// -// @Import("interleaveLeave") -// int[] getInterleaveLeave(); - @Import("frameCount") @Override int getFrameCount(); diff --git a/runescape-client/src/main/java/Model.java b/runescape-client/src/main/java/Model.java index 9a27115261..04d186a751 100644 --- a/runescape-client/src/main/java/Model.java +++ b/runescape-client/src/main/java/Model.java @@ -200,13 +200,17 @@ public class Model extends Renderable { @Export("zMidOffset") int zMidOffset; @ObfuscatedName("bo") - public byte field2494; + @Export("overrideHue") + public byte overrideHue; @ObfuscatedName("bf") - public byte field2495; + @Export("overrideSaturation") + public byte overrideSaturation; @ObfuscatedName("be") - public byte field2479; + @Export("overrideLuminance") + public byte overrideLuminance; @ObfuscatedName("ce") - public byte field2474; + @Export("overrideAmount") + public byte overrideAmount; static { Model_sharedSequenceModel = new Model(); @@ -574,7 +578,7 @@ public class Model extends Renderable { var2.field2449 = this.field2449; var2.isSingleTile = this.isSingleTile; var2.resetBounds(); - var2.field2474 = 0; + var2.overrideAmount = 0; return var2; } @@ -1569,10 +1573,10 @@ public class Model extends Renderable { } } else if (this.faceColors3[var1] == -1) { Rasterizer3D.method3856(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], Model_colorPalette[this.faceColors1[var1]]); - } else if (this.field2474 > 0) { - var5 = this.method4216(this.faceColors1[var1], this.field2494, this.field2495, this.field2479, this.field2474); - var6 = this.method4216(this.faceColors2[var1], this.field2494, this.field2495, this.field2479, this.field2474); - var7 = this.method4216(this.faceColors3[var1], this.field2494, this.field2495, this.field2479, this.field2474); + } else if (this.overrideAmount > 0) { + var5 = this.method4216(this.faceColors1[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); + var6 = this.method4216(this.faceColors2[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); + var7 = this.method4216(this.faceColors3[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); Rasterizer3D.method3854(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], var5, var6, var7); } else { Rasterizer3D.method3854(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], this.faceColors1[var1], this.faceColors2[var1], this.faceColors3[var1]); diff --git a/runescape-client/src/main/java/NPC.java b/runescape-client/src/main/java/NPC.java index 0507cf325a..54bc07a1b2 100644 --- a/runescape-client/src/main/java/NPC.java +++ b/runescape-client/src/main/java/NPC.java @@ -129,12 +129,12 @@ public final class NPC extends Actor { } if (super.field1146 != 0 && Client.cycle >= super.field1141 && Client.cycle < super.field1140) { - var3.field2494 = super.field1143; - var3.field2495 = super.field1144; - var3.field2479 = super.field1095; - var3.field2474 = super.field1146; + var3.overrideHue = super.field1143; + var3.overrideSaturation = super.field1144; + var3.overrideLuminance = super.field1095; + var3.overrideAmount = super.field1146; } else { - var3.field2474 = 0; + var3.overrideAmount = 0; } return var3; diff --git a/runescape-client/src/main/java/Player.java b/runescape-client/src/main/java/Player.java index 0866f9e41e..b0e15a332a 100644 --- a/runescape-client/src/main/java/Player.java +++ b/runescape-client/src/main/java/Player.java @@ -381,12 +381,12 @@ public final class Player extends Actor { var3.isSingleTile = true; if (super.field1146 != 0 && Client.cycle >= super.field1141 && Client.cycle < super.field1140) { - var3.field2494 = super.field1143; - var3.field2495 = super.field1144; - var3.field2479 = super.field1095; - var3.field2474 = super.field1146; + var3.overrideHue = super.field1143; + var3.overrideSaturation = super.field1144; + var3.overrideLuminance = super.field1095; + var3.overrideAmount = super.field1146; } else { - var3.field2474 = 0; + var3.overrideAmount = 0; } return var3; diff --git a/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java new file mode 100644 index 0000000000..2b53c7a870 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java @@ -0,0 +1,49 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RuneLiteIterableLinkDeque implements Iterator +{ + public final LinkDeque linkDeque; + public Link link; + + public RuneLiteIterableLinkDeque(LinkDeque linkDeque) + { + this.linkDeque = linkDeque; + this.link = this.linkDeque.sentinel.previous; + } + + @Override + public boolean hasNext() + { + return this.link != this.linkDeque.sentinel; + } + + @Override + public Link next() + { + if (this.link == this.linkDeque.sentinel) + { + throw new NoSuchElementException(); + } + else + { + Link friendLoginUpdate = this.link; + this.link = this.link.previous; + + return friendLoginUpdate; + } + } + + public void remove() + { + Link link = this.link.next; + if (link == this.linkDeque.sentinel) + { + throw new IllegalStateException(); + } + else + { + link.remove(); + } + } +} diff --git a/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java b/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java new file mode 100644 index 0000000000..b6bfb495e4 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java @@ -0,0 +1,49 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RuneLiteIterableNodeDeque implements Iterator +{ + public final NodeDeque nodeDeque; + public Node node; + + public RuneLiteIterableNodeDeque(NodeDeque nodeDeque) + { + this.nodeDeque = nodeDeque; + this.node = this.nodeDeque.sentinel.previous; + } + + @Override + public boolean hasNext() + { + return this.node != this.nodeDeque.sentinel; + } + + @Override + public Node next() + { + if (this.node == this.nodeDeque.sentinel) + { + throw new NoSuchElementException(); + } + else + { + Node node = this.node; + this.node = this.node.previous; + + return node; + } + } + + public void remove() + { + Node node = this.node.next; + if (node == this.nodeDeque.sentinel) + { + throw new IllegalStateException(); + } + else + { + node.remove(); + } + } +} diff --git a/runescape-client/src/main/java/RuneLiteIterableHashTable.java b/runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java similarity index 89% rename from runescape-client/src/main/java/RuneLiteIterableHashTable.java rename to runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java index ca4f181efb..5fd93eaee1 100644 --- a/runescape-client/src/main/java/RuneLiteIterableHashTable.java +++ b/runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java @@ -1,13 +1,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; -public class RuneLiteIterableHashTable implements Iterator +public class RuneLiteIterableNodeHashTable implements Iterator { public Node node; public final NodeHashTable nodeHashTable; public int it; - public RuneLiteIterableHashTable(NodeHashTable nodeHashTable) + public RuneLiteIterableNodeHashTable(NodeHashTable nodeHashTable) { this.nodeHashTable = nodeHashTable; } From 2f00f87d25b9d9cb03ddf2a2cce6fffbeedbfbb1 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 05:40:06 +0100 Subject: [PATCH 25/42] project: Bump version --- buildSrc/src/main/kotlin/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 48258f6387..89a53056a8 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -27,7 +27,7 @@ object ProjectVersions { const val launcherVersion = "2.2.0" const val rlVersion = "1.8.6" - const val openosrsVersion = "4.16.2" + const val openosrsVersion = "4.17.0" const val rsversion = 202 const val cacheversion = 165 From 0b91062e9d6c0b2f256b39d24cd0a2ac7c6b282c Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 17:15:19 +0100 Subject: [PATCH 26/42] project: Injector add CheckCast support for copy classes --- .../asm/attributes/code/instructions/CheckCast.java | 7 +++++++ .../injector/injectors/raw/CopyRuneLiteClasses.java | 6 ++++++ .../src/main/java/RuneLiteIterableLinkDeque.java | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java index 98326c0972..4fc7513a64 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java @@ -47,6 +47,13 @@ public class CheckCast extends Instruction implements TypeInstruction super(instructions, InstructionType.CHECKCAST); } + public CheckCast(Instructions instructions, Type type) + { + super(instructions, InstructionType.CHECKCAST); + + this.type = type; + } + public CheckCast(Instructions instructions, InstructionType type) { super(instructions, type); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java index 6fd1546be2..43a1c46822 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -19,6 +19,7 @@ import net.runelite.asm.Type; import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.CheckCast; import net.runelite.asm.attributes.code.instructions.GetField; import net.runelite.asm.attributes.code.instructions.GetStatic; import net.runelite.asm.attributes.code.instructions.InvokeSpecial; @@ -228,6 +229,11 @@ public class CopyRuneLiteClasses extends AbstractInjector iterator.set(new New(ins, inject.toVanilla(deobClass))); } } + else if (i instanceof CheckCast) + { + CheckCast clazz = ((CheckCast) i); + iterator.set(new CheckCast(ins, getObfuscatedSignature(clazz.getType_()))); + } } } } diff --git a/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java index 2b53c7a870..b315836771 100644 --- a/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java +++ b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java @@ -19,7 +19,7 @@ public class RuneLiteIterableLinkDeque implements Iterator } @Override - public Link next() + public FriendLoginUpdate next() { if (this.link == this.linkDeque.sentinel) { @@ -27,7 +27,7 @@ public class RuneLiteIterableLinkDeque implements Iterator } else { - Link friendLoginUpdate = this.link; + FriendLoginUpdate friendLoginUpdate = (FriendLoginUpdate) this.link; this.link = this.link.previous; return friendLoginUpdate; From 425d93ba818c7dc4f33672de4c0fadb9674d9f9c Mon Sep 17 00:00:00 2001 From: Hexagon Date: Tue, 14 Dec 2021 22:29:22 -0300 Subject: [PATCH 27/42] Remove osb related http endpoints and client --- .../api/osbuddy/OSBGrandExchangeClient.java | 75 ----------- .../api/osbuddy/OSBGrandExchangeResult.java | 38 ------ .../service/osbuddy/GrandExchangeEntry.java | 38 ------ .../osbuddy/OSBGrandExchangeController.java | 58 -------- .../osbuddy/OSBGrandExchangeService.java | 124 ------------------ .../http/service/osbuddy/OsbuddyClient.java | 72 ---------- .../osbuddy/beans/OsbuddySummaryItem.java | 39 ------ 7 files changed, 444 deletions(-) delete mode 100644 http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java delete mode 100644 http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeEntry.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/osbuddy/OsbuddyClient.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/osbuddy/beans/OsbuddySummaryItem.java diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java deleted file mode 100644 index 7bd1706cf4..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.api.osbuddy; - -import com.google.gson.JsonParseException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -@Slf4j -@AllArgsConstructor -public class OSBGrandExchangeClient -{ - private final OkHttpClient client; - - public OSBGrandExchangeResult lookupItem(int itemId) throws IOException - { - final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() - .addPathSegment("osb") - .addPathSegment("ge") - .addQueryParameter("itemId", Integer.toString(itemId)) - .build(); - - log.debug("Built URI: {}", url); - - final Request request = new Request.Builder() - .url(url) - .build(); - - try (final Response response = client.newCall(request).execute()) - { - if (!response.isSuccessful()) - { - throw new IOException("Error looking up item id: " + response); - } - - final InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), OSBGrandExchangeResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } - } -} diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java deleted file mode 100644 index 13e5f5e8e4..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.api.osbuddy; - -import java.time.Instant; -import lombok.Data; - -@Data -public class OSBGrandExchangeResult -{ - private int item_id; - private int buy_average; - private int sell_average; - private int overall_average; - private Instant last_update; -} diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeEntry.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeEntry.java deleted file mode 100644 index 8ea34c10c9..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeEntry.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.service.osbuddy; - -import java.time.Instant; -import lombok.Data; - -@Data -class GrandExchangeEntry -{ - private int item_id; - private int buy_average; - private int sell_average; - private int overall_average; - private Instant last_update; -} diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java deleted file mode 100644 index eaade27c12..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.service.osbuddy; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.CacheControl; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/osb/ge") -public class OSBGrandExchangeController -{ - private final OSBGrandExchangeService grandExchangeService; - - @Autowired - public OSBGrandExchangeController(OSBGrandExchangeService grandExchangeService) - { - this.grandExchangeService = grandExchangeService; - } - - @GetMapping - public ResponseEntity get(@RequestParam("itemId") int itemId) throws ExecutionException - { - GrandExchangeEntry grandExchangeEntry = grandExchangeService.get(itemId); - - return ResponseEntity.ok() - .cacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES).cachePublic()) - .body(grandExchangeEntry); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java deleted file mode 100644 index 49e9e4a636..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.service.osbuddy; - -import java.io.IOException; -import java.sql.Timestamp; -import java.time.Instant; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.service.osbuddy.beans.OsbuddySummaryItem; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.sql2o.Connection; -import org.sql2o.Query; -import org.sql2o.Sql2o; - -@Service -@Slf4j -public class OSBGrandExchangeService -{ - private static final String CREATE_GRAND_EXCHANGE_PRICES = "CREATE TABLE IF NOT EXISTS `osb_ge` (\n" - + " `item_id` int(11) NOT NULL,\n" - + " `buy_average` int(11) NOT NULL,\n" - + " `sell_average` int(11) NOT NULL,\n" - + " `overall_average` int(11) NOT NULL,\n" - + " `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" - + " PRIMARY KEY (`item_id`)\n" - + ") ENGINE=InnoDB"; - - private static final OsbuddyClient CLIENT = new OsbuddyClient(); - - private final Sql2o sql2o; - - @Autowired - public OSBGrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o) - { - this.sql2o = sql2o; - - try (Connection con = sql2o.open()) - { - con.createQuery(CREATE_GRAND_EXCHANGE_PRICES).executeUpdate(); - } - } - - public GrandExchangeEntry get(int itemId) - { - try (Connection con = sql2o.open()) - { - return con.createQuery("SELECT item_id, buy_average, sell_average, overall_average, last_update" - + " FROM osb_ge WHERE item_id = :itemId") - .addParameter("itemId", itemId) - .executeAndFetchFirst(GrandExchangeEntry.class); - } - } - - @Scheduled(initialDelay = 1000 * 5, fixedDelay = 1000 * 60 * 30) - private void updateDatabase() - { - try - { - Map summary = CLIENT.getSummary(); - - try (Connection con = sql2o.beginTransaction()) - { - Instant updateTime = Instant.now(); - - Query query = con.createQuery("INSERT INTO osb_ge (item_id, buy_average, sell_average, overall_average," - + " last_update) VALUES (:itemId, :buyAverage, :sellAverage, :overallAverage, :lastUpdate)" - + " ON DUPLICATE KEY UPDATE buy_average = VALUES(buy_average), sell_average = VALUES(sell_average)," - + " overall_average = VALUES(overall_average), last_update = VALUES(last_update)"); - - for (Map.Entry entry : summary.entrySet()) - { - Integer itemId = entry.getKey(); - OsbuddySummaryItem item = entry.getValue(); - - if (item.getBuy_average() <= 0 || item.getSell_average() <= 0 || item.getOverall_average() <= 0) - { - continue; - } - - query - .addParameter("itemId", itemId) - .addParameter("buyAverage", item.getBuy_average()) - .addParameter("sellAverage", item.getSell_average()) - .addParameter("overallAverage", item.getOverall_average()) - .addParameter("lastUpdate", Timestamp.from(updateTime)) - .addToBatch(); - } - - query.executeBatch(); - con.commit(false); - } - } - catch (IOException e) - { - log.warn("Error while updating the osb grand exchange table", e); - } - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/OsbuddyClient.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/OsbuddyClient.java deleted file mode 100644 index 585577511a..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/OsbuddyClient.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.service.osbuddy; - -import com.google.gson.JsonSyntaxException; -import com.google.gson.reflect.TypeToken; -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.Map; -import net.runelite.http.api.RuneLiteAPI; -import net.runelite.http.service.osbuddy.beans.OsbuddySummaryItem; -import okhttp3.HttpUrl; -import okhttp3.Request; -import okhttp3.Response; - -public class OsbuddyClient -{ - public Map getSummary() throws IOException - { - HttpUrl httpUrl = new HttpUrl.Builder() - .scheme("https") - .host("storage.googleapis.com") - .addPathSegment("osb-exchange") - .addPathSegment("summary.json") - .build(); - - Request request = new Request.Builder() - .url(httpUrl) - .header("User-Agent", "RuneLite") - .build(); - - try (Response responseOk = RuneLiteAPI.CLIENT.newCall(request).execute()) - { - if (!responseOk.isSuccessful()) - { - throw new IOException("Error retrieving summary from OSBuddy: " + responseOk.message()); - } - - Type type = new TypeToken>() - { - }.getType(); - - return RuneLiteAPI.GSON.fromJson(responseOk.body().string(), type); - } - catch (JsonSyntaxException ex) - { - throw new IOException(ex); - } - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/beans/OsbuddySummaryItem.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/beans/OsbuddySummaryItem.java deleted file mode 100644 index 2f969d9636..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/beans/OsbuddySummaryItem.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.http.service.osbuddy.beans; - -import lombok.Data; - -@Data -public class OsbuddySummaryItem -{ - private int id; - private String name; - private boolean members; - private int sp; - private int buy_average; - private int sell_average; - private int overall_average; -} From 01145a6bef217936fdf19557e3a289789357aabe Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 20:00:28 +0100 Subject: [PATCH 28/42] project: Add back MenuEntryAdded setters --- .../runelite/api/events/MenuEntryAdded.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index 745f939bfa..47c9d5227f 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -25,6 +25,7 @@ package net.runelite.api.events; import lombok.Getter; +import lombok.Setter; /** * An event when a new entry is added to a right-click menu. @@ -49,25 +50,32 @@ public class MenuEntryAdded } @Getter - private final String option; + @Setter + private String option; @Getter - private final String target; + @Setter + private String target; @Getter - private final int type; + @Setter + private int type; @Getter - private final int identifier; + @Setter + private int identifier; @Getter - private final int actionParam0; + @Setter + private int actionParam0; @Getter - private final int actionParam1; + @Setter + private int actionParam1; @Getter - private final boolean forceLeftClick; + @Setter + private boolean forceLeftClick; /** * If this is set to true client mixin will update @@ -77,6 +85,7 @@ public class MenuEntryAdded * been multiple changes */ @Getter + @Setter private boolean modified; public void setModified() From dfc6c0c2592d7a58c6bdf323f69e33847d36493d Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 20:00:41 +0100 Subject: [PATCH 29/42] project: Add back missing config features --- .../runelite/client/config/ConfigManager.java | 10 +- .../client/plugins/config/ConfigPanel.java | 367 +++++++++++++++--- 2 files changed, 315 insertions(+), 62 deletions(-) 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 d6d4e384b0..1b0e33560a 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 @@ -629,7 +629,7 @@ public class ConfigManager .collect(Collectors.toList()); final List titles = getAllDeclaredInterfaceFields(inter).stream() - .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getClass().equals(String.class)) + .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getType() == String.class) .map(m -> { try @@ -936,10 +936,6 @@ public class ConfigManager { return Base64.getUrlEncoder().encodeToString((byte[]) object); } - if (object instanceof Set) - { - return gson.toJson(object, Set.class); - } if (object instanceof EnumSet) { if (((EnumSet) object).size() == 0) @@ -949,6 +945,10 @@ public class ConfigManager return ((EnumSet) object).toArray()[0].getClass().getCanonicalName() + "{" + object.toString() + "}"; } + if (object instanceof Set) + { + return gson.toJson(object, Set.class); + } return object == null ? null : object.toString(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index c526d66379..91d97920bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -30,7 +30,6 @@ import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Sets; import com.google.common.primitives.Ints; - import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; @@ -47,7 +46,10 @@ import java.awt.event.ItemEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -55,6 +57,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import javax.inject.Inject; import javax.swing.BorderFactory; import javax.swing.BoxLayout; @@ -62,6 +65,7 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JList; @@ -71,18 +75,22 @@ import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JSeparator; +import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JTextArea; +import javax.swing.JTextField; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; +import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicSpinnerUI; import javax.swing.text.JTextComponent; import lombok.extern.slf4j.Slf4j; import net.runelite.client.config.ConfigDescriptor; @@ -117,6 +125,7 @@ import net.runelite.client.ui.components.ToggleButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker; import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.DeferredDocumentChangedListener; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; @@ -330,10 +339,10 @@ class ConfigPanel extends PluginPanel final Map sectionWidgets = new HashMap<>(); final Map titleWidgets = new HashMap<>(); final Map topLevelPanels = new TreeMap<>((a, b) -> - ComparisonChain.start() - .compare(a.position(), b.position()) - .compare(a.name(), b.name()) - .result()); + ComparisonChain.start() + .compare(a.position(), b.position()) + .compare(a.name(), b.name()) + .result()); for (ConfigSectionDescriptor csd : cd.getSections()) { @@ -350,8 +359,8 @@ class ConfigPanel extends PluginPanel // For whatever reason, the header extends out by a single pixel when closed. Adding a single pixel of // border on the right only affects the width when closed, fixing the issue. sectionHeader.setBorder(new CompoundBorder( - new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), - new EmptyBorder(0, 0, 3, 1))); + new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), + new EmptyBorder(0, 0, 3, 1))); section.add(sectionHeader, BorderLayout.NORTH); final JButton sectionToggle = new JButton(isOpen ? SECTION_RETRACT_ICON : SECTION_EXPAND_ICON); @@ -373,8 +382,8 @@ class ConfigPanel extends PluginPanel sectionContents.setLayout(new DynamicGridLayout(0, 1, 0, 5)); sectionContents.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); sectionContents.setBorder(new CompoundBorder( - new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), - new EmptyBorder(BORDER_OFFSET, 0, BORDER_OFFSET, 0))); + new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), + new EmptyBorder(BORDER_OFFSET, 0, BORDER_OFFSET, 0))); sectionContents.setVisible(isOpen); section.add(sectionContents, BorderLayout.SOUTH); @@ -474,7 +483,22 @@ class ConfigPanel extends PluginPanel } else if (cid.getType() == String.class) { - item.add(createTextField(cd, cid), BorderLayout.SOUTH); + JTextComponent textField = createTextField(cd, cid); + + if (cid.getItem().parse()) + { + JLabel parsingLabel = createParseLabel(cid, textField); + + item.add(configEntryName, BorderLayout.NORTH); + item.add(textField, BorderLayout.CENTER); + + parseLabel(cid.getItem(), parsingLabel, textField.getText()); + item.add(parsingLabel, BorderLayout.SOUTH); + } + else + { + item.add(textField, BorderLayout.SOUTH); + } } else if (cid.getType() == Color.class) { @@ -497,25 +521,33 @@ class ConfigPanel extends PluginPanel ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); if (parameterizedType.getRawType() == Set.class) { - item.add(createList(cd, cid), BorderLayout.EAST); + item.add(createList(cd, cid), BorderLayout.SOUTH); } - } - else if (cid.getType() instanceof EnumSet) - { - ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); - if (parameterizedType.getRawType() == EnumSet.class) + else if (parameterizedType.getRawType() == Consumer.class) { - item.add(createList(cd, cid), BorderLayout.EAST); + item.remove(configEntryName); + item.add(createConsumer(cd, cid), BorderLayout.CENTER); + } + else if (parameterizedType.getRawType() == EnumSet.class) + { + item.add(createEnumSetLayout(cd, cid), BorderLayout.SOUTH); } } + JPanel section = sectionWidgets.get(cid.getItem().section()); - if (section == null) + JPanel title = titleWidgets.get(cid.getItem().title()); + + if (section != null) { - topLevelPanels.put(cid, item); + section.add(item); + } + else if (title != null) + { + title.add(item); } else { - section.add(item); + topLevelPanels.put(cid, item); } } @@ -525,8 +557,8 @@ class ConfigPanel extends PluginPanel resetButton.addActionListener((e) -> { final int result = JOptionPane.showOptionDialog(resetButton, "Are you sure you want to reset this plugin's configuration?", - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result == JOptionPane.YES_OPTION) { @@ -551,6 +583,18 @@ class ConfigPanel extends PluginPanel revalidate(); } + private JButton createConsumer(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JButton button = new JButton(cid.getItem().name()); + button.addActionListener((e) -> + { + log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); + configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); + }); + + return button; + } + private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid) { JCheckBox checkbox = new ToggleButton(); @@ -560,10 +604,11 @@ class ConfigPanel extends PluginPanel return checkbox; } - private JSpinner createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + private JComponent createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) { int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + Units units = cid.getUnits(); Range range = cid.getRange(); int min = 0, max = Integer.MAX_VALUE; if (range != null) @@ -575,20 +620,122 @@ class ConfigPanel extends PluginPanel // Config may previously have been out of range value = Ints.constrainToRange(value, min, max); - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - Units units = cid.getUnits(); - if (units != null) + if (max < Integer.MAX_VALUE) { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); - } + JLabel sliderValueLabel = new JLabel(); + JSlider slider = new JSlider(min, max, value); + slider.setBackground(ColorScheme.DARK_GRAY_COLOR); + if (units != null) + { + sliderValueLabel.setText(slider.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(slider.getValue())); + } + slider.setPreferredSize(new Dimension(80, 25)); + slider.addChangeListener((l) -> + { + if (units != null) + { + sliderValueLabel.setText(slider.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(slider.getValue())); + } - return spinner; + if (!slider.getValueIsAdjusting()) + { + changeConfiguration(slider, cd, cid); + } + } + ); + + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.setUI(new BasicSpinnerUI() + { + protected Component createNextButton() + { + return null; + } + + protected Component createPreviousButton() + { + return null; + } + }); + + JPanel subPanel = new JPanel(); + subPanel.setPreferredSize(new Dimension(110, 25)); + subPanel.setLayout(new BorderLayout()); + + spinner.addChangeListener((ce) -> + { + changeConfiguration(spinner, cd, cid); + + if (units != null) + { + sliderValueLabel.setText(spinner.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(spinner.getValue())); + } + slider.setValue((Integer) spinner.getValue()); + + subPanel.add(sliderValueLabel, BorderLayout.WEST); + subPanel.add(slider, BorderLayout.EAST); + subPanel.remove(spinner); + + validate(); + repaint(); + }); + + sliderValueLabel.addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent e) + { + spinner.setValue(slider.getValue()); + + subPanel.remove(sliderValueLabel); + subPanel.remove(slider); + subPanel.add(spinner, BorderLayout.EAST); + + validate(); + repaint(); + + final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); + tf.requestFocusInWindow(); + SwingUtilities.invokeLater(tf::selectAll); + } + }); + + subPanel.add(sliderValueLabel, BorderLayout.WEST); + subPanel.add(slider, BorderLayout.EAST); + + return subPanel; + } + else + { + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + if (units != null) + { + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); + } + + return spinner; + } } private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) @@ -601,6 +748,7 @@ class ConfigPanel extends PluginPanel JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + return spinner; } @@ -635,6 +783,25 @@ class ConfigPanel extends PluginPanel return textField; } + private JLabel createParseLabel(ConfigItemDescriptor cid, JTextComponent textField) + { + JLabel parsingLabel = new JLabel(); + parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); + parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); + + DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); + listener.addChangeListener(e -> + { + if (cid.getItem().parse()) + { + parseLabel(cid.getItem(), parsingLabel, textField.getText()); + } + }); + textField.getDocument().addDocumentListener(listener); + + return parsingLabel; + } + private ColorJButton createColorPicker(ConfigDescriptor cd, ConfigItemDescriptor cid) { Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); @@ -660,10 +827,10 @@ class ConfigPanel extends PluginPanel public void mouseClicked(MouseEvent e) { RuneliteColorPicker colorPicker = colorPickerManager.create( - SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getColor(), - cid.getItem().name(), - alphaHidden); + SwingUtilities.windowForComponent(ConfigPanel.this), + colorPickerBtn.getColor(), + cid.getItem().name(), + alphaHidden); colorPicker.setLocation(getLocationOnScreen()); colorPicker.setOnColorChange(c -> { @@ -701,7 +868,7 @@ class ConfigPanel extends PluginPanel heightSpinnerTextField.setColumns(4); ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); widthSpinner.addChangeListener(listener); heightSpinner.addChangeListener(listener); @@ -751,8 +918,8 @@ class ConfigPanel extends PluginPanel private HotkeyButton createKeybind(ConfigDescriptor cd, ConfigItemDescriptor cid) { Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), - (Class) cid.getType()); + cid.getItem().keyName(), + (Class) cid.getType()); HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); @@ -796,6 +963,92 @@ class ConfigPanel extends PluginPanel return list; } + private JPanel createEnumSetLayout(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Class enumType = cid.getItem().enumClass(); + + EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), + cid.getItem().keyName(), EnumSet.class); + if (enumSet == null || enumSet.contains(null)) + { + enumSet = EnumSet.noneOf(enumType); + } + + JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); + List jcheckboxes = new ArrayList<>(); + + for (Object obj : enumType.getEnumConstants()) + { + String option = Text.titleCase((Enum) obj); + + JCheckBox checkbox = new ToggleButton(option); + checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); + checkbox.setSelected(enumSet.toString().contains(String.valueOf(obj))); + jcheckboxes.add(checkbox); + + enumsetLayout.add(checkbox); + } + + jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); + + return enumsetLayout; + } + + private Boolean parse(ConfigItem item, String value) + { + try + { + Method parse = item.clazz().getMethod(item.method(), String.class); + + return (boolean) parse.invoke(null, value); + } + catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) + { + log.error("Parsing failed: {}", ex.getMessage()); + } + + return null; + } + + private void parseLabel(ConfigItem item, JLabel label, String value) + { + Boolean result = parse(item, value); + + if (result == null) + { + label.setForeground(Color.RED); + label.setText("Parsing failed"); + } + else if (result) + { + label.setForeground(Color.GREEN); + label.setText("Valid input"); + } + else + { + label.setForeground(Color.RED); + label.setText("Invalid input"); + } + } + + private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) + { + EnumSet enumSet = EnumSet.noneOf(cid.getItem().enumClass()); + + //noinspection unchecked + components.forEach(value -> + { + if (value.isSelected()) + { + enumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); + } + }); + + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), enumSet); + + rebuild(); + } + private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid) { final ConfigItem configItem = cid.getItem(); @@ -803,8 +1056,8 @@ class ConfigPanel extends PluginPanel if (!Strings.isNullOrEmpty(configItem.warning())) { final int result = JOptionPane.showOptionDialog(component, configItem.warning(), - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result != JOptionPane.YES_OPTION) { @@ -877,7 +1130,7 @@ class ConfigPanel extends PluginPanel private void onExternalPluginsChanged(ExternalPluginsChanged ev) { if (pluginManager.getPlugins().stream() - .noneMatch(p -> p == this.pluginConfig.getPlugin())) + .noneMatch(p -> p == this.pluginConfig.getPlugin())) { pluginList.getMuxer().popState(); } @@ -914,10 +1167,10 @@ class ConfigPanel extends PluginPanel boolean show = false; List itemHide = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); for (ConfigItemDescriptor cid2 : cd.getItems()) { @@ -936,20 +1189,20 @@ class ConfigPanel extends PluginPanel if (!cid.getItem().unhideValue().equals("")) { List unhideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().unhideValue()); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().unhideValue()); show = unhideValue.contains(selectedItem.toString()); } else if (!cid.getItem().hideValue().equals("")) { List hideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().hideValue()); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().hideValue()); show = !hideValue.contains(selectedItem.toString()); } From 7ef3e6b98035e30198548aff4d3be06abcbbd82a Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 15 Dec 2021 21:26:20 +0100 Subject: [PATCH 30/42] project: Make Rl their config sets a lot less ugly and more user friendly --- .../client/plugins/config/ConfigPanel.java | 81 ++++++++++--------- .../client/ui/components/ToggleButton.java | 22 +++++ 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 91d97920bf..a2356c2676 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.config; -import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; @@ -53,11 +52,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.swing.BorderFactory; import javax.swing.BoxLayout; @@ -80,7 +82,6 @@ import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListCellRenderer; -import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; @@ -130,7 +131,6 @@ import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @Slf4j class ConfigPanel extends PluginPanel @@ -935,32 +935,31 @@ class ConfigPanel extends PluginPanel return button; } - private JList> createList(ConfigDescriptor cd, ConfigItemDescriptor cid) + private JPanel createList(ConfigDescriptor cd, ConfigItemDescriptor cid) { ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); Class type = (Class) parameterizedType.getActualTypeArguments()[0]; Set set = configManager.getConfiguration(cd.getGroup().value(), null, - cid.getItem().keyName(), parameterizedType); + cid.getItem().keyName(), parameterizedType); - JList> list = new JList>(type.getEnumConstants()); // NOPMD: UseDiamondOperator - list.setCellRenderer(listCellRenderer); - list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - list.setLayoutOrientation(JList.VERTICAL); - list.setSelectedIndices( - MoreObjects.firstNonNull(set, Collections.emptySet()) - .stream() - .mapToInt(e -> ArrayUtils.indexOf(type.getEnumConstants(), e)) - .toArray()); - list.addFocusListener(new FocusAdapter() + JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); + List jcheckboxes = new ArrayList<>(); + + Set selectedItems = new HashSet(Objects.requireNonNullElse(set, Collections.emptySet())); + + for (Object obj : type.getEnumConstants()) { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(list, cd, cid); - } - }); + ToggleButton checkbox = new ToggleButton(obj); + checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); + checkbox.setSelected(selectedItems.contains(obj)); + jcheckboxes.add(checkbox); - return list; + enumsetLayout.add(checkbox); + } + + jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); + + return enumsetLayout; } private JPanel createEnumSetLayout(ConfigDescriptor cd, ConfigItemDescriptor cid) @@ -975,13 +974,13 @@ class ConfigPanel extends PluginPanel } JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); - List jcheckboxes = new ArrayList<>(); + List jcheckboxes = new ArrayList<>(); for (Object obj : enumType.getEnumConstants()) { String option = Text.titleCase((Enum) obj); - JCheckBox checkbox = new ToggleButton(option); + ToggleButton checkbox = new ToggleButton(option); checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); checkbox.setSelected(enumSet.toString().contains(String.valueOf(obj))); jcheckboxes.add(checkbox); @@ -1031,22 +1030,32 @@ class ConfigPanel extends PluginPanel } } - private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) + private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) { - EnumSet enumSet = EnumSet.noneOf(cid.getItem().enumClass()); - - //noinspection unchecked - components.forEach(value -> + if (cid.getItem().enumClass() != Enum.class) { - if (value.isSelected()) + EnumSet enumSet = EnumSet.noneOf(cid.getItem().enumClass()); + + //noinspection unchecked + components.forEach(value -> { - enumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); - } - }); + if (value.isSelected()) + { + enumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); + } + }); - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), enumSet); - - rebuild(); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), enumSet); + } + else + { + Set values = components + .stream() + .filter(ToggleButton::isSelected) + .map(ToggleButton::getObject) + .collect(Collectors.toSet()); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), values); + } } private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java index f6a7007d26..d0c028b2ff 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java @@ -31,6 +31,7 @@ import javax.swing.JCheckBox; import net.runelite.client.ui.ColorScheme; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; +import net.runelite.client.util.Text; public class ToggleButton extends JCheckBox { @@ -38,6 +39,8 @@ public class ToggleButton extends JCheckBox private static final ImageIcon OFF_SWITCHER; private static final ImageIcon DISABLED_SWITCHER; + private final Object object; + static { BufferedImage onSwitcher = ImageUtil.loadImageResource(ToggleButton.class, "switcher_on.png"); @@ -63,6 +66,8 @@ public class ToggleButton extends JCheckBox public ToggleButton() { super(OFF_SWITCHER); + this.object = null; + setSelectedIcon(ON_SWITCHER); setDisabledIcon(DISABLED_SWITCHER); SwingUtil.removeButtonDecorations(this); @@ -71,8 +76,25 @@ public class ToggleButton extends JCheckBox public ToggleButton(String text) { super(text, OFF_SWITCHER, false); + this.object = null; + setSelectedIcon(ON_SWITCHER); setDisabledIcon(DISABLED_SWITCHER); SwingUtil.removeButtonDecorations(this); } + + public ToggleButton(Object object) + { + super(Text.titleCase((Enum) object), OFF_SWITCHER, false); + this.object = object; + + setSelectedIcon(ON_SWITCHER); + setDisabledIcon(DISABLED_SWITCHER); + SwingUtil.removeButtonDecorations(this); + } + + public Object getObject() + { + return this.object; + } } From ddd74ab31344f408eba79b4ccac324c18eb130dc Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 15 Dec 2021 17:56:25 -0700 Subject: [PATCH 31/42] Update Scripts to 2021-12-16 --- .../src/main/scripts/ChatSend.hash | 2 +- .../src/main/scripts/ChatSend.rs2asm | 137 ++++++++++-------- .../src/main/scripts/GeExamineInfoText.hash | 2 +- .../src/main/scripts/GeExamineInfoText.rs2asm | 32 +++- 4 files changed, 101 insertions(+), 72 deletions(-) diff --git a/runelite-client/src/main/scripts/ChatSend.hash b/runelite-client/src/main/scripts/ChatSend.hash index 03fd850497..1e7ae9ee97 100644 --- a/runelite-client/src/main/scripts/ChatSend.hash +++ b/runelite-client/src/main/scripts/ChatSend.hash @@ -1 +1 @@ -77B41EBBD7A825A8AC984B282115ED636C9F32A4FA777B1B58169E9C6FF103E0 \ No newline at end of file +95E7960E289ECA35DEADD35BC5A34AEBAA1C9F367AC42A71A5F3EFCCA0600D10 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatSend.rs2asm b/runelite-client/src/main/scripts/ChatSend.rs2asm index 7ce4fa5d9a..e4e8725cbf 100644 --- a/runelite-client/src/main/scripts/ChatSend.rs2asm +++ b/runelite-client/src/main/scripts/ChatSend.rs2asm @@ -30,28 +30,41 @@ LABEL16: join_string 5 mes LABEL23: - iload 3 - iconst -1 - if_icmpne LABEL27 - jump LABEL60 + invoke 5262 + iconst 0 + if_icmpeq LABEL27 + jump LABEL33 LABEL27: iload 3 iconst 4 - if_icmple LABEL31 - jump LABEL60 + if_icmpeq LABEL31 + jump LABEL33 LABEL31: + get_varc_int 945 + istore 3 +LABEL33: + iload 3 + iconst -1 + if_icmpne LABEL37 + jump LABEL70 +LABEL37: + iload 3 + iconst 4 + if_icmple LABEL41 + jump LABEL70 +LABEL41: iload 3 get_varc_int 945 - if_icmpne LABEL35 - jump LABEL60 -LABEL35: + if_icmpne LABEL45 + jump LABEL70 +LABEL45: iload 3 set_varc_int 945 iload 3 iconst 0 - if_icmpne LABEL41 - jump LABEL51 -LABEL41: + if_icmpne LABEL51 + jump LABEL61 +LABEL51: sconst "Your chatbox mode is now set to " iconst 105 iconst 115 @@ -61,8 +74,8 @@ LABEL41: sconst " chat, to reset your mode type /@p" join_string 3 mes - jump LABEL60 -LABEL51: + jump LABEL70 +LABEL61: sconst "Your chatbox mode has been reset to " iconst 105 iconst 115 @@ -72,28 +85,28 @@ LABEL51: sconst " chat." join_string 3 mes -LABEL60: +LABEL70: iload 2 iconst 1 - if_icmpeq LABEL64 - jump LABEL102 -LABEL64: + if_icmpeq LABEL74 + jump LABEL112 +LABEL74: get_varc_int 945 switch - 1: LABEL67 - 2: LABEL88 - 3: LABEL93 - 4: LABEL98 - jump LABEL102 -LABEL67: + 1: LABEL77 + 2: LABEL98 + 3: LABEL103 + 4: LABEL108 + jump LABEL112 +LABEL77: iconst 2 istore 0 sload 0 string_length iconst 0 - if_icmpgt LABEL74 - jump LABEL87 -LABEL74: + if_icmpgt LABEL84 + jump LABEL97 +LABEL84: sload 0 iconst 0 iconst 1 @@ -101,33 +114,33 @@ LABEL74: sconst "/" compare iconst 0 ; - if_icmpne LABEL83 - jump LABEL87 -LABEL83: + if_icmpne LABEL93 + jump LABEL97 +LABEL93: sconst "/" sload 0 append sstore 0 -LABEL87: - jump LABEL102 -LABEL88: +LABEL97: + jump LABEL112 +LABEL98: iconst 3 iconst 0 istore 1 istore 0 - jump LABEL102 -LABEL93: + jump LABEL112 +LABEL103: iconst 4 iconst 0 istore 1 istore 0 - jump LABEL102 -LABEL98: + jump LABEL112 +LABEL108: iconst 3 iconst 1 istore 1 istore 0 -LABEL102: +LABEL112: sload 0 ; load input iload 0 ; load chat type iload 1 ; load clan target @@ -144,31 +157,31 @@ CONTINUE: sstore 1 iload 0 iconst 2 - if_icmpeq LABEL114 + if_icmpeq LABEL124 iload 0 iconst 3 - if_icmpeq LABEL114 + if_icmpeq LABEL124 iload 0 iconst 4 - if_icmpeq LABEL114 - jump LABEL154 -LABEL114: + if_icmpeq LABEL124 + jump LABEL164 +LABEL124: sload 0 invoke 5501 iconst 1 - if_icmpeq LABEL119 - jump LABEL123 -LABEL119: + if_icmpeq LABEL129 + jump LABEL133 +LABEL129: sload 0 invoke 632 sstore 0 sstore 1 -LABEL123: +LABEL133: iload 1 iconst 1 - if_icmpeq LABEL127 - jump LABEL143 -LABEL127: + if_icmpeq LABEL137 + jump LABEL153 +LABEL137: sload 0 iconst 0 iconst 1 @@ -185,33 +198,33 @@ LABEL127: sload 0 append sstore 0 -LABEL143: +LABEL153: sload 0 string_length iconst 0 - if_icmple LABEL148 - jump LABEL149 -LABEL148: + if_icmple LABEL158 + jump LABEL159 +LABEL158: return -LABEL149: +LABEL159: sload 0 iload 0 iload 1 chat_sendclan - jump LABEL163 -LABEL154: + jump LABEL173 +LABEL164: sload 0 string_length iconst 0 - if_icmple LABEL159 - jump LABEL160 -LABEL159: + if_icmple LABEL169 + jump LABEL170 +LABEL169: return -LABEL160: +LABEL170: sload 0 iload 0 chat_sendpublic -LABEL163: +LABEL173: clientclock set_varc_int 61 return diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.hash b/runelite-client/src/main/scripts/GeExamineInfoText.hash index 162121bd78..e920ac8015 100644 --- a/runelite-client/src/main/scripts/GeExamineInfoText.hash +++ b/runelite-client/src/main/scripts/GeExamineInfoText.hash @@ -1 +1 @@ -157D0FE4248A0C0CAC825733A8DE7B0FA5A93451A9FCE3A4B1D8BFD54038B970 \ No newline at end of file +703C181C0453F22483854DC20D14FCBDE79E9DEC0400F9DB5404A7E299AA5CD8 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm index 20c53ea902..07eb5a9c1a 100644 --- a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm +++ b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm @@ -21,23 +21,39 @@ string_length iconst 0 if_icmpgt LABEL13 - jump LABEL118 + jump LABEL131 LABEL13: + iload 0 + if_getwidth + istore 2 + sload 0 + iload 2 + iconst 494 + paraheight + iconst 2 + if_icmple LABEL23 + jump LABEL30 +LABEL23: sload 0 sconst "
" sconst "
" sload 1 join_string 4 - iload 0 - if_getwidth - istore 2 sstore 2 + jump LABEL35 +LABEL30: + sload 0 + sconst "
" + sload 1 + join_string 3 + sstore 2 +LABEL35: sload 0 ; examine sload 1 ; Convenience fee sload 2 ; "<$string0>

<$string1>" sconst "geExamineText" - runelite_callback + runelite_callback sstore 2 ; final text pop_string ; Convenience fee pop_string ; examine @@ -137,8 +153,8 @@ LABEL13: sconst "Info" iload 1 if_setop - jump LABEL139 -LABEL118: + jump LABEL152 +LABEL131: sload 0 sstore 2 iconst 1 @@ -160,7 +176,7 @@ LABEL118: if_setonop iload 1 if_clearops -LABEL139: +LABEL152: sload 2 iload 0 if_settext From 8492e43ceae2e33c7a69e09432a419203d4cf5a3 Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 15 Dec 2021 17:56:25 -0700 Subject: [PATCH 32/42] Update Item IDs to 2021-12-16 --- .../main/java/net/runelite/api/ItemID.java | 68 ++++++++++++++++++- .../java/net/runelite/api/NullItemID.java | 64 +++++++++++++++++ 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index 87f575a455..45e0f6ae2f 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -12206,11 +12206,11 @@ public final class ItemID public static final int NIHIL_SHARD = 26231; public static final int ANCIENT_GODSWORD = 26233; public static final int ZARYTE_VAMBRACES = 26235; - public static final int ZARYTE_BOW_UNCHARGED = 26237; - public static final int ZARYTE_BOW = 26239; + public static final int ZARYTE_BOW = 26237; + public static final int ZARYTE_BOW_26239 = 26239; public static final int VIRTUS_MASK = 26241; public static final int VIRTUS_ROBE_TOP = 26243; - public static final int VIRTUS_ROBE_LEGS = 26245; + public static final int VIRTUS_ROBE_BOTTOMS = 26245; public static final int PUMPKIN_PIE = 26247; public static final int JEREDS_EMPTY_WINE_BOTTLE = 26250; public static final int AD_COUPON = 26252; @@ -12222,5 +12222,67 @@ public final class ItemID public static final int STUDDED_BODY_26264 = 26264; public static final int CONDENSED_GOLD = 26266; public static final int GOLD_SINK = 26269; + public static final int FESTIVE_CINNAMON = 26270; + public static final int FESTIVE_HOLLY = 26272; + public static final int FESTIVE_WHITE_WINE = 26274; + public static final int NOTES_26276 = 26276; + public static final int MAGICAL_CLEANING_POTION = 26278; + public static final int PINK_STAINED_PLATEBODY = 26280; + public static final int PINK_STAINED_PLATELEGS = 26282; + public static final int PINK_STAINED_FULL_HELM = 26284; + public static final int CLEAN_PLATEBODY = 26286; + public static final int CLEAN_PLATELEGS = 26288; + public static final int CLEAN_FULL_HELM = 26290; + public static final int FESTIVE_GINGERBREAD_GNOMES = 26292; + public static final int FESTIVE_MULLED_WINE = 26294; + public static final int SNOW = 26296; + public static final int SECRET_SANTA_PRESENT = 26298; + public static final int SECRET_SANTA_PRESENT_26300 = 26300; + public static final int SECRET_SANTA_PRESENT_26302 = 26302; + public static final int CHOCOLATE_CHIPS = 26304; + public static final int CHOCOLATE_CHIPS_26306 = 26306; + public static final int A_BIG_PRESENT = 26308; + public static final int FESTIVE_ELF_SLIPPERS = 26310; + public static final int FESTIVE_ELF_HAT = 26312; + public static final int SNOWMAN_RING = 26314; + public static final int SECRET_SANTA_PRESENT_RED = 26316; + public static final int SECRET_SANTA_PRESENT_BLUE = 26318; + public static final int SECRET_SANTA_PRESENT_GREEN = 26320; + public static final int SECRET_SANTA_PRESENT_BLACK = 26322; + public static final int SECRET_SANTA_PRESENT_GOLD = 26324; + public static final int LITTLE_SNOWBALL = 26326; + public static final int SMALL_SNOWBALL = 26328; + public static final int NORMAL_SNOWBALL = 26330; + public static final int BIG_SNOWBALL = 26332; + public static final int LARGE_SNOWBALL = 26334; + public static final int HUGE_SNOWBALL = 26336; + public static final int HUMONGOUS_SNOWBALL = 26338; + public static final int ANCIENT_BREW4 = 26340; + public static final int ANCIENT_BREW3 = 26342; + public static final int ANCIENT_BREW2 = 26344; + public static final int ANCIENT_BREW1 = 26346; + public static final int NEXLING = 26348; + public static final int ANCIENT_MIX2 = 26350; + public static final int ANCIENT_MIX1 = 26353; + public static final int FROZEN_KEY_26356 = 26356; + public static final int FROZEN_KEY_PIECE_ARMADYL = 26358; + public static final int FROZEN_KEY_PIECE_BANDOS = 26360; + public static final int FROZEN_KEY_PIECE_ZAMORAK = 26362; + public static final int FROZEN_KEY_PIECE_SARADOMIN = 26364; + public static final int IMPORTANT_LETTER = 26366; + public static final int NIHIL_DUST = 26368; + public static final int ANCIENT_HILT = 26370; + public static final int NIHIL_HORN = 26372; + public static final int ZARYTE_CROSSBOW = 26374; + public static final int TORVA_FULL_HELM_DAMAGED = 26376; + public static final int TORVA_PLATEBODY_DAMAGED = 26378; + public static final int TORVA_PLATELEGS_DAMAGED = 26380; + public static final int TORVA_FULL_HELM = 26382; + public static final int TORVA_PLATEBODY = 26384; + public static final int TORVA_PLATELEGS = 26386; + public static final int ECUMENICAL_KEY_SHARD = 26388; + public static final int BLOOD_ESSENCE = 26390; + public static final int BLOOD_ESSENCE_ACTIVE = 26392; + public static final int BANDOSIAN_COMPONENTS = 26394; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index 4ac8a346ad..3adbbe4a12 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -13837,5 +13837,69 @@ public final class NullItemID public static final int NULL_26265 = 26265; public static final int NULL_26267 = 26267; public static final int NULL_26268 = 26268; + public static final int NULL_26271 = 26271; + public static final int NULL_26273 = 26273; + public static final int NULL_26275 = 26275; + public static final int NULL_26277 = 26277; + public static final int NULL_26279 = 26279; + public static final int NULL_26281 = 26281; + public static final int NULL_26283 = 26283; + public static final int NULL_26285 = 26285; + public static final int NULL_26287 = 26287; + public static final int NULL_26289 = 26289; + public static final int NULL_26291 = 26291; + public static final int NULL_26293 = 26293; + public static final int NULL_26295 = 26295; + public static final int NULL_26297 = 26297; + public static final int NULL_26299 = 26299; + public static final int NULL_26301 = 26301; + public static final int NULL_26303 = 26303; + public static final int NULL_26305 = 26305; + public static final int NULL_26307 = 26307; + public static final int NULL_26309 = 26309; + public static final int NULL_26311 = 26311; + public static final int NULL_26313 = 26313; + public static final int NULL_26315 = 26315; + public static final int NULL_26317 = 26317; + public static final int NULL_26319 = 26319; + public static final int NULL_26321 = 26321; + public static final int NULL_26323 = 26323; + public static final int NULL_26325 = 26325; + public static final int NULL_26327 = 26327; + public static final int NULL_26329 = 26329; + public static final int NULL_26331 = 26331; + public static final int NULL_26333 = 26333; + public static final int NULL_26335 = 26335; + public static final int NULL_26337 = 26337; + public static final int NULL_26339 = 26339; + public static final int NULL_26341 = 26341; + public static final int NULL_26343 = 26343; + public static final int NULL_26345 = 26345; + public static final int NULL_26347 = 26347; + public static final int NULL_26349 = 26349; + public static final int NULL_26351 = 26351; + public static final int NULL_26352 = 26352; + public static final int NULL_26354 = 26354; + public static final int NULL_26355 = 26355; + public static final int NULL_26357 = 26357; + public static final int NULL_26359 = 26359; + public static final int NULL_26361 = 26361; + public static final int NULL_26363 = 26363; + public static final int NULL_26365 = 26365; + public static final int NULL_26367 = 26367; + public static final int NULL_26369 = 26369; + public static final int NULL_26371 = 26371; + public static final int NULL_26373 = 26373; + public static final int NULL_26375 = 26375; + public static final int NULL_26377 = 26377; + public static final int NULL_26379 = 26379; + public static final int NULL_26381 = 26381; + public static final int NULL_26383 = 26383; + public static final int NULL_26385 = 26385; + public static final int NULL_26387 = 26387; + public static final int NULL_26389 = 26389; + public static final int NULL_26391 = 26391; + public static final int NULL_26393 = 26393; + public static final int NULL_26395 = 26395; /* This file is automatically generated. Do not edit. */ } From f0ac473ba6631b8070b4ecbeb33422f419ac083f Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 15 Dec 2021 17:56:25 -0700 Subject: [PATCH 33/42] Update Item variations to 2021-12-16 --- .../src/main/resources/item_variations.json | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 083b901710..6a56701fb7 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -244,7 +244,8 @@ 20772, 21056, 21057, - 21058 + 21058, + 26276 ], "glarials urn": [ 296, @@ -3254,6 +3255,10 @@ 3739, 3740 ], + "frozen key": [ + 3741, + 26356 + ], "archer helm": [ 3749, 20572 @@ -10189,5 +10194,51 @@ "ugly halloween jumper": [ 26256, 26258 + ], + "secret santa present": [ + 26298, + 26300, + 26302, + 26316, + 26318, + 26320, + 26322, + 26324 + ], + "chocolate chips": [ + 26304, + 26306 + ], + "ancient brew": [ + 26340, + 26342, + 26344, + 26346 + ], + "ancient mix": [ + 26350, + 26353 + ], + "frozen key piece": [ + 26358, + 26360, + 26362, + 26364 + ], + "torva helm": [ + 26376, + 26382 + ], + "torva platebody": [ + 26378, + 26384 + ], + "torva platelegs": [ + 26380, + 26386 + ], + "blood essence": [ + 26390, + 26392 ] } \ No newline at end of file From 4236ae864a1a0632c304cc75d6b43d99d3ce1304 Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 15 Dec 2021 17:56:25 -0700 Subject: [PATCH 34/42] Update Object IDs to 2021-12-16 --- .../java/net/runelite/api/NullObjectID.java | 62 +++++++++++++++++++ .../main/java/net/runelite/api/ObjectID.java | 55 ++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index ac7cff6b24..ae2f7ee931 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -21006,5 +21006,67 @@ public final class NullObjectID public static final int NULL_42849 = 42849; public static final int NULL_42850 = 42850; public static final int NULL_42851 = 42851; + public static final int NULL_42873 = 42873; + public static final int NULL_42874 = 42874; + public static final int NULL_42875 = 42875; + public static final int NULL_42876 = 42876; + public static final int NULL_42877 = 42877; + public static final int NULL_42882 = 42882; + public static final int NULL_42883 = 42883; + public static final int NULL_42884 = 42884; + public static final int NULL_42893 = 42893; + public static final int NULL_42894 = 42894; + public static final int NULL_42896 = 42896; + public static final int NULL_42897 = 42897; + public static final int NULL_42898 = 42898; + public static final int NULL_42899 = 42899; + public static final int NULL_42900 = 42900; + public static final int NULL_42901 = 42901; + public static final int NULL_42902 = 42902; + public static final int NULL_42903 = 42903; + public static final int NULL_42904 = 42904; + public static final int NULL_42905 = 42905; + public static final int NULL_42906 = 42906; + public static final int NULL_42909 = 42909; + public static final int NULL_42910 = 42910; + public static final int NULL_42911 = 42911; + public static final int NULL_42912 = 42912; + public static final int NULL_42913 = 42913; + public static final int NULL_42914 = 42914; + public static final int NULL_42915 = 42915; + public static final int NULL_42916 = 42916; + public static final int NULL_42917 = 42917; + public static final int NULL_42918 = 42918; + public static final int NULL_42919 = 42919; + public static final int NULL_42920 = 42920; + public static final int NULL_42921 = 42921; + public static final int NULL_42922 = 42922; + public static final int NULL_42923 = 42923; + public static final int NULL_42924 = 42924; + public static final int NULL_42925 = 42925; + public static final int NULL_42926 = 42926; + public static final int NULL_42927 = 42927; + public static final int NULL_42945 = 42945; + public static final int NULL_42946 = 42946; + public static final int NULL_42947 = 42947; + public static final int NULL_42948 = 42948; + public static final int NULL_42949 = 42949; + public static final int NULL_42950 = 42950; + public static final int NULL_42951 = 42951; + public static final int NULL_42952 = 42952; + public static final int NULL_42953 = 42953; + public static final int NULL_42954 = 42954; + public static final int NULL_42955 = 42955; + public static final int NULL_42956 = 42956; + public static final int NULL_42957 = 42957; + public static final int NULL_42958 = 42958; + public static final int NULL_42959 = 42959; + public static final int NULL_42960 = 42960; + public static final int NULL_42961 = 42961; + public static final int NULL_42962 = 42962; + public static final int NULL_42963 = 42963; + public static final int NULL_42964 = 42964; + public static final int NULL_42967 = 42967; + public static final int NULL_42968 = 42968; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 832f553d9a..016f9487e5 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -21832,5 +21832,60 @@ public final class ObjectID public static final int FROZEN_DOOR = 42840; public static final int FROZEN_DOOR_42841 = 42841; public static final int GOLD_SINK_42852 = 42852; + public static final int SIGN_42853 = 42853; + public static final int SCUFFED_SNOW = 42854; + public static final int SNOWMAN = 42855; + public static final int SNOWMAN_42856 = 42856; + public static final int SNOWMAN_42857 = 42857; + public static final int SNOWMAN_42858 = 42858; + public static final int SNOWMAN_42859 = 42859; + public static final int SNOWMAN_42860 = 42860; + public static final int SNOWMAN_42861 = 42861; + public static final int SNOWMAN_42862 = 42862; + public static final int SNOWMAN_42863 = 42863; + public static final int SNOWMAN_42864 = 42864; + public static final int SPADE_42865 = 42865; + public static final int PILE_OF_SNOW = 42866; + public static final int BUSH_42867 = 42867; + public static final int PILE_OF_SNOW_42868 = 42868; + public static final int PILE_OF_SNOW_42869 = 42869; + public static final int CHRISTMAS_TREE = 42870; + public static final int CHRISTMAS_TREE_42871 = 42871; + public static final int CHRISTMAS_TREE_42872 = 42872; + public static final int PRESENTS = 42878; + public static final int PRESENTS_42879 = 42879; + public static final int PRESENTS_42880 = 42880; + public static final int PRESENTS_42881 = 42881; + public static final int POTTED_TREE = 42885; + public static final int POTTED_TREE_42886 = 42886; + public static final int MARKET_STALL_42887 = 42887; + public static final int MARKET_STALL_42888 = 42888; + public static final int MARKET_STALL_42889 = 42889; + public static final int MARKET_STALL_42890 = 42890; + public static final int MARKET_STALL_42891 = 42891; + public static final int MARKET_STALL_42892 = 42892; + public static final int ROBIN = 42895; + public static final int DEAD_TREE_42907 = 42907; + public static final int DEAD_OAK_42908 = 42908; + public static final int SANTAS_SLEIGH = 42928; + public static final int SANTAS_THRONE = 42929; + public static final int SANTAS_SACK = 42930; + public static final int FROZEN_DOOR_42931 = 42931; + public static final int FROZEN_DOOR_42932 = 42932; + public static final int DOOR_42933 = 42933; + public static final int DOOR_42934 = 42934; + public static final int ANCIENT_PLAQUE = 42935; + public static final int SCOREBOARD_42936 = 42936; + public static final int ANCIENT_BARRIER = 42937; + public static final int ANCIENT_BARRIER_42938 = 42938; + public static final int ANCIENT_BARRIER_42939 = 42939; + public static final int ANCIENT_BARRIER_42940 = 42940; + public static final int ANCIENT_BARRIER_42941 = 42941; + public static final int SHADOW = 42942; + public static final int STALAGMITE_42943 = 42943; + public static final int STALAGMITE_42944 = 42944; + public static final int ALTAR_42965 = 42965; + public static final int ANCIENT_FORGE = 42966; + public static final int BROKEN_CROSSBOW_42969 = 42969; /* This file is automatically generated. Do not edit. */ } From a8aae62c57d79147568a4391a71738656f41ec8a Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 15 Dec 2021 17:56:25 -0700 Subject: [PATCH 35/42] Update NPC IDs to 2021-12-16 --- .../src/main/java/net/runelite/api/NpcID.java | 44 +++++++++++++++++++ .../main/java/net/runelite/api/NullNpcID.java | 20 +++++++++ 2 files changed, 64 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index d07ffdbd55..cd8c383e63 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -9477,5 +9477,49 @@ public final class NpcID public static final int REGENT = 11229; public static final int GROUP_STORAGE_TUTOR = 11230; public static final int GROUP_IRON_TUTOR = 11231; + public static final int TINY_SNOWBALL = 11232; + public static final int MINI_SNOWBALL = 11233; + public static final int LITTLE_SNOWBALL = 11234; + public static final int SMALL_SNOWBALL = 11235; + public static final int NORMAL_SNOWBALL = 11236; + public static final int BIG_SNOWBALL = 11237; + public static final int LARGE_SNOWBALL = 11238; + public static final int HUGE_SNOWBALL = 11239; + public static final int HUMONGOUS_SNOWBALL = 11240; + public static final int BUOY = 11241; + public static final int GURL = 11242; + public static final int BUOY_11243 = 11243; + public static final int GURL_11244 = 11244; + public static final int HERQUIN_11245 = 11245; + public static final int CECILIA_11247 = 11247; + public static final int LARRY_11248 = 11248; + public static final int SANTAS_THRONE = 11249; + public static final int SANTA = 11250; + public static final int WAYNE_11251 = 11251; + public static final int WYSON_THE_GARDENER_11252 = 11252; + public static final int HAIRDRESSER_11254 = 11254; + public static final int SIR_VYVIN_11255 = 11255; + public static final int XI_PLZPETDOGZ_XIX = 11259; + public static final int DRAKE_11260 = 11260; + public static final int DUCK_11261 = 11261; + public static final int NEXLING = 11276; + public static final int NEXLING_11277 = 11277; + public static final int NEX = 11278; + public static final int NEX_11279 = 11279; + public static final int NEX_11280 = 11280; + public static final int NEX_11281 = 11281; + public static final int NEX_11282 = 11282; + public static final int FUMUS = 11283; + public static final int UMBRA = 11284; + public static final int CRUOR = 11285; + public static final int GLACIES = 11286; + public static final int MESSENGER = 11287; + public static final int ASHUELOT_REIS = 11288; + public static final int ASHUELOT_REIS_11289 = 11289; + public static final int SPIRITUAL_WARRIOR_11290 = 11290; + public static final int SPIRITUAL_RANGER_11291 = 11291; + public static final int SPIRITUAL_MAGE_11292 = 11292; + public static final int BLOOD_REAVER = 11293; + public static final int BLOOD_REAVER_11294 = 11294; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 757da4d4a1..73396db288 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -1738,6 +1738,26 @@ public final class NullNpcID public static final int NULL_11222 = 11222; public static final int NULL_11223 = 11223; public static final int NULL_11224 = 11224; + public static final int NULL_11246 = 11246; public static final int NULL_11253 = 11253; + public static final int NULL_11256 = 11256; + public static final int NULL_11257 = 11257; + public static final int NULL_11258 = 11258; + public static final int NULL_11262 = 11262; + public static final int NULL_11263 = 11263; + public static final int NULL_11264 = 11264; + public static final int NULL_11265 = 11265; + public static final int NULL_11266 = 11266; + public static final int NULL_11267 = 11267; + public static final int NULL_11268 = 11268; + public static final int NULL_11269 = 11269; + public static final int NULL_11270 = 11270; + public static final int NULL_11271 = 11271; + public static final int NULL_11272 = 11272; + public static final int NULL_11273 = 11273; + public static final int NULL_11274 = 11274; + public static final int NULL_11275 = 11275; + public static final int NULL_11295 = 11295; + public static final int NULL_11296 = 11296; /* This file is automatically generated. Do not edit. */ } From a79b73c9b0c9936b22049d8a0d86f85fe3356629 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 15 Dec 2021 18:54:03 -0700 Subject: [PATCH 36/42] rl-client: add timestamp script --- .../src/main/scripts/ChatTimestamp.hash | 1 + .../src/main/scripts/ChatTimestamp.rs2asm | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 runelite-client/src/main/scripts/ChatTimestamp.hash create mode 100644 runelite-client/src/main/scripts/ChatTimestamp.rs2asm diff --git a/runelite-client/src/main/scripts/ChatTimestamp.hash b/runelite-client/src/main/scripts/ChatTimestamp.hash new file mode 100644 index 0000000000..0fca71cb43 --- /dev/null +++ b/runelite-client/src/main/scripts/ChatTimestamp.hash @@ -0,0 +1 @@ +6943EE91A5B24C1E3C43274E34A6207A981EE9DDF1F8CBB2129666CF70DC955F \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatTimestamp.rs2asm b/runelite-client/src/main/scripts/ChatTimestamp.rs2asm new file mode 100644 index 0000000000..7ebc00dbde --- /dev/null +++ b/runelite-client/src/main/scripts/ChatTimestamp.rs2asm @@ -0,0 +1,56 @@ +; used by TimestampPlugin via Chat(Split)Builder to display timestamps +; add a timestamp to a message +; string0 = timestamp +; string1 = message +; string2 = timestamp color +.id 4742 +.int_stack_count 0 +.string_stack_count 3 +.int_var_count 0 +.string_var_count 3 + jump ENABLED ; jump over ~on_enhanced_any = 0 | chat_gettimestamps = 0 + invoke 100 + iconst 0 + if_icmpeq LABEL11 + 5025 + iconst 0 + if_icmpeq LABEL11 +ENABLED: + sload 0 + invoke 5529 + iconst 1 + if_icmpeq LABEL11 + jump LABEL13 +LABEL11: + sload 1 + return +LABEL13: + sload 1 + invoke 5530 + invoke 5529 + iconst 1 + if_icmpeq LABEL19 + jump LABEL21 +LABEL19: + sload 1 + return +LABEL21: + sload 2 + invoke 5529 + iconst 0 + if_icmpeq LABEL26 + jump LABEL31 +LABEL26: + sload 2 + sload 0 + sconst "" + join_string 3 + sstore 0 +LABEL31: + sload 0 + sconst " " + sload 1 + join_string 3 + return + sconst "" + return From a42c845ad3c7cd64b1c738134b3dd874b83716d6 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Thu, 16 Dec 2021 09:45:44 +0100 Subject: [PATCH 37/42] project: Implement the new menu entry handling --- .../java/com/openosrs/injector/Injector.java | 3 + .../injectors/raw/CopyRuneLiteClasses.java | 3 +- .../injectors/raw/RuneliteMenuEntry.java | 99 ++++++ .../main/java/net/runelite/api/Client.java | 18 -- .../main/java/net/runelite/api/MenuEntry.java | 234 ++------------ .../runelite/client/menus/MenuManager.java | 4 +- .../plugins/banktags/BankTagsPlugin.java | 4 +- .../plugins/banktags/tabs/TabInterface.java | 4 +- .../chathistory/ChatHistoryPlugin.java | 8 +- .../plugins/friendlist/FriendListPlugin.java | 4 +- .../friendnotes/FriendNotesPlugin.java | 4 +- .../groundmarkers/GroundMarkerPlugin.java | 8 +- .../client/plugins/hiscore/HiscorePlugin.java | 4 +- .../inventorytags/InventoryTagsPlugin.java | 4 +- .../MenuEntrySwapperPlugin.java | 4 +- .../npchighlight/NpcIndicatorsPlugin.java | 10 +- .../ObjectIndicatorsPlugin.java | 4 +- .../client/plugins/wiki/WikiPlugin.java | 4 +- .../worldhopper/WorldHopperPlugin.java | 4 +- .../plugins/xptracker/XpTrackerPlugin.java | 4 +- .../client/ui/overlay/OverlayRenderer.java | 4 +- .../ui/overlay/worldmap/WorldMapOverlay.java | 4 +- .../runelite/client/menus/TestMenuEntry.java | 2 +- .../java/net/runelite/mixins/MenuMixin.java | 32 +- .../net/runelite/mixins/RSClientMixin.java | 274 ++++++++++++----- .../rs/api/RSRuneLiteIterableHashTable.java | 4 - .../api/RSRuneLiteIterableNodeHashTable.java | 4 + .../runelite/rs/api/RSRuneLiteMenuEntry.java | 13 + runescape-client/runescape-client.gradle.kts | 2 + .../src/main/java/ChatChannel.java | 2 +- runescape-client/src/main/java/Client.java | 2 +- .../src/main/java/FileSystem.java | 3 +- runescape-client/src/main/java/Message.java | 3 +- .../src/main/java/RuneLiteMenuEntry.java | 285 ++++++++++++++++++ runescape-client/src/main/java/class10.java | 2 +- 35 files changed, 665 insertions(+), 402 deletions(-) create mode 100644 injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java delete mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java create mode 100644 runescape-client/src/main/java/RuneLiteMenuEntry.java diff --git a/injector/src/main/java/com/openosrs/injector/Injector.java b/injector/src/main/java/com/openosrs/injector/Injector.java index 643bd17886..2264ff15f1 100644 --- a/injector/src/main/java/com/openosrs/injector/Injector.java +++ b/injector/src/main/java/com/openosrs/injector/Injector.java @@ -24,6 +24,7 @@ import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; import com.openosrs.injector.injectors.raw.CopyRuneLiteClasses; import com.openosrs.injector.injectors.raw.RuneLiteIterables; +import com.openosrs.injector.injectors.raw.RuneliteMenuEntry; import com.openosrs.injector.injectors.raw.RuneliteObject; import com.openosrs.injector.injectors.raw.ScriptVM; import com.openosrs.injector.rsapi.RSApi; @@ -150,6 +151,8 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new AddPlayerToMenu(this)); + inject(new RuneliteMenuEntry(this)); + validate(new InjectorValidator(this)); transform(new SourceChanger(this)); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java index 43a1c46822..9296d10b8f 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -38,7 +38,8 @@ public class CopyRuneLiteClasses extends AbstractInjector "RuneLiteObject", "RuneLiteIterableLinkDeque", "RuneLiteIterableNodeDeque", - "RuneLiteIterableNodeHashTable" + "RuneLiteIterableNodeHashTable", + "RuneLiteMenuEntry" ); public CopyRuneLiteClasses(InjectData inject) diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java new file mode 100644 index 0000000000..fe67fb85a3 --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.InjectUtil; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import java.util.ListIterator; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.BAStore; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.ILoad; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.InvokeStatic; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneliteMenuEntry extends AbstractInjector +{ + private static final String RUNELITE_MENU_ENTRY = "RuneLiteMenuEntry"; + + public RuneliteMenuEntry(InjectData inject) + { + super(inject); + } + + public void inject() + { + addInvoke(); + addSwap(InjectUtil.findMethod(inject, "incrementMenuEntries")); + addSwap(InjectUtil.findMethod(inject, "decrementMenuEntries")); + } + + private void addInvoke() + { + ClassFile runeliteMenuEntryVanilla = inject.vanilla.findClass(RUNELITE_MENU_ENTRY); + + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Method copy = clientVanilla.findMethod("newRuneliteMenuEntry"); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteMenuEntryVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ILoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteMenuEntryVanilla.getPoolClass(), "", new Signature("(I)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + private void addSwap(Method method) + { + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Instructions ins = method.getCode().getInstructions(); + ListIterator iterator = ins.getInstructions().listIterator(); + while (iterator.hasNext()) + { + Instruction i = iterator.next(); + + if (!(i instanceof BAStore)) + { + continue; + } + + ILoad i1 = new ILoad(ins, 2); + InvokeStatic i2 = new InvokeStatic(ins, new net.runelite.asm.pool.Method(clientVanilla.getPoolClass(), "swapMenuEntries", new Signature("(I)V"))); + + iterator.add(i1); + iterator.add(i2); + + return; + } + } +} diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 83d0c1cf1b..318deaf0f8 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -2124,24 +2124,6 @@ public interface Client extends GameEngine */ void scaleSprite(int[] canvas, int[] pixels, int color, int pixelX, int pixelY, int canvasIdx, int canvasOffset, int newWidth, int newHeight, int pixelWidth, int pixelHeight, int oldWidth); - /** - * Get the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use getMenuEntries, - * which will create a big array, when you only want to change - * the left click one. - */ - MenuEntry getLeftClickMenuEntry(); - - /** - * Set the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use setMenuEntries, - * which will arraycopy a big array to several smaller arrays lol, - * when you only want to change the left click one. - */ - void setLeftClickMenuEntry(MenuEntry entry); - /** * If this field is set to true, getting 5 minute logged won't show * the "You have been disconnected." message anymore. diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 2e17407dec..e607e2aca2 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,240 +24,72 @@ */ package net.runelite.api; -import java.util.Arrays; import java.util.function.Consumer; -import lombok.Data; -import lombok.NoArgsConstructor; /** * A menu entry in a right-click menu. */ -@Data -@NoArgsConstructor -public class MenuEntry implements Cloneable +public interface MenuEntry { /** * The option text added to the menu. (ie. "Walk here", "Use") */ - private String option; + String getOption(); + MenuEntry setOption(String option); + /** * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. */ - private String target; + String getTarget(); + MenuEntry setTarget(String target); + /** * An identifier value for the target of the action. */ - private int identifier; + int getIdentifier(); + MenuEntry setIdentifier(int identifier); + /** * The action the entry will trigger. - * {@link MenuAction} */ - private int opcode; + MenuAction getType(); + MenuEntry setType(MenuAction type); + /** * An additional parameter for the action. */ - private int param0; + int getParam0(); + MenuEntry setParam0(int param0); + /** * A second additional parameter for the action. */ - private int param1; + int getParam1(); + MenuEntry setParam1(int param1); + /** - * If this field is true and you have single mouse button on and this entry is + * If this is true and you have single mouse button on and this entry is * the top entry the right click menu will not be opened when you left click * * This is used for shift click */ - private boolean forceLeftClick; - - public MenuEntry(String option, String target, int type, int opcode, int param0, int param1, boolean forceLeftClick) - { - this.option = option; - this.target = target; - this.identifier = type; - this.opcode = opcode; - this.param0 = param0; - this.param1 = param1; - this.forceLeftClick = forceLeftClick; - } - - @Override - public MenuEntry clone() - { - try - { - return (MenuEntry) super.clone(); - } - catch (CloneNotSupportedException ex) - { - throw new RuntimeException(ex); - } - } - - public String getOption() - { - return option; - } - - public MenuEntry setOption(String option) - { - this.option = option; - return this; - } - - public String getTarget() - { - return target; - } - - public MenuEntry setTarget(String target) - { - this.target = target; - return this; - } - - public int getIdentifier() - { - return this.identifier; - } - - public MenuEntry setIdentifier(int identifier) - { - this.identifier = identifier; - return this; - } - - public MenuAction getType() - { - return MenuAction.of(this.opcode); - } - - public MenuEntry setType(MenuAction type) - { - this.opcode = type.getId(); - return this; - } - - public int getParam0() - { - return this.param0; - } - - public MenuEntry setParam0(int param0) - { - this.param0 = param0; - return this; - } - - public int getParam1() - { - return this.param1; - } - - public MenuEntry setParam1(int param1) - { - this.param1 = param1; - return this; - } - - public boolean isForceLeftClick() - { - return this.forceLeftClick; - } - - public MenuEntry setForceLeftClick(boolean forceLeftClick) - { - this.forceLeftClick = forceLeftClick; - return this; - } - - public boolean isDeprioritized() - { - return opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - public MenuEntry setDeprioritized(boolean deprioritized) - { - if (deprioritized) - { - if (opcode < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) - { - opcode += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - } - else - { - if (opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) - { - opcode -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - } - - return this; - } - - public MenuEntry onClick(Consumer callback) - { - return this; - } - - public void setActionParam0(int i) - { - this.param0 = i; - } - - public int getActionParam0() - { - return this.param0; - } - - public void setActionParam1(int i) - { - this.param1 = i; - } - - public int getActionParam1() - { - return this.param1; - } - - public void setType(int i) - { - this.opcode = i; - } - - public void setId(int i) - { - this.identifier = i; - } - - public int getId() - { - return this.identifier; - } + boolean isForceLeftClick(); + MenuEntry setForceLeftClick(boolean forceLeftClick); /** - * Get opcode, but as it's enum counterpart + * Deprioritized menus are sorted in the menu to be below the other menu entries. + * @return */ - public MenuAction getMenuAction() - { - return MenuAction.of(getOpcode()); - } + boolean isDeprioritized(); + MenuEntry setDeprioritized(boolean deprioritized); - // TODO: Remove this after properly implementing the menu - public void add(Client client) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(option); - menuEntry.setTarget(target); - menuEntry.setParam0(param0); - menuEntry.setParam1(param1); - menuEntry.setIdentifier(identifier); - menuEntry.setType(MenuAction.of(getOpcode())); - client.setMenuEntries(menuEntries); - } -} + /** + * Set a callback to be called when this menu option is clicked + * @param callback + * @return + */ + MenuEntry onClick(Consumer callback); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 93459b761c..69e9dca77c 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -142,9 +142,7 @@ public class MenuManager .setTarget(currentMenu.getMenuTarget()) .setType(MenuAction.RUNELITE) .setParam1(widgetId) - .onClick(currentMenu.callback) - // TODO: remove - .add(client); + .onClick(currentMenu.callback); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 3ee0513b06..bacab9beae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -362,9 +362,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener .setOption(text) .setType(MenuAction.RUNELITE) .setIdentifier(event.getIdentifier()) - .onClick(this::editTags) - // TODO: remove - .add(client); + .onClick(this::editTags); } tabInterface.handleAdd(event); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 1601e0d71f..7a1954e656 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -1196,8 +1196,6 @@ public class TabInterface .setTarget(target) .setOption(option) .setType(MenuAction.RUNELITE) - .setIdentifier(event.getIdentifier()) - // TODO: remove - .add(client); + .setIdentifier(event.getIdentifier()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index c5f1996275..2b11c3318b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -242,9 +242,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - }) - // TODO: remove - .add(client); + }); } @Subscribe @@ -290,9 +288,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener } optionBuilder.append(CLEAR_HISTORY); - clearEntry.setOption(optionBuilder.toString()) - // TODO: remove - .add(client); + clearEntry.setOption(optionBuilder.toString()); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index cadefce9c0..b3d85305ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -185,9 +185,7 @@ public class FriendListPlugin extends Plugin .type(ChatMessageType.CONSOLE) .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) .build()); - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index 24e321ae08..c274b74834 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -266,9 +266,7 @@ public class FriendNotesPlugin extends Plugin log.debug("Set note for '{}': '{}'", sanitizedTarget, content); setFriendNote(sanitizedTarget, content); }).build(); - }) - // TODO: remove - .add(client); + }); } else if (hoveredFriend != null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index baebf52248..e8de79d73e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -251,9 +251,7 @@ public class GroundMarkerPlugin extends Plugin { markTile(target.getLocalLocation()); } - }) - // TODO: remove - .add(client); + }); if (exists) { @@ -268,9 +266,7 @@ public class GroundMarkerPlugin extends Plugin { labelTile(target); } - }) - // TODO: remove - .add(client); + }); } } } 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 ecb68c64d0..8e567d37d7 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 @@ -178,9 +178,7 @@ public class HiscorePlugin extends Plugin HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); String target = Text.removeTags(e.getTarget()); lookupPlayer(target, endpoint); - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index c0e7a60cde..d588ed42aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -198,9 +198,7 @@ public class InventoryTagsPlugin extends Plugin { unsetTag(itemId); } - }) - // TODO: remove - .add(client); + }); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index a06ad3cbf7..58c2a66a6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -598,9 +598,7 @@ public class MenuEntrySwapperPlugin extends Plugin .setOption(RESET) .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) .setType(MenuAction.RUNELITE) - .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)) - // TODO: remove - .add(client); + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)); } @Subscribe 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 ff775e7129..4ee62c2545 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 @@ -296,19 +296,15 @@ public class NpcIndicatorsPlugin extends Plugin .setTarget(event.getTarget()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::tag) - // TODO: remove - .add(client); + .onClick(this::tag); } - client.createMenuEntry(-1) + MenuEntry i = client.createMenuEntry(-1) .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) .setTarget(event.getTarget()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::tag) - // TODO: remove - .add(client); + .onClick(this::tag); } } 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 2985ca8d12..526ffe7f91 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 @@ -235,9 +235,7 @@ public class ObjectIndicatorsPlugin extends Plugin .setParam1(event.getActionParam1()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::markObject) - // TODO: remove - .add(client); + .onClick(this::markObject); } private void markObject(MenuEntry entry) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index 9761c5935e..9ac225d4ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -418,9 +418,7 @@ public class WikiPlugin extends Plugin .addPathSegment("w") .addPathSegment(Text.removeTags(ev.getTarget())) .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString())) - // TODO: remove - .add(client); + .build().toString())); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index a6df02a7c5..82d44972e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -405,9 +405,7 @@ public class WorldHopperPlugin extends Plugin { hop(p.getWorld()); } - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 772d1f8c85..5407226a99 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -532,9 +532,7 @@ public class XpTrackerPlugin extends Plugin { addOverlay(skill); } - }) - // TODO: remove - .add(client); + }); } XpStateSingle getSkillState(Skill skill) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index 535587d409..7bd2d7cbad 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -185,9 +185,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener .setOption(overlayMenuEntry.getOption()) .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) .setType(overlayMenuEntry.getMenuAction()) - .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))) - // TODO: remove - .add(client); + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 4ec9d466f9..16ca444f8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -114,9 +114,7 @@ public class WorldMapOverlay extends Overlay .setOption(FOCUS_ON) .setType(MenuAction.RUNELITE) .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( - MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))) - // TODO: remove - .add(client); + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))); }); bottomBar.setHasListener(true); diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java index 6665f40ec3..5427f76540 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -30,7 +30,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @EqualsAndHashCode(callSuper = false) -public class TestMenuEntry extends MenuEntry +public class TestMenuEntry implements MenuEntry { private String option; private String target; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java index 6fb4d17233..21a59cd3fa 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java @@ -163,36 +163,6 @@ public abstract class MenuMixin implements RSClient } } - @Inject - @Override - public MenuEntry getLeftClickMenuEntry() - { - final int i = getMenuOptionCount() - 1; - return new MenuEntry( - getMenuOptions()[i], - getMenuTargets()[i], - getMenuIdentifiers()[i], - getMenuOpcodes()[i], - getMenuArguments1()[i], - getMenuArguments2()[i], - getMenuForceLeftClick()[i] - ); - } - - @Inject - @Override - public void setLeftClickMenuEntry(final MenuEntry entry) - { - final int i = getMenuOptionCount() - 1; - getMenuOptions()[i] = entry.getOption(); - getMenuTargets()[i] = entry.getTarget(); - getMenuIdentifiers()[i] = entry.getIdentifier(); - getMenuOpcodes()[i] = entry.getOpcode(); - getMenuArguments1()[i] = entry.getParam0(); - getMenuArguments2()[i] = entry.getParam1(); - getMenuForceLeftClick()[i] = entry.isForceLeftClick(); - } - @Inject @FieldHook("tempMenuAction") public static void onTempMenuActionChanged(int idx) @@ -213,7 +183,7 @@ public abstract class MenuMixin implements RSClient } tempMenuAction.setOption(entry.getOption()); - tempMenuAction.setOpcode(entry.getOpcode()); + tempMenuAction.setOpcode(entry.getType().getId()); tempMenuAction.setIdentifier(entry.getIdentifier()); tempMenuAction.setParam0(entry.getParam0()); tempMenuAction.setParam1(entry.getParam1()); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 06bea2ec7d..b1f1d79763 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -156,6 +156,7 @@ import net.runelite.rs.api.RSNodeDeque; import net.runelite.rs.api.RSNodeHashTable; import net.runelite.rs.api.RSPacketBuffer; import net.runelite.rs.api.RSPlayer; +import net.runelite.rs.api.RSRuneLiteMenuEntry; import net.runelite.rs.api.RSScene; import net.runelite.rs.api.RSScriptEvent; import net.runelite.rs.api.RSSpritePixels; @@ -294,6 +295,12 @@ public abstract class RSClientMixin implements RSClient @Inject private static ArrayList hiddenWidgets = new ArrayList<>(); + @Inject + private static final RSRuneLiteMenuEntry[] rl$menuEntries = new RSRuneLiteMenuEntry[500]; + + @Inject + private static int tmpMenuOptionsCount; + @Inject @Override public void setPrintMenuActions(boolean yes) @@ -789,119 +796,210 @@ public abstract class RSClientMixin implements RSClient setChatCycle(getCycleCntr()); } + @Inject + public static RSRuneLiteMenuEntry newRuneliteMenuEntry(int idx) + { + return null; + } + @Inject @Override public MenuEntry createMenuEntry(int idx) { - // TODO: Implement this + if (client.getMenuOptionCount() >= 500) + { + throw new IllegalStateException(); + } + else + { + if (idx < 0) + { + idx = client.getMenuOptionCount() + idx + 1; + if (idx < 0) + { + throw new IllegalArgumentException(); + } + } - return new MenuEntry(); + RSRuneLiteMenuEntry menuEntry; + if (idx < client.getMenuOptionCount()) + { + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[client.getMenuOptionCount()]; + if (tmpEntry == null) + { + tmpEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + for (int i = client.getMenuOptionCount(); i > idx; rl$menuEntries[i].setIdx(i--)) + { + client.getMenuOptions()[i] = client.getMenuOptions()[i - 1]; + client.getMenuTargets()[i] = client.getMenuTargets()[i - 1]; + client.getMenuIdentifiers()[i] = client.getMenuIdentifiers()[i - 1]; + client.getMenuOpcodes()[i] = client.getMenuOpcodes()[i - 1]; + client.getMenuArguments1()[i] = client.getMenuArguments1()[i - 1]; + client.getMenuArguments2()[i] = client.getMenuArguments2()[i - 1]; + client.getMenuForceLeftClick()[i] = client.getMenuForceLeftClick()[i - 1]; + + rl$menuEntries[i] = rl$menuEntries[i - 1]; + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + + menuEntry = tmpEntry; + rl$menuEntries[idx] = tmpEntry; + + tmpEntry.setIdx(idx); + } + else + { + if (idx != client.getMenuOptionCount()) + { + throw new IllegalArgumentException(); + } + + menuEntry = rl$menuEntries[client.getMenuOptionCount()]; + + if (menuEntry == null) + { + menuEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + } + + menuEntry.setOption(""); + menuEntry.setTarget(""); + menuEntry.setIdentifier(0); + menuEntry.setType(MenuAction.RUNELITE); + menuEntry.setParam0(0); + menuEntry.setParam1(0); + menuEntry.setConsumer(null); + + return menuEntry; + } } @Inject @Override public MenuEntry[] getMenuEntries() { - int count = getMenuOptionCount(); - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - MenuEntry[] entries = new MenuEntry[count]; - for (int i = 0; i < count; ++i) - { - MenuEntry entry = entries[i] = new MenuEntry(); - entry.setOption(menuOptions[i]); - entry.setTarget(menuTargets[i]); - entry.setIdentifier(menuIdentifiers[i]); - entry.setOpcode(menuTypes[i]); - entry.setParam0(params0[i]); - entry.setParam1(params1[i]); - entry.setForceLeftClick(leftClick[i]); - } - return entries; + return Arrays.copyOf(rl$menuEntries, client.getMenuOptionCount()); } @Inject @Override - public void setMenuEntries(MenuEntry[] entries) + public void setMenuEntries(MenuEntry[] menuEntries) { - int count = 0; - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - for (MenuEntry entry : entries) + for (int i = 0; i < menuEntries.length; ++i) { - if (entry == null) + RSRuneLiteMenuEntry menuEntry = (RSRuneLiteMenuEntry) menuEntries[i]; + if (menuEntry.getIdx() != i) { - continue; + sortMenuEntries(menuEntry.getIdx(), i); } - - menuOptions[count] = entry.getOption(); - menuTargets[count] = entry.getTarget(); - menuIdentifiers[count] = entry.getIdentifier(); - menuTypes[count] = entry.getOpcode(); - params0[count] = entry.getParam0(); - params1[count] = entry.getParam1(); - leftClick[count] = entry.isForceLeftClick(); - ++count; } - setMenuOptionCount(count); - oldMenuEntryCount = count; + client.setMenuOptionCount(menuEntries.length); + tmpMenuOptionsCount = menuEntries.length; + } + + @Inject + public static void sortMenuEntries(int left, int right) + { + String menuOption = client.getMenuOptions()[left]; + client.getMenuOptions()[left] = client.getMenuOptions()[right]; + client.getMenuOptions()[right] = menuOption; + + String menuTarget = client.getMenuTargets()[left]; + client.getMenuTargets()[left] = client.getMenuTargets()[right]; + client.getMenuTargets()[right] = menuTarget; + + int menuIdentifier = client.getMenuIdentifiers()[left]; + client.getMenuIdentifiers()[left] = client.getMenuIdentifiers()[right]; + client.getMenuIdentifiers()[right] = menuIdentifier; + + int menuOpcode = client.getMenuOpcodes()[left]; + client.getMenuOpcodes()[left] = client.getMenuOpcodes()[right]; + client.getMenuOpcodes()[right] = menuOpcode; + + int menuArguments1 = client.getMenuArguments1()[left]; + client.getMenuArguments1()[left] = client.getMenuArguments1()[right]; + client.getMenuArguments1()[right] = menuArguments1; + + int menuArgument2 = client.getMenuArguments2()[left]; + client.getMenuArguments2()[left] = client.getMenuArguments2()[right]; + client.getMenuArguments2()[right] = menuArgument2; + + boolean menuForceLeftClick = client.getMenuForceLeftClick()[left]; + client.getMenuForceLeftClick()[left] = client.getMenuForceLeftClick()[right]; + client.getMenuForceLeftClick()[right] = menuForceLeftClick; + + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[left]; + rl$menuEntries[left] = rl$menuEntries[right]; + rl$menuEntries[right] = tmpEntry; + + rl$menuEntries[left].setIdx(left); + rl$menuEntries[right].setIdx(right); + } + + @Inject + public static void swapMenuEntries(int var0) + { + RSRuneLiteMenuEntry var1 = rl$menuEntries[var0]; + RSRuneLiteMenuEntry var2 = rl$menuEntries[var0 + 1]; + + rl$menuEntries[var0] = var2; + rl$menuEntries[var0 + 1] = var1; + + var1.setIdx(var0 + 1); + var2.setIdx(var0); } @FieldHook("menuOptionsCount") @Inject public static void onMenuOptionsChanged(int idx) { - int oldCount = oldMenuEntryCount; - int newCount = client.getMenuOptionCount(); + int tmpOptionsCount = tmpMenuOptionsCount; + int optionCount = client.getMenuOptionCount(); - oldMenuEntryCount = newCount; + tmpMenuOptionsCount = optionCount; - final String[] options = client.getMenuOptions(); - final String[] targets = client.getMenuTargets(); - final int[] identifiers = client.getMenuIdentifiers(); - final int[] opcodes = client.getMenuOpcodes(); - final int[] arguments1 = client.getMenuArguments1(); - final int[] arguments2 = client.getMenuArguments2(); - final boolean[] forceLeftClick = client.getMenuForceLeftClick(); - - if (newCount == oldCount + 1) + if (optionCount < tmpOptionsCount) { - MenuEntryAdded event = new MenuEntryAdded( - options[oldCount], - targets[oldCount], - identifiers[oldCount], - opcodes[oldCount], - arguments1[oldCount], - arguments2[oldCount], - forceLeftClick[oldCount] - ); - - client.getCallbacks().post(event); - - if (event.isModified() && client.getMenuOptionCount() == newCount) + for (int i = optionCount; i < tmpOptionsCount; ++i) { - options[oldCount] = event.getOption(); - targets[oldCount] = event.getTarget(); - identifiers[oldCount] = event.getIdentifier(); - opcodes[oldCount] = event.getType(); - arguments1[oldCount] = event.getActionParam0(); - arguments2[oldCount] = event.getActionParam1(); - forceLeftClick[oldCount] = event.isForceLeftClick(); + rl$menuEntries[i].setConsumer(null); } } + else if (optionCount == tmpOptionsCount + 1) + { + String menuOption = client.getMenuOptions()[tmpOptionsCount]; + String menuTarget = client.getMenuTargets()[tmpOptionsCount]; + int menuOpcode = client.getMenuOpcodes()[tmpOptionsCount]; + int menuIdentifier = client.getMenuIdentifiers()[tmpOptionsCount]; + int menuArgument1 = client.getMenuArguments1()[tmpOptionsCount]; + int menuArgument2 = client.getMenuArguments2()[tmpOptionsCount]; + if (rl$menuEntries[tmpOptionsCount] == null) + { + rl$menuEntries[tmpOptionsCount] = newRuneliteMenuEntry(tmpOptionsCount); + } + else + { + rl$menuEntries[tmpOptionsCount].setConsumer(null); + } + + MenuEntryAdded menuEntryAdded = new MenuEntryAdded( + menuOption, + menuTarget, + menuOpcode, + menuIdentifier, + menuArgument1, + menuArgument2 + ); + client.getCallbacks().post(menuEntryAdded); + } } @Inject @@ -1479,6 +1577,17 @@ public abstract class RSClientMixin implements RSClient @Replace("menuAction") static void copy$menuAction(int param0, int param1, int opcode, int id, String option, String target, int canvasX, int canvasY) { + RSRuneLiteMenuEntry menuEntry = null; + + for (int i = client.getMenuOptionCount() - 1; i >= 0; --i) + { + if (client.getMenuOptions()[i] == option && client.getMenuTargets()[i] == target && client.getMenuIdentifiers()[i] == id && client.getMenuOpcodes()[i] == opcode) + { + menuEntry = rl$menuEntries[i]; + break; + } + } + /* * The RuneScape client may deprioritize an action in the menu by incrementing the opcode with 2000, * undo it here so we can get the correct opcode @@ -1501,6 +1610,11 @@ public abstract class RSClientMixin implements RSClient client.getCallbacks().post(menuOptionClicked); + if (menuEntry != null && menuEntry.getConsumer() != null) + { + menuEntry.getConsumer().accept(menuEntry); + } + if (menuOptionClicked.isConsumed()) { return; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java deleted file mode 100644 index 29833ca736..0000000000 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.runelite.rs.api; - -public interface RSRuneLiteIterableHashTable -{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java new file mode 100644 index 0000000000..6337285901 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableNodeHashTable +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java new file mode 100644 index 0000000000..ba16a2c48d --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java @@ -0,0 +1,13 @@ +package net.runelite.rs.api; + +import java.util.function.Consumer; +import net.runelite.api.MenuEntry; + +public interface RSRuneLiteMenuEntry extends MenuEntry +{ + Consumer getConsumer(); + void setConsumer(Consumer consumer); + + int getIdx(); + void setIdx(int idx); +} diff --git a/runescape-client/runescape-client.gradle.kts b/runescape-client/runescape-client.gradle.kts index fe52c6c012..5fc7078743 100644 --- a/runescape-client/runescape-client.gradle.kts +++ b/runescape-client/runescape-client.gradle.kts @@ -27,6 +27,8 @@ group = "com.openosrs.rs" description = "RuneScape Client" dependencies { + api(project(":runelite-api")) + implementation(project(":injection-annotations")) implementation(group = "org.bouncycastle", name = "bcprov-jdk15on", version = "1.52") diff --git a/runescape-client/src/main/java/ChatChannel.java b/runescape-client/src/main/java/ChatChannel.java index 4ff9e9bd1b..9bd2622d45 100644 --- a/runescape-client/src/main/java/ChatChannel.java +++ b/runescape-client/src/main/java/ChatChannel.java @@ -161,7 +161,7 @@ public class ChatChannel { Client.meslayerContinueWidget = null; } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); class115.revalidateWidgetScroll(MouseRecorder.Widget_interfaceComponents[var0 >> 16], var4, false); class33.runWidgetOnLoadListener(var1); if (Client.rootInterface != -1) { diff --git a/runescape-client/src/main/java/Client.java b/runescape-client/src/main/java/Client.java index 40e1149835..42e7d5c191 100644 --- a/runescape-client/src/main/java/Client.java +++ b/runescape-client/src/main/java/Client.java @@ -6401,7 +6401,7 @@ public final class Client extends GameEngine implements Usernamed, OAuthTokens { ) @Export("menu") final void menu() { - Message.method1115(); + Message.incrementMenuEntries(); if (class143.dragInventoryWidget == null) { if (clickedWidget == null) { int var1 = MouseHandler.MouseHandler_lastButton; diff --git a/runescape-client/src/main/java/FileSystem.java b/runescape-client/src/main/java/FileSystem.java index 8dd33ebc91..d26b04189b 100644 --- a/runescape-client/src/main/java/FileSystem.java +++ b/runescape-client/src/main/java/FileSystem.java @@ -30,7 +30,8 @@ public class FileSystem { descriptor = "(I)V", garbageValue = "497428397" ) - static void method3084() { + @Export("decrementMenuEntries") + static void decrementMenuEntries() { for (int var0 = 0; var0 < Client.menuOptionsCount; ++var0) { if (InvDefinition.method3157(Client.menuOpcodes[var0])) { if (var0 < Client.menuOptionsCount - 1) { diff --git a/runescape-client/src/main/java/Message.java b/runescape-client/src/main/java/Message.java index a6b0243341..fda1fa3c4b 100644 --- a/runescape-client/src/main/java/Message.java +++ b/runescape-client/src/main/java/Message.java @@ -166,7 +166,8 @@ public class Message extends DualNode { descriptor = "(I)V", garbageValue = "1989735073" ) - static final void method1115() { + @Export("incrementMenuEntries") + static final void incrementMenuEntries() { boolean var0 = false; while (!var0) { diff --git a/runescape-client/src/main/java/RuneLiteMenuEntry.java b/runescape-client/src/main/java/RuneLiteMenuEntry.java new file mode 100644 index 0000000000..72e9c392b4 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteMenuEntry.java @@ -0,0 +1,285 @@ +import java.util.function.Consumer; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +public class RuneLiteMenuEntry implements MenuEntry +{ + public Consumer consumer; + public int idx; + + public RuneLiteMenuEntry(int idx) + { + this.idx = idx; + } + + public Consumer getConsumer() + { + return consumer; + } + + public void setConsumer(Consumer consumer) + { + this.consumer = consumer; + } + + public int getIdx() + { + return idx; + } + + public void setIdx(int idx) + { + this.idx = idx; + } + + @Override + public String getOption() + { + return Client.menuActions[this.idx]; + } + + @Override + public MenuEntry setOption(String option) + { + Client.menuActions[this.idx] = option; + return this; + } + + @Override + public String getTarget() + { + return Client.menuTargets[this.idx]; + } + + @Override + public MenuEntry setTarget(String target) + { + Client.menuTargets[this.idx] = target; + return this; + } + + @Override + public MenuAction getType() + { + int opcode = Client.menuOpcodes[this.idx]; + if (opcode >= 2000) + { + opcode -= 2000; + } + + return MenuAction.of(opcode); + } + + @Override + public MenuEntry setType(MenuAction menuAction) + { + int opcode = Client.menuOpcodes[this.idx]; + short mod = 0; + if (opcode >= 2000) + { + mod = 2000; + } + + Client.menuOpcodes[this.idx] = menuAction.getId() + mod; + return this; + } + + @Override + public int getIdentifier() + { + return Client.menuIdentifiers[this.idx]; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + Client.menuIdentifiers[this.idx] = identifier; + return this; + } + + @Override + public int getParam0() + { + return Client.menuArguments1[this.idx]; + } + + @Override + public MenuEntry setParam0(int param0) + { + Client.menuArguments1[this.idx] = param0; + return this; + } + + @Override + public int getParam1() + { + return Client.menuArguments2[this.idx]; + } + + @Override + public MenuEntry setParam1(int param1) + { + Client.menuArguments2[this.idx] = param1; + return this; + } + + @Override + public boolean isDeprioritized() + { + return Client.menuOpcodes[this.idx] >= 2000; + } + + @Override + public MenuEntry setDeprioritized(boolean deprioritize) + { + int[] opcodes; + + if (deprioritize) + { + if (Client.menuOpcodes[this.idx] < 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] += 2000; + } + } + else if (Client.menuOpcodes[this.idx] >= 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] -= 2000; + } + + return this; + } + + @Override + public boolean isForceLeftClick() + { + return Client.menuShiftClick[this.idx]; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + Client.menuShiftClick[this.idx] = forceLeftClick; + return this; + } + + @Override + public MenuEntry onClick(Consumer consumer) + { + this.consumer = consumer; + return this; + } + + public boolean instanceOf(Object o) + { + return o instanceof RuneLiteMenuEntry; + } + + @Override + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + else if (!(o instanceof RuneLiteMenuEntry)) + { + return false; + } + else + { + RuneLiteMenuEntry menuEntry = (RuneLiteMenuEntry) o; + if (!menuEntry.instanceOf(this)) + { + return false; + } + else if (this.getIdentifier() != menuEntry.getIdentifier()) + { + return false; + } + else if (this.getParam0() != menuEntry.getParam0()) + { + return false; + } + else if (this.getParam1() != menuEntry.getParam1()) + { + return false; + } + else if (this.isForceLeftClick() != menuEntry.isForceLeftClick()) + { + return false; + } + else if (this.isDeprioritized() != menuEntry.isDeprioritized()) + { + return false; + } + else + { + String option = this.getOption(); + String menuEntryOption = menuEntry.getOption(); + if (option == null) + { + if (menuEntryOption != null) + { + return false; + } + } + else if (!option.equals(menuEntryOption)) + { + return false; + } + + String target = this.getTarget(); + String menuEntryTarget = menuEntry.getTarget(); + if (target == null) + { + if (menuEntryTarget != null) + { + return false; + } + } + else if (!target.equals(menuEntryTarget)) + { + return false; + } + + MenuAction type = this.getType(); + MenuAction menuEntryType = menuEntry.getType(); + if (type == null) + { + if (menuEntryType == null) + { + return true; + } + } + else if (type.equals(menuEntryType)) + { + return true; + } + + return false; + } + } + } + + @Override + public int hashCode() + { + byte b = 1; + + int hash = b * 59 + this.getIdentifier(); + hash = hash * 59 + this.getParam0(); + hash = hash * 59 + this.getParam1(); + hash = hash * 59 + (this.isForceLeftClick() ? 79 : 97); + hash = hash * 59 + (this.isDeprioritized() ? 79 : 97); + String option = this.getOption(); + hash = hash * 59 + (option == null ? 43 : option.hashCode()); + String target = this.getTarget(); + hash = hash * 59 + (target == null ? 43 : target.hashCode()); + MenuAction type = this.getType(); + hash = hash * 59 + (type == null ? 43 : type.hashCode()); + + return hash; + } +} diff --git a/runescape-client/src/main/java/class10.java b/runescape-client/src/main/java/class10.java index 211323be03..6ec5f93e9e 100644 --- a/runescape-client/src/main/java/class10.java +++ b/runescape-client/src/main/java/class10.java @@ -320,7 +320,7 @@ public class class10 { SecureRandomCallable.invalidateWidget(var4); } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); if (Client.rootInterface != -1) { Message.runIntfCloseListeners(Client.rootInterface, 1); } From df5e3e2334320d828325ceba4d781b02c82b6800 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Thu, 16 Dec 2021 10:18:41 +0100 Subject: [PATCH 38/42] project: Add a bit of backward compatibility to the reworked menus --- .../main/java/net/runelite/api/MenuEntry.java | 18 ++++++ .../runelite/api/events/MenuEntryAdded.java | 42 ++++++++++++++ .../api/events/MenuOptionClicked.java | 24 ++++++++ .../runelite/client/menus/TestMenuEntry.java | 42 ++++++++++++++ .../src/main/java/RuneLiteMenuEntry.java | 55 +++++++++++++++++++ 5 files changed, 181 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index e607e2aca2..f0db11f095 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -92,4 +92,22 @@ public interface MenuEntry * @return */ MenuEntry onClick(Consumer callback); + + @Deprecated + int getOpcode(); + @Deprecated + void setOpcode(int opcode); + + @Deprecated + int getActionParam0(); + @Deprecated + void setActionParam0(int param0); + + @Deprecated + int getActionParam1(); + @Deprecated + void setActionParam1(int param0); + + @Deprecated + MenuAction getMenuAction(); } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index 47c9d5227f..faf369be56 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -26,6 +26,7 @@ package net.runelite.api.events; import lombok.Getter; import lombok.Setter; +import net.runelite.api.MenuAction; /** * An event when a new entry is added to a right-click menu. @@ -92,4 +93,45 @@ public class MenuEntryAdded { this.modified = true; } + + @Deprecated + public int getParam0() + { + return actionParam0; + } + + @Deprecated + public void setParam0(int param) + { + actionParam0 = param; + } + + @Deprecated + public int getParam1() + { + return actionParam1; + } + + @Deprecated + public void setParam1(int param) + { + actionParam1 = param; + } + @Deprecated + public int getOpcode() + { + return type; + } + + @Deprecated + public void setOpcode(int opcode) + { + type = opcode; + } + + @Deprecated + public MenuAction getMenuAction() + { + return MenuAction.of(type); + } } diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index 3a5e884636..d25ee0a34d 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -96,4 +96,28 @@ public class MenuOptionClicked this.setParam0(entry.getParam0()); this.setParam1(entry.getParam1()); } + + @Deprecated + public int getActionParam() + { + return param0; + } + + @Deprecated + public void setActionParam(int i) + { + param0 = i; + } + + @Deprecated + public int getWidgetId() + { + return param1; + } + + @Deprecated + public void setWidgetId(int i) + { + param1 = i; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java index 5427f76540..fc337e7376 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -163,4 +163,46 @@ public class TestMenuEntry implements MenuEntry { return this; } + + @Override + public int getOpcode() + { + return this.type; + } + + @Override + public void setOpcode(int opcode) + { + this.type = opcode; + } + + @Override + public int getActionParam0() + { + return this.param0; + } + + @Override + public void setActionParam0(int param0) + { + this.param0 = param0; + } + + @Override + public int getActionParam1() + { + return this.param1; + } + + @Override + public void setActionParam1(int param1) + { + this.param1 = param1; + } + + @Override + public MenuAction getMenuAction() + { + return MenuAction.of(this.type); + } } diff --git a/runescape-client/src/main/java/RuneLiteMenuEntry.java b/runescape-client/src/main/java/RuneLiteMenuEntry.java index 72e9c392b4..d47d3d9927 100644 --- a/runescape-client/src/main/java/RuneLiteMenuEntry.java +++ b/runescape-client/src/main/java/RuneLiteMenuEntry.java @@ -70,6 +70,12 @@ public class RuneLiteMenuEntry implements MenuEntry return MenuAction.of(opcode); } + @Override + public MenuAction getMenuAction() + { + return this.getType(); + } + @Override public MenuEntry setType(MenuAction menuAction) { @@ -84,6 +90,31 @@ public class RuneLiteMenuEntry implements MenuEntry return this; } + @Override + public int getOpcode() + { + int opcode = Client.menuOpcodes[this.idx]; + if (opcode >= 2000) + { + opcode -= 2000; + } + + return opcode; + } + + @Override + public void setOpcode(int code) + { + int opcode = Client.menuOpcodes[this.idx]; + short mod = 0; + if (opcode >= 2000) + { + mod = 2000; + } + + Client.menuOpcodes[this.idx] = code + mod; + } + @Override public int getIdentifier() { @@ -110,6 +141,18 @@ public class RuneLiteMenuEntry implements MenuEntry return this; } + @Override + public int getActionParam0() + { + return this.getParam0(); + } + + @Override + public void setActionParam0(int param0) + { + this.setParam0(param0); + } + @Override public int getParam1() { @@ -123,6 +166,18 @@ public class RuneLiteMenuEntry implements MenuEntry return this; } + @Override + public int getActionParam1() + { + return this.getParam1(); + } + + @Override + public void setActionParam1(int param1) + { + this.setParam1(param1); + } + @Override public boolean isDeprioritized() { From 7e88e8e989c7d1ec2852f6f06bae47d8d2706ef2 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Thu, 16 Dec 2021 04:46:07 -0700 Subject: [PATCH 39/42] rl-api/Quest: Add The Frozen Door --- runelite-api/src/main/java/net/runelite/api/Quest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Quest.java b/runelite-api/src/main/java/net/runelite/api/Quest.java index 06702d4bf3..be6e21c911 100644 --- a/runelite-api/src/main/java/net/runelite/api/Quest.java +++ b/runelite-api/src/main/java/net/runelite/api/Quest.java @@ -198,7 +198,9 @@ public enum Quest FAMILY_PEST(329, "Family Pest"), MAGE_ARENA_II(330, "Mage Arena II"), IN_SEARCH_OF_KNOWLEDGE(3143, "In Search of Knowledge"), - DADDYS_HOME(1688, "Daddy's Home"); + DADDYS_HOME(1688, "Daddy's Home"), + THE_FROZEN_DOOR(3768, "The Frozen Door"), +; @Getter private final int id; From 53917cd3430d71dd69bfe76a16d080cee78d177c Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Thu, 16 Dec 2021 11:55:09 +0000 Subject: [PATCH 40/42] Release 1.8.7 --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-jshell/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index aa3e9cf336..f5eaca3e46 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 89eab54e01..aada2f1c2f 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index e3dd6a7fda..e092eab868 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 cache diff --git a/http-api/pom.xml b/http-api/pom.xml index bba80a65f8..a293793f45 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 2664f354a4..74bb472c37 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 Web Service diff --git a/pom.xml b/pom.xml index 51e43da81f..112c4dc950 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 pom RuneLite @@ -61,7 +61,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - HEAD + runelite-parent-1.8.7 diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 78e3b77012..a529584d8c 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 95b36353c8..850bc2f4e6 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 client diff --git a/runelite-jshell/pom.xml b/runelite-jshell/pom.xml index a4e3b26d1f..fa772fea44 100644 --- a/runelite-jshell/pom.xml +++ b/runelite-jshell/pom.xml @@ -30,7 +30,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 jshell diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 6c7b4e3810..be61039835 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7-SNAPSHOT + 1.8.7 script-assembler-plugin From 3c33d89a16035f84b30e95bcde56eae634f0bd4b Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Thu, 16 Dec 2021 11:55:12 +0000 Subject: [PATCH 41/42] Bump for 1.8.8-SNAPSHOT --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-jshell/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index f5eaca3e46..5f616c30f5 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index aada2f1c2f..5252bba4d5 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index e092eab868..5aac96d0c6 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT cache diff --git a/http-api/pom.xml b/http-api/pom.xml index a293793f45..24ffa1bfdd 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 74bb472c37..671c95d597 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT Web Service diff --git a/pom.xml b/pom.xml index 112c4dc950..3f5542e96d 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT pom RuneLite @@ -61,7 +61,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - runelite-parent-1.8.7 + HEAD diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index a529584d8c..62813947a2 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 850bc2f4e6..e2ee15124e 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT client diff --git a/runelite-jshell/pom.xml b/runelite-jshell/pom.xml index fa772fea44..97fa8eae63 100644 --- a/runelite-jshell/pom.xml +++ b/runelite-jshell/pom.xml @@ -30,7 +30,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT jshell diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index be61039835..49ba0eb296 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.7 + 1.8.8-SNAPSHOT script-assembler-plugin From 8495c3dd278c2cb14acd688266911fa71250f8e7 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Thu, 16 Dec 2021 13:05:26 +0100 Subject: [PATCH 42/42] project: Bump RL version --- buildSrc/src/main/kotlin/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 89a53056a8..e125baaf00 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -25,7 +25,7 @@ object ProjectVersions { const val launcherVersion = "2.2.0" - const val rlVersion = "1.8.6" + const val rlVersion = "1.8.7" const val openosrsVersion = "4.17.0"