This commit is contained in:
ThatGamerBlue
2021-02-04 07:16:17 +00:00
parent 58e1150d51
commit 4023066b5d
29 changed files with 329 additions and 555 deletions

View File

@@ -28,11 +28,10 @@ public class SoundManager
this.runeliteConfig = runeLiteConfig;
}
public void playSound(final Sound sound)
public void play(final Sound sound)
{
new Thread(new Runnable()
{
@Override
public void run()
{

View File

@@ -1,13 +1,28 @@
/*******************************************************************************
* Copyright (c) 2019 openosrs
* Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors:
* ST0NEWALL#9112
* Macweese#1169 UID 159941566994186240, macweese@pm.me
* openosrs Discord: https://discord.gg/Q7wFtCe
* openosrs website: https://openosrs.com
******************************************************************************/
/*
* Copyright (c) 2019, ST0NEWALL
* Copyright (c) 2020, Macweese <Macweese#1169 159941566994186240, macweese@pm.me>
* 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 com.openosrs.client.game;
import com.google.common.collect.ImmutableMap;

View File

@@ -1,135 +0,0 @@
/*
*
* Copyright (c) 2019, Zeruth <TheRealNull@gmail.com>
* 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 com.openosrs.client.plugins.openosrs;
import ch.qos.logback.classic.Logger;
import com.openosrs.client.config.OpenOSRSConfig;
import com.openosrs.client.plugins.openosrs.externals.ExternalPluginManagerPanel;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.Keybind;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.HotkeyListener;
import net.runelite.client.util.ImageUtil;
import org.slf4j.LoggerFactory;
@PluginDescriptor(
loadWhenOutdated = true, // prevent users from disabling
hidden = true, // prevent users from disabling
name = "OpenOSRS"
)
@Singleton
@Slf4j
public class OpenOSRSPlugin extends Plugin
{
@Inject
private OpenOSRSConfig config;
@Inject
private KeyManager keyManager;
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private ClientToolbar clientToolbar;
private NavigationButton navButton;
private final HotkeyListener hotkeyListener = new HotkeyListener(() -> this.keybind)
{
@Override
public void hotkeyPressed()
{
if (client == null)
{
return;
}
detach = !detach;
client.setOculusOrbState(detach ? 1 : 0);
client.setOculusOrbNormalSpeed(detach ? 36 : 12);
}
};
private boolean detach;
private Keybind keybind;
@Override
protected void startUp()
{
ExternalPluginManagerPanel panel = injector.getInstance(ExternalPluginManagerPanel.class);
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "externalmanager_icon.png");
navButton = NavigationButton.builder()
.tooltip("External Plugin Manager")
.icon(icon)
.priority(1)
.panel(panel)
.build();
clientToolbar.addNavigation(navButton);
this.keybind = config.detachHotkey();
keyManager.registerKeyListener(hotkeyListener);
}
@Override
protected void shutDown()
{
clientToolbar.removeNavigation(navButton);
}
@Subscribe
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("openosrs"))
{
return;
}
this.keybind = config.detachHotkey();
if (event.getKey().equals("shareLogs") && !config.shareLogs())
{
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
logger.detachAppender("Sentry");
}
}
}

View File

@@ -1,97 +0,0 @@
package com.openosrs.client.plugins.openosrs.externals;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.net.URL;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.text.DefaultCaret;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import org.pf4j.update.PluginInfo;
public class ExternalBox extends JPanel
{
private static final Font normalFont = FontManager.getRunescapeFont();
private static final Font smallFont = FontManager.getRunescapeSmallFont();
PluginInfo pluginInfo;
JLabel install = new JLabel();
JMultilineLabel description = new JMultilineLabel();
ExternalBox(String name, URL url)
{
this(name, url.toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", ""));
}
ExternalBox(PluginInfo pluginInfo)
{
this(pluginInfo.name, pluginInfo.description);
}
ExternalBox(String name, String desc)
{
setLayout(new BorderLayout());
setBackground(ColorScheme.DARKER_GRAY_COLOR);
JPanel titleWrapper = new JPanel(new BorderLayout());
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
titleWrapper.setBorder(new CompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR),
BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR)
));
JLabel title = new JLabel();
title.setText(name);
title.setFont(normalFont);
title.setBorder(null);
title.setBackground(ColorScheme.DARKER_GRAY_COLOR);
title.setPreferredSize(new Dimension(0, 24));
title.setForeground(Color.WHITE);
title.setBorder(new EmptyBorder(0, 8, 0, 0));
JPanel titleActions = new JPanel(new BorderLayout(3, 0));
titleActions.setBorder(new EmptyBorder(0, 0, 0, 8));
titleActions.setBackground(ColorScheme.DARKER_GRAY_COLOR);
titleActions.add(install, BorderLayout.EAST);
titleWrapper.add(title, BorderLayout.CENTER);
titleWrapper.add(titleActions, BorderLayout.EAST);
description.setText(desc);
description.setFont(smallFont);
description.setDisabledTextColor(Color.WHITE);
description.setBackground(ColorScheme.DARKER_GRAY_COLOR);
add(titleWrapper, BorderLayout.NORTH);
add(description, BorderLayout.CENTER);
}
public static class JMultilineLabel extends JTextArea
{
private static final long serialVersionUID = 1L;
public JMultilineLabel()
{
super();
setEditable(false);
setCursor(null);
setOpaque(false);
setFocusable(false);
setWrapStyleWord(true);
setLineWrap(true);
setBorder(new EmptyBorder(0, 8, 0, 8));
setAlignmentY(JLabel.CENTER_ALIGNMENT);
DefaultCaret caret = (DefaultCaret) getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
}
}
}

View File

@@ -1,294 +0,0 @@
package com.openosrs.client.plugins.openosrs.externals;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.util.ImageUtil;
public class ExternalPluginManagerPanel extends PluginPanel
{
private static final ImageIcon ADD_ICON_RAW;
private static final ImageIcon ADD_HOVER_ICON_RAW;
private static final ImageIcon ADD_ICON_GH;
private static final ImageIcon ADD_HOVER_ICON_GH;
static
{
final BufferedImage addIconRaw =
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_raw_icon.png");
final BufferedImage addIconGh = ImageUtil
.resizeImage(ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "gh_icon.png"), 14, 14);
ADD_ICON_RAW = new ImageIcon(addIconRaw);
ADD_HOVER_ICON_RAW = new ImageIcon(ImageUtil.alphaOffset(addIconRaw, 0.53f));
ADD_ICON_GH = new ImageIcon(addIconGh);
ADD_HOVER_ICON_GH = new ImageIcon(ImageUtil.alphaOffset(addIconGh, 0.53f));
}
private final OPRSExternalPluginManager externalPluginManager;
private final ScheduledExecutorService executor;
private final EventBus eventBus;
@Inject
private ExternalPluginManagerPanel(OPRSExternalPluginManager externalPluginManager, ScheduledExecutorService executor, EventBus eventBus)
{
super(false);
this.externalPluginManager = externalPluginManager;
this.executor = executor;
this.eventBus = eventBus;
buildPanel();
}
private void buildPanel()
{
removeAll();
setLayout(new BorderLayout(0, 10));
setBackground(ColorScheme.DARK_GRAY_COLOR);
add(titleBar(), BorderLayout.NORTH);
add(tabbedPane(), BorderLayout.CENTER);
revalidate();
repaint();
}
private JPanel titleBar()
{
JPanel titlePanel = new JPanel(new BorderLayout());
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JLabel title = new JLabel();
JLabel addGHRepo = new JLabel(ADD_ICON_GH);
JLabel addRawRepo = new JLabel(ADD_ICON_RAW);
JPanel buttonHolder = new JPanel(new BorderLayout());
buttonHolder.setBorder(new EmptyBorder(0, 0, 0, 0));
title.setText("External Plugin Manager");
title.setForeground(Color.WHITE);
addGHRepo.setToolTipText("Add new GitHub repository");
addGHRepo.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
if (externalPluginManager.getWarning())
{
JCheckBox checkbox = new JCheckBox("Don't show again.");
int answer = showWarningDialog(checkbox);
if (answer == 1)
{
return;
}
if (checkbox.isSelected())
{
externalPluginManager.setWarning(false);
}
}
JTextField owner = new JTextField();
JTextField name = new JTextField();
Object[] message = {
"Github Repository owner:", owner,
"Github Repository name:", name
};
int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals(""))
{
return;
}
if (externalPluginManager.doesGhRepoExist(owner.getText(), name.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This repository already exists.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (OPRSExternalPluginManager.testGHRepository(owner.getText(), name.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addGHRepository(owner.getText(), name.getText());
}
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
addGHRepo.setIcon(ADD_HOVER_ICON_GH);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
addGHRepo.setIcon(ADD_ICON_GH);
}
});
addGHRepo.setBorder(new EmptyBorder(0, 3, 0, 0));
addRawRepo.setToolTipText("Add new raw repository");
addRawRepo.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
if (externalPluginManager.getWarning())
{
JCheckBox checkbox = new JCheckBox("Don't show again.");
int answer = showWarningDialog(checkbox);
if (answer == 1)
{
return;
}
if (checkbox.isSelected())
{
externalPluginManager.setWarning(false);
}
}
JTextField id = new JTextField();
JTextField url = new JTextField();
Object[] message = {
"Repository ID:", id,
"Repository URL:", url
};
int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || id.getText().equals("") || url.getText().equals(""))
{
return;
}
if (id.getText().startsWith("gh:") || id.getText().contains("|"))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
"Repository id cannot begin with \"gh:\"\nor contain the pipe character '|'.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (externalPluginManager.doesRepoExist(id.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
String.format("The repository with id %s already exists.", id.getText()), "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
URL urlActual;
try
{
urlActual = new URL(url.getText());
}
catch (MalformedURLException e)
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (OPRSExternalPluginManager.testRepository(urlActual))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addRepository(id.getText(), urlActual);
}
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_HOVER_ICON_RAW);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_ICON_RAW);
}
});
addRawRepo.setBorder(new EmptyBorder(0, 0, 0, 3));
titlePanel.add(title, BorderLayout.WEST);
buttonHolder.add(addRawRepo, BorderLayout.WEST);
buttonHolder.add(addGHRepo, BorderLayout.EAST);
titlePanel.add(buttonHolder, BorderLayout.EAST);
return titlePanel;
}
private JTabbedPane tabbedPane()
{
JTabbedPane mainTabPane = new JTabbedPane();
PluginsPanel pluginPanel = new PluginsPanel(this.externalPluginManager, this.executor, this.eventBus);
JScrollPane repositoryPanel = wrapContainer(new RepositoryPanel(this.externalPluginManager, this.eventBus));
mainTabPane.add("Plugins", pluginPanel);
mainTabPane.add("Repositories", repositoryPanel);
return mainTabPane;
}
private int showWarningDialog(JCheckBox checkbox)
{
Object[] options = {"Okay, I accept the risk", "Never mind, turn back", checkbox};
return JOptionPane.showOptionDialog(new JFrame(),
"Adding plugins from unverified sources may put your account, or personal information at risk! \n",
"Account security warning",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[0]);
}
static JScrollPane wrapContainer(final JPanel container)
{
final JPanel wrapped = new JPanel(new BorderLayout());
wrapped.add(container, BorderLayout.NORTH);
final JScrollPane scroller = new JScrollPane(wrapped);
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroller.getVerticalScrollBar().setPreferredSize(new Dimension(8, 0));
return scroller;
}
}

View File

@@ -1,591 +0,0 @@
package com.openosrs.client.plugins.openosrs.externals;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import com.google.gson.JsonSyntaxException;
import com.openosrs.client.events.ExternalPluginChanged;
import com.openosrs.client.events.ExternalRepositoryChanged;
import net.runelite.client.util.DeferredDocumentChangedListener;
import com.openosrs.client.util.SwingUtil;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import lombok.extern.slf4j.Slf4j;
import static net.runelite.api.util.Text.DISTANCE;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.IconTextField;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.ImageUtil;
import org.pf4j.update.PluginInfo;
import org.pf4j.update.UpdateManager;
import org.pf4j.update.UpdateRepository;
import org.pf4j.update.VerifyException;
@Slf4j
public class PluginsPanel extends JPanel
{
private static final ImageIcon ADD_ICON;
private static final ImageIcon ADD_HOVER_ICON;
private static final ImageIcon DELETE_ICON;
private static final ImageIcon DELETE_HOVER_ICON;
private static final ImageIcon DELETE_ICON_GRAY;
private static final ImageIcon DELETE_HOVER_ICON_GRAY;
static
{
final BufferedImage addIcon =
ImageUtil.recolorImage(
ImageUtil.getResourceStreamFromClass(PluginsPanel.class, "add_icon.png"), ColorScheme.BRAND_BLUE
);
ADD_ICON = new ImageIcon(addIcon);
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
final BufferedImage deleteImg =
ImageUtil.recolorImage(
ImageUtil.resizeCanvas(
ImageUtil.getResourceStreamFromClass(PluginsPanel.class, "delete_icon.png"), 14, 14
), ColorScheme.BRAND_BLUE
);
DELETE_ICON = new ImageIcon(deleteImg);
DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, 0.53f));
DELETE_ICON_GRAY = new ImageIcon(ImageUtil.grayscaleImage(deleteImg));
DELETE_HOVER_ICON_GRAY = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.grayscaleImage(deleteImg), 0.53f));
}
private final OPRSExternalPluginManager externalPluginManager;
private final UpdateManager updateManager;
private final ScheduledExecutorService executor;
private final EventBus eventBus;
private final IconTextField searchBar = new IconTextField();
private final JPanel filterwrapper = new JPanel(new BorderLayout(0, 10));
private final List<PluginInfo> installedPluginsList = new ArrayList<>();
private final List<PluginInfo> availablePluginsList = new ArrayList<>();
private final JPanel installedPluginsPanel = new JPanel(new GridBagLayout());
private final JPanel availablePluginsPanel = new JPanel(new GridBagLayout());
private JComboBox<String> filterComboBox;
private Set<String> deps;
PluginsPanel(OPRSExternalPluginManager externalPluginManager, ScheduledExecutorService executor, EventBus eventBus)
{
this.externalPluginManager = externalPluginManager;
this.updateManager = externalPluginManager.getUpdateManager();
this.executor = executor;
this.eventBus = eventBus;
setLayout(new BorderLayout(0, 10));
setBackground(ColorScheme.DARK_GRAY_COLOR);
buildFilter();
JTabbedPane mainTabPane = new JTabbedPane();
mainTabPane.add("Installed", ExternalPluginManagerPanel.wrapContainer(installedPluginsPanel()));
mainTabPane.add("Available", ExternalPluginManagerPanel.wrapContainer(availablePluginsPanel()));
add(filterwrapper, BorderLayout.NORTH);
add(mainTabPane, BorderLayout.CENTER);
eventBus.register(this);
reloadPlugins();
}
@Subscribe
public void onExternalRepositoryChanged(ExternalRepositoryChanged event)
{
buildFilter();
reloadPlugins();
repaint();
}
private void buildFilter()
{
filterwrapper.removeAll();
DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener();
listener.addChangeListener(e ->
{
installedPlugins();
availablePlugins();
});
filterwrapper.setBorder(new EmptyBorder(10, 10, 0, 10));
List<String> repositories = getRepositories();
filterComboBox = new JComboBox<>(repositories.toArray(new String[0]));
filterComboBox.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH - 20, 30));
filterComboBox.addActionListener(e -> {
installedPlugins();
availablePlugins();
});
if (repositories.size() > 2)
{
filterwrapper.add(filterComboBox, BorderLayout.NORTH);
}
searchBar.setIcon(IconTextField.Icon.SEARCH);
searchBar.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH - 20, 30));
searchBar.setBackground(ColorScheme.DARKER_GRAY_COLOR);
searchBar.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR);
searchBar.getDocument().addDocumentListener(listener);
filterwrapper.add(searchBar, BorderLayout.CENTER);
}
private List<String> getRepositories()
{
List<String> repositories = new ArrayList<>();
repositories.add("All");
for (UpdateRepository updateRepository : this.updateManager.getRepositories())
{
repositories.add(updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", ""));
}
return repositories;
}
private JLabel titleLabel(String text)
{
JLabel title = new JShadowedLabel();
title.setFont(FontManager.getRunescapeSmallFont());
title.setForeground(Color.WHITE);
title.setHorizontalAlignment(SwingConstants.CENTER);
title.setText("<html><body style = 'text-align:center'>" + text + "</body></html>");
return title;
}
private JPanel installedPluginsPanel()
{
JPanel installedPluginsContainer = new JPanel();
installedPluginsContainer.setLayout(new BorderLayout(0, 5));
installedPluginsContainer.setBorder(new EmptyBorder(0, 10, 10, 10));
installedPluginsContainer.add(installedPluginsPanel, BorderLayout.CENTER);
return installedPluginsContainer;
}
private JPanel availablePluginsPanel()
{
JPanel availablePluginsContainer = new JPanel();
availablePluginsContainer.setLayout(new BorderLayout(0, 5));
availablePluginsContainer.setBorder(new EmptyBorder(0, 10, 10, 10));
availablePluginsContainer.add(availablePluginsPanel, BorderLayout.CENTER);
return availablePluginsContainer;
}
static boolean mismatchesSearchTerms(String search, PluginInfo pluginInfo)
{
final String[] searchTerms = search.toLowerCase().split(" ");
final String[] pluginTerms = (pluginInfo.name + " " + pluginInfo.description).toLowerCase().split("[/\\s]");
for (String term : searchTerms)
{
if (Arrays.stream(pluginTerms).noneMatch((t) -> t.contains(term) ||
DISTANCE.apply(t, term) > 0.9))
{
return true;
}
}
return false;
}
private void reloadPlugins()
{
fetchPlugins();
try
{
SwingUtil.syncExec(() -> {
this.installedPlugins();
this.availablePlugins();
});
}
catch (InvocationTargetException | InterruptedException e)
{
e.printStackTrace();
}
}
private void fetchPlugins()
{
List<PluginInfo> availablePlugins = null;
List<PluginInfo> plugins = null;
List<String> disabledPlugins = externalPluginManager.getDisabledPlugins();
try
{
availablePlugins = updateManager.getAvailablePlugins();
plugins = updateManager.getPlugins();
}
catch (JsonSyntaxException ex)
{
log.error(String.valueOf(ex));
}
if (availablePlugins == null || plugins == null)
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "The external plugin list could not be loaded.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
availablePluginsList.clear();
installedPluginsList.clear();
deps = externalPluginManager.getDependencies();
for (PluginInfo pluginInfo : plugins)
{
if (availablePlugins.contains(pluginInfo) || disabledPlugins.contains(pluginInfo.id))
{
availablePluginsList.add(pluginInfo);
}
else
{
installedPluginsList.add(pluginInfo);
}
}
}
@Subscribe
private void onExternalPluginChanged(ExternalPluginChanged externalPluginChanged)
{
String pluginId = externalPluginChanged.getPluginId();
Optional<Component> externalBox;
if (externalPluginChanged.isAdded())
{
externalBox = Arrays.stream(
availablePluginsPanel.getComponents()
).filter(extBox ->
extBox instanceof ExternalBox && ((ExternalBox) extBox).pluginInfo.id.equals(pluginId)
).findFirst();
}
else
{
externalBox = Arrays.stream(
installedPluginsPanel.getComponents()
).filter(extBox ->
extBox instanceof ExternalBox && ((ExternalBox) extBox).pluginInfo.id.equals(pluginId)
).findFirst();
}
if (externalBox.isEmpty())
{
log.info("EXTERNALBOX IS EMPTY: {}", pluginId);
return;
}
ExternalBox extBox = (ExternalBox) externalBox.get();
deps = externalPluginManager.getDependencies();
try
{
SwingUtil.syncExec(() ->
{
if (externalPluginChanged.isAdded())
{
availablePluginsPanel.remove(externalBox.get());
availablePluginsList.remove(extBox.pluginInfo);
installedPluginsList.add(extBox.pluginInfo);
installedPluginsList.sort(Comparator.naturalOrder());
installedPlugins();
pluginInstallButton(extBox.install, extBox.pluginInfo, true, deps.contains(extBox.pluginInfo.id));
}
else
{
installedPluginsPanel.remove(externalBox.get());
installedPluginsList.remove(extBox.pluginInfo);
availablePluginsList.add(extBox.pluginInfo);
availablePluginsList.sort(Comparator.naturalOrder());
availablePlugins();
pluginInstallButton(extBox.install, extBox.pluginInfo, false, false);
}
});
}
catch (InvocationTargetException | InterruptedException e)
{
e.printStackTrace();
}
}
private void installedPlugins()
{
GridBagConstraints c = new GridBagConstraints();
installedPluginsPanel.removeAll();
String search = searchBar.getText();
for (PluginInfo pluginInfo : installedPluginsList)
{
if (!search.equals("") && mismatchesSearchTerms(search, pluginInfo))
{
continue;
}
if (filterComboBox.getSelectedIndex() != 0)
{
boolean filtered = true;
String filter = String.valueOf(filterComboBox.getSelectedItem());
for (UpdateRepository updateRepository : updateManager.getRepositories())
{
if (filter.equals(updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", "")) &&
pluginInfo.getRepositoryId().equals(updateRepository.getId()))
{
filtered = false;
}
}
if (filtered)
{
continue;
}
}
ExternalBox pluginBox = new ExternalBox(pluginInfo);
pluginBox.pluginInfo = pluginInfo;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
c.gridy += 1;
c.insets = new Insets(5, 0, 0, 0);
pluginInstallButton(pluginBox.install, pluginInfo, true, deps.contains(pluginInfo.id));
installedPluginsPanel.add(pluginBox, c);
}
if (installedPluginsPanel.getComponents().length < 1)
{
installedPluginsPanel.add(titleLabel("No plugins found"));
}
}
private void availablePlugins()
{
GridBagConstraints c = new GridBagConstraints();
availablePluginsPanel.removeAll();
String search = searchBar.getText();
for (PluginInfo pluginInfo : availablePluginsList)
{
if (!search.equals("") && mismatchesSearchTerms(search, pluginInfo))
{
continue;
}
if (filterComboBox.getSelectedIndex() != 0)
{
boolean filtered = true;
String filter = String.valueOf(filterComboBox.getSelectedItem());
for (UpdateRepository updateRepository : updateManager.getRepositories())
{
if (filter.equals(updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", "")) &&
pluginInfo.getRepositoryId().equals(updateRepository.getId()))
{
filtered = false;
}
}
if (filtered)
{
continue;
}
}
ExternalBox pluginBox = new ExternalBox(pluginInfo);
pluginBox.pluginInfo = pluginInfo;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
c.gridy += 1;
c.insets = new Insets(5, 0, 0, 0);
pluginInstallButton(pluginBox.install, pluginInfo, false, false);
availablePluginsPanel.add(pluginBox, c);
}
if (availablePluginsPanel.getComponents().length < 1)
{
availablePluginsPanel.add(titleLabel("No plugins found"));
}
}
private void pluginInstallButton(JLabel install, PluginInfo pluginInfo, boolean installed, boolean hideAction)
{
install.setIcon(installed ? hideAction ? DELETE_ICON_GRAY : DELETE_ICON : ADD_ICON);
install.setText("");
if (!hideAction)
{
install.setToolTipText(installed ? "Uninstall" : "Install");
}
install.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
if (installed)
{
if (hideAction)
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This plugin can't be uninstalled because one or more other plugins have a dependency on it.", "Error!", JOptionPane.ERROR_MESSAGE);
}
else
{
install.setIcon(null);
install.setText("Uninstalling");
SwingWorker<Boolean, Void> worker = new SwingWorker<>()
{
@Override
protected Boolean doInBackground()
{
return externalPluginManager.uninstall(pluginInfo.id);
}
@Override
protected void done()
{
boolean status = false;
try
{
status = get();
}
catch (InterruptedException | ExecutionException e)
{
}
if (!status)
{
pluginInstallButton(install, pluginInfo, installed, hideAction);
}
}
};
worker.execute();
}
}
else
{
install.setIcon(null);
install.setText("Installing");
SwingWorker<Boolean, Void> worker = new SwingWorker<>()
{
@Override
protected Boolean doInBackground()
{
return installPlugin(pluginInfo);
}
@Override
protected void done()
{
boolean status = false;
try
{
status = get();
}
catch (InterruptedException | ExecutionException e)
{
}
if (!status)
{
pluginInstallButton(install, pluginInfo, installed, hideAction);
}
}
};
worker.execute();
}
}
@Override
public void mouseEntered(MouseEvent e)
{
if (install.getText().toLowerCase().contains("installing"))
{
return;
}
install.setIcon(installed ? hideAction ? DELETE_HOVER_ICON_GRAY : DELETE_HOVER_ICON : ADD_HOVER_ICON);
}
@Override
public void mouseExited(MouseEvent e)
{
if (install.getText().toLowerCase().contains("installing"))
{
return;
}
install.setIcon(installed ? hideAction ? DELETE_ICON_GRAY : DELETE_ICON : ADD_ICON);
}
});
}
private boolean installPlugin(PluginInfo pluginInfo)
{
try
{
return externalPluginManager.install(pluginInfo.id);
}
catch (VerifyException ex)
{
try
{
SwingUtil.syncExec(() ->
JOptionPane.showMessageDialog(ClientUI.getFrame(), pluginInfo.name + " could not be installed, the hash could not be verified.", "Error!", JOptionPane.ERROR_MESSAGE));
}
catch (InvocationTargetException | InterruptedException ignored)
{
}
}
return false;
}
}

View File

@@ -1,179 +0,0 @@
package com.openosrs.client.plugins.openosrs.externals;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import com.openosrs.client.ui.JMultilineLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Optional;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.LinkBrowser;
import org.pf4j.update.PluginInfo;
import org.pf4j.update.UpdateRepository;
public class RepositoryBox extends JPanel
{
private static final Font normalFont = FontManager.getRunescapeFont();
private static final Font smallFont = FontManager.getRunescapeSmallFont();
private static final ImageIcon DELETE_ICON;
private static final ImageIcon DELETE_HOVER_ICON;
private static final ImageIcon DISCORD_ICON;
private static final ImageIcon DISCORD_HOVER_ICON;
static
{
final BufferedImage deleteImg =
ImageUtil.recolorImage(
ImageUtil.resizeCanvas(
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "delete_icon.png"), 14, 14
), ColorScheme.BRAND_BLUE
);
DELETE_ICON = new ImageIcon(deleteImg);
DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, 0.53f));
final BufferedImage discordImg =
ImageUtil.recolorImage(
ImageUtil.resizeCanvas(
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "discord_icon.png"), 14, 14
), Color.WHITE
);
DISCORD_ICON = new ImageIcon(discordImg);
DISCORD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(discordImg, 0.53f));
}
RepositoryBox(OPRSExternalPluginManager externalPluginManager, UpdateRepository updateRepository)
{
setLayout(new BorderLayout());
setBackground(ColorScheme.DARKER_GRAY_COLOR);
String name = updateRepository.getId();
String urlString = updateRepository.getUrl().toString();
if (urlString.startsWith("/"))
{
urlString = urlString.substring(1);
}
JPanel titleWrapper = new JPanel(new BorderLayout());
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
titleWrapper.setBorder(new CompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR),
BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR)
));
JLabel title = new JLabel();
title.setText(name);
title.setFont(normalFont);
title.setBorder(null);
title.setBackground(ColorScheme.DARKER_GRAY_COLOR);
title.setPreferredSize(new Dimension(0, 24));
title.setForeground(Color.WHITE);
title.setBorder(new EmptyBorder(0, 8, 0, 0));
JPanel titleActions = new JPanel(new BorderLayout(3, 0));
titleActions.setBorder(new EmptyBorder(0, 0, 0, 8));
titleActions.setBackground(ColorScheme.DARKER_GRAY_COLOR);
Optional<PluginInfo> firstPlugin = updateRepository.getPlugins().values().stream().findFirst();
if (firstPlugin.isPresent() && !firstPlugin.get().projectUrl.equals(""))
{
JLabel support = new JLabel();
support.setIcon(DISCORD_ICON);
support.setToolTipText("Support");
support.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
LinkBrowser.browse(firstPlugin.get().projectUrl);
}
@Override
public void mouseEntered(MouseEvent e)
{
support.setIcon(DISCORD_HOVER_ICON);
}
@Override
public void mouseExited(MouseEvent e)
{
support.setIcon(DISCORD_ICON);
}
});
titleActions.add(support, BorderLayout.WEST);
}
if (!name.equals("OpenOSRS") && !name.equals("Plugin-Hub"))
{
JLabel install = new JLabel();
install.setIcon(DELETE_ICON);
install.setToolTipText("Remove");
install.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
externalPluginManager.removeRepository(updateRepository.getId());
}
@Override
public void mouseEntered(MouseEvent e)
{
install.setIcon(DELETE_HOVER_ICON);
}
@Override
public void mouseExited(MouseEvent e)
{
install.setIcon(DELETE_ICON);
}
});
titleActions.add(install, BorderLayout.EAST);
}
titleWrapper.add(title, BorderLayout.CENTER);
titleWrapper.add(titleActions, BorderLayout.EAST);
JMultilineLabel repository = new JMultilineLabel();
repository.setText(formatURL(urlString));
repository.setFont(smallFont);
repository.setDisabledTextColor(Color.WHITE);
String finalUrlString = urlString;
repository.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
LinkBrowser.browse(formatURL(finalUrlString));
}
});
add(titleWrapper, BorderLayout.NORTH);
add(repository, BorderLayout.CENTER);
}
private String formatURL(String url)
{
if (url.contains("githubusercontent"))
{
url = url.replace("raw.githubusercontent", "github").replace("/master/", "");
}
return url;
}
}

View File

@@ -1,55 +0,0 @@
package com.openosrs.client.plugins.openosrs.externals;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import com.openosrs.client.events.ExternalRepositoryChanged;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.inject.Inject;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.ui.ColorScheme;
import org.pf4j.update.UpdateRepository;
public class RepositoryPanel extends JPanel
{
@Inject
public EventBus eventBus;
private final OPRSExternalPluginManager externalPluginManager;
private final GridBagConstraints c = new GridBagConstraints();
RepositoryPanel(OPRSExternalPluginManager externalPluginManager, EventBus eventBus)
{
this.externalPluginManager = externalPluginManager;
setLayout(new GridBagLayout());
setBackground(ColorScheme.DARK_GRAY_COLOR);
setBorder(new EmptyBorder(0, 10, 0, 10));
onExternalRepositoryChanged(null);
eventBus.register(this);
}
@Subscribe
private void onExternalRepositoryChanged(ExternalRepositoryChanged event)
{
removeAll();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridy = 0;
c.insets = new Insets(5, 0, 0, 0);
for (UpdateRepository repository : externalPluginManager.getRepositories())
{
final RepositoryBox p = new RepositoryBox(externalPluginManager, repository);
add(p, c);
c.gridy++;
}
}
}

View File

@@ -47,7 +47,7 @@ import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import com.openosrs.client.ui.OpenOSRSSplashScreen;
import net.runelite.client.util.ImageUtil;
import com.openosrs.client.util.LinkBrowser;
import net.runelite.client.util.LinkBrowser;
@Slf4j
public class InfoPanel extends JPanel

View File

@@ -1,83 +0,0 @@
package com.openosrs.client.util;
import java.awt.Desktop;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.io.File;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LinkBrowser extends net.runelite.client.util.LinkBrowser
{
/**
* Tries to open the specified {@code File} with the systems default text editor. If operation fails
* an error message is displayed with the option to copy the absolute file path to clipboard.
*
* @param file the File instance of the log file
* @return did the file open successfully?
*/
public static boolean openLocalFile(final File file)
{
if (file == null || !file.exists())
{
return false;
}
if (attemptOpenLocalFile(file))
{
log.debug("Opened log file through Desktop#edit to {}", file);
return true;
}
showMessageBox("Unable to open log file. Press 'OK' and the file path will be copied to your clipboard", file.getAbsolutePath());
return false;
}
private static boolean attemptOpenLocalFile(final File file)
{
if (!Desktop.isDesktopSupported())
{
return false;
}
final Desktop desktop = Desktop.getDesktop();
if (!desktop.isSupported(Desktop.Action.OPEN))
{
return false;
}
try
{
desktop.open(file);
return true;
}
catch (IOException ex)
{
log.warn("Failed to open Desktop#edit {}", file, ex);
return false;
}
}
/**
* Open swing message box with specified message and copy data to clipboard
* @param message message to show
*/
private static void showMessageBox(final String message, final String data)
{
SwingUtilities.invokeLater(() ->
{
final int result = JOptionPane.showConfirmDialog(null, message, "Message",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION)
{
final StringSelection stringSelection = new StringSelection(data);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
});
}
}

View File

@@ -1,202 +0,0 @@
package com.openosrs.client.util;
import java.awt.Polygon;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.runelite.api.Client;
import net.runelite.api.Player;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
public class MiscUtils
{
private static final int[] abovePointsX = {2944, 3392, 3392, 2944};
private static final int[] abovePointsY = {3523, 3523, 3971, 3971};
private static final int[] belowPointsX = {2944, 2944, 3264, 3264};
private static final int[] belowPointsY = {9918, 10360, 10360, 9918};
private static final Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length);
private static final Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length);
private static final ChronoUnit[] ORDERED_CHRONOS = new ChronoUnit[]
{
ChronoUnit.YEARS,
ChronoUnit.MONTHS,
ChronoUnit.WEEKS,
ChronoUnit.DAYS,
ChronoUnit.HOURS,
ChronoUnit.MINUTES,
ChronoUnit.SECONDS
};
//test replacement so private for now
private static boolean inWildy(WorldPoint point)
{
if (point == null)
{
return false;
}
return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY());
}
public static int getWildernessLevelFrom(Client client, WorldPoint point)
{
if (client == null)
{
return 0;
}
if (point == null)
{
return 0;
}
int x = point.getX();
if (point.getPlane() == 0 && (x < 2940 || x > 3391))
{
return 0;
}
int y = point.getY();
//v underground //v above ground
int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56);
if (point.getPlane() > 0 && y < 9920)
{
wildernessLevel = 0;
}
if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.HIGH_RISK))
{
wildernessLevel += 15;
}
return Math.max(0, wildernessLevel);
}
public static int clamp(int val, int min, int max)
{
return Math.max(min, Math.min(max, val));
}
public static float clamp(float val, float min, float max)
{
return Math.max(min, Math.min(max, val));
}
public static boolean inWilderness(Client client)
{
Player localPlayer = client.getLocalPlayer();
if (localPlayer == null)
{
return false;
}
return inWildy(localPlayer.getWorldLocation());
//return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0;
}
public static String formatTimeAgo(Duration dur)
{
long dA = 0, dB = 0, rm;
ChronoUnit cA = null, cB = null;
for (int i = 0; i < ORDERED_CHRONOS.length; i++)
{
cA = ORDERED_CHRONOS[i];
dA = dur.getSeconds() / cA.getDuration().getSeconds();
rm = dur.getSeconds() % cA.getDuration().getSeconds();
if (dA <= 0)
{
cA = null;
continue;
}
if (i + 1 < ORDERED_CHRONOS.length)
{
cB = ORDERED_CHRONOS[i + 1];
dB = rm / cB.getDuration().getSeconds();
if (dB <= 0)
{
cB = null;
}
}
break;
}
if (cA == null)
{
return "just now.";
}
String str = formatUnit(cA, dA);
if (cB != null)
{
str += " and " + formatUnit(cB, dB);
}
return str + " ago.";
}
private static String formatUnit(ChronoUnit chrono, long val)
{
boolean multiple = val != 1;
String str;
if (multiple)
{
str = val + " ";
}
else
{
str = "a" + (chrono == ChronoUnit.HOURS ? "n " : " ");
}
str += chrono.name().toLowerCase();
if (!multiple)
{
if (str.charAt(str.length() - 1) == 's')
{
str = str.substring(0, str.length() - 1);
}
}
else if (str.charAt(str.length() - 1) != 's')
{
str += "s";
}
return str;
}
/**
* Mostly stolen from {@link java.net.URLStreamHandler#toExternalForm(URL)}
*
* @param url URL to encode
* @return URL, with path, query and ref encoded
*/
public static String urlToStringEncoded(URL url)
{
String s;
String path = url.getPath() != null ? Stream.of(url.getPath().split("/"))
.map(s2 -> URLEncoder.encode(s2, StandardCharsets.UTF_8)).collect(Collectors.joining("/")) : "";
return url.getProtocol()
+ ':'
+ (((s = url.getAuthority()) != null && s.length() > 0) ? "//" + s : "")
+ (path)
+ (((s = url.getQuery()) != null) ? '?' + urlEncode(s) : "")
+ (((s = url.getRef()) != null) ? '#' + urlEncode(s) : "");
}
private static String urlEncode(String s)
{
return URLEncoder.encode(s, StandardCharsets.UTF_8);
}
}

View File

@@ -1,110 +0,0 @@
package com.openosrs.client.util;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import net.runelite.client.util.CallableExceptionLogger;
import static net.runelite.client.util.RunnableExceptionLogger.wrap;
import org.jetbrains.annotations.NotNull;
// Awkward name because plugins already referenced the ExecutorServiceExceptionLogger
// (which only handles ScheduledExecutorServices) before this class was introduced
public class NonScheduledExecutorServiceExceptionLogger implements ExecutorService
{
private final ExecutorService service;
public NonScheduledExecutorServiceExceptionLogger(ExecutorService service)
{
this.service = service;
}
@Override
public void shutdown()
{
service.shutdown();
}
@NotNull
@Override
public List<Runnable> shutdownNow()
{
return service.shutdownNow();
}
@Override
public boolean isShutdown()
{
return service.isShutdown();
}
@Override
public boolean isTerminated()
{
return service.isTerminated();
}
@Override
public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException
{
return service.awaitTermination(timeout, unit);
}
@Override
public void execute(@NotNull Runnable command)
{
service.execute(wrap(command));
}
@NotNull
@Override
public <T> Future<T> submit(@NotNull Callable<T> task)
{
return service.submit(CallableExceptionLogger.wrap(task));
}
@NotNull
@Override
public <T> Future<T> submit(@NotNull Runnable task, T result)
{
return service.submit(wrap(task), result);
}
@NotNull
@Override
public Future<?> submit(@NotNull Runnable task)
{
return service.submit(wrap(task));
}
@NotNull
@Override
public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> tasks) throws InterruptedException
{
return service.invokeAll(tasks);
}
@NotNull
@Override
public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException
{
return service.invokeAll(tasks, timeout, unit);
}
@NotNull
@Override
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException
{
return service.invokeAny(tasks);
}
@Override
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return service.invokeAny(tasks, timeout, unit);
}
}

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2019. PKLite - All Rights Reserved
* Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited.
* Proprietary and confidential. Refer to PKLite License file for more information on
* full terms of this copyright and to determine what constitutes authorized use.
* Written by PKLite(ST0NEWALL, others) <stonewall@thots.cc.usa>, 2019
*
*/
package com.openosrs.client.util;
import net.runelite.api.Client;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemComposition;
import net.runelite.api.Player;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.geometry.Cuboid;
import net.runelite.client.game.ItemManager;
import net.runelite.client.util.QuantityFormatter;
import org.apache.commons.lang3.ArrayUtils;
import java.awt.Polygon;
import java.util.Comparator;
import java.util.Objects;
import java.util.TreeMap;
public class PvPUtil
{
private static final Polygon NOT_WILDERNESS_BLACK_KNIGHTS = new Polygon( // this is black knights castle
new int[]{2994, 2995, 2996, 2996, 2994, 2994, 2997, 2998, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3005,
3005, 3019, 3020, 3022, 3023, 3024, 3025, 3026, 3026, 3027, 3027, 3028, 3028, 3029, 3029, 3030, 3030, 3031,
3031, 3032, 3033, 3034, 3035, 3036, 3037, 3037},
new int[]{3525, 3526, 3527, 3529, 3529, 3534, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544,
3545, 3545, 3546, 3546, 3545, 3544, 3543, 3543, 3542, 3541, 3540, 3539, 3537, 3536, 3535, 3534, 3533, 3532,
3531, 3530, 3529, 3528, 3527, 3526, 3526, 3525},
43
);
private static final Cuboid MAIN_WILDERNESS_CUBOID = new Cuboid(2944, 3525, 0, 3391, 4351, 3);
private static final Cuboid GOD_WARS_WILDERNESS_CUBOID = new Cuboid(3008, 10112, 0, 3071, 10175, 3);
private static final Cuboid WILDERNESS_UNDERGROUND_CUBOID = new Cuboid(2944, 9920, 0, 3391, 10879, 3);
/**
* Gets the wilderness level based on a world point
* Java reimplementation of clientscript 384 [proc,wilderness_level]
*
* @param point the point in the world to get the wilderness level for
* @return the int representing the wilderness level
*/
public static int getWildernessLevelFrom(WorldPoint point)
{
if (MAIN_WILDERNESS_CUBOID.contains(point))
{
if (NOT_WILDERNESS_BLACK_KNIGHTS.contains(point.getX(), point.getY()))
{
return 0;
}
return ((point.getY() - 3520) / 8) + 1; // calc(((coordz(coord) - (55 * 64)) / 8) + 1)
}
else if (GOD_WARS_WILDERNESS_CUBOID.contains(point))
{
return ((point.getY() - 9920) / 8) - 1; // calc(((coordz(coord) - (155 * 64)) / 8) - 1)
}
else if (WILDERNESS_UNDERGROUND_CUBOID.contains(point))
{
return ((point.getY() - 9920) / 8) + 1; // calc(((coordz(coord) - (155 * 64)) / 8) + 1)
}
return 0;
}
/**
* Determines if another player is attackable based off of wilderness level and combat levels
*
* @param client The client of the local player
* @param player the player to determine attackability
* @return returns true if the player is attackable, false otherwise
*/
public static boolean isAttackable(Client client, Player player)
{
int wildernessLevel = 0;
if (WorldType.isDeadmanWorld(client.getWorldType()))
{
return true;
}
if (WorldType.isPvpWorld(client.getWorldType()))
{
wildernessLevel += 15;
}
if (client.getVar(Varbits.IN_WILDERNESS) == 1)
{
wildernessLevel += getWildernessLevelFrom(client.getLocalPlayer().getWorldLocation());
}
return wildernessLevel != 0 && Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel()) <= wildernessLevel;
}
public static int calculateRisk(Client client, ItemManager itemManager)
{
if (client.getItemContainer(InventoryID.EQUIPMENT) == null)
{
return 0;
}
if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null)
{
return 0;
}
Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(),
Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems());
TreeMap<Integer, Item> priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue));
int wealth = 0;
for (Item i : items)
{
int value = (itemManager.getItemPrice(i.getId()) * i.getQuantity());
final ItemComposition itemComposition = itemManager.getItemComposition(i.getId());
if (!itemComposition.isTradeable() && value == 0)
{
value = itemComposition.getPrice() * i.getQuantity();
priceMap.put(value, i);
}
else
{
value = itemManager.getItemPrice(i.getId()) * i.getQuantity();
if (i.getId() > 0 && value > 0)
{
priceMap.put(value, i);
}
}
wealth += value;
}
return Integer.parseInt(QuantityFormatter.quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum()));
}
}

View File

@@ -1,19 +0,0 @@
package com.openosrs.client.util;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
public class SwingUtil extends net.runelite.client.util.SwingUtil
{
public static void syncExec(final Runnable r) throws InvocationTargetException, InterruptedException
{
if (EventQueue.isDispatchThread())
{
r.run();
}
else
{
EventQueue.invokeAndWait(r);
}
}
}