externalmanager: rework config format, add direct repo support, change icons
This commit is contained in:
@@ -50,6 +50,7 @@ import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.events.ExternalPluginChanged;
|
||||
import net.runelite.client.events.ExternalRepositoryChanged;
|
||||
import net.runelite.client.ui.RuneLiteSplashScreen;
|
||||
import net.runelite.client.util.MiscUtils;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import org.pf4j.DefaultPluginManager;
|
||||
import org.pf4j.DependencyResolver;
|
||||
@@ -184,22 +185,41 @@ class ExternalPluginManager
|
||||
this.externalPluginManager.setSystemVersion(SYSTEM_VERSION);
|
||||
}
|
||||
|
||||
public boolean doesGhRepoExist(String owner, String name)
|
||||
{
|
||||
return doesRepoExist("gh:" + owner + "/" + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that {@link org.pf4j.update.UpdateManager#addRepository} checks if the repo exists, however it throws an exception which is bad
|
||||
*/
|
||||
public boolean doesRepoExist(String id)
|
||||
{
|
||||
return repositories.stream().anyMatch((repo) -> repo.getId().equals(id));
|
||||
}
|
||||
|
||||
private static URL toRepositoryUrl(String owner, String name) throws MalformedURLException
|
||||
{
|
||||
return new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/");
|
||||
}
|
||||
|
||||
public static boolean testRepository(String owner, String name)
|
||||
public static boolean testGHRepository(String owner, String name)
|
||||
{
|
||||
final List<UpdateRepository> repositories = new ArrayList<>();
|
||||
try
|
||||
{
|
||||
repositories.add(new DefaultUpdateRepository("github", new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/")));
|
||||
return testRepository(toRepositoryUrl(owner, name));
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
return true;
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean testRepository(URL url)
|
||||
{
|
||||
final List<UpdateRepository> repositories = new ArrayList<>();
|
||||
repositories.add(new DefaultUpdateRepository("repository-testing", url));
|
||||
DefaultPluginManager testPluginManager = new DefaultPluginManager(EXTERNALPLUGIN_DIR.toPath());
|
||||
UpdateManager updateManager = new UpdateManager(testPluginManager, repositories);
|
||||
|
||||
@@ -238,6 +258,42 @@ class ExternalPluginManager
|
||||
}
|
||||
|
||||
public void startExternalUpdateManager()
|
||||
{
|
||||
if (!tryLoadNewFormat())
|
||||
{
|
||||
loadOldFormat();
|
||||
}
|
||||
|
||||
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
|
||||
}
|
||||
|
||||
public boolean tryLoadNewFormat()
|
||||
{
|
||||
try
|
||||
{
|
||||
for (String keyval : openOSRSConfig.getExternalRepositories().split(";"))
|
||||
{
|
||||
String[] split = keyval.split("\\|");
|
||||
if (split.length != 2)
|
||||
{
|
||||
repositories.clear();
|
||||
return false;
|
||||
}
|
||||
String id = split[0];
|
||||
String url = split[1];
|
||||
|
||||
repositories.add(new DefaultUpdateRepository(id, new URL(url)));
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException | MalformedURLException e)
|
||||
{
|
||||
repositories.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void loadOldFormat()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -253,18 +309,13 @@ class ExternalPluginManager
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
|
||||
}
|
||||
|
||||
public void addRepository(String owner, String name)
|
||||
public void addGHRepository(String owner, String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
DefaultUpdateRepository respository = new DefaultUpdateRepository(owner + toRepositoryUrl(owner, name), toRepositoryUrl(owner, name));
|
||||
updateManager.addRepository(respository);
|
||||
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(owner + toRepositoryUrl(owner, name), true));
|
||||
saveConfig();
|
||||
addRepository("gh:" + owner + "/" + name, toRepositoryUrl(owner, name));
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
@@ -272,6 +323,14 @@ class ExternalPluginManager
|
||||
}
|
||||
}
|
||||
|
||||
public void addRepository(String key, URL url)
|
||||
{
|
||||
DefaultUpdateRepository respository = new DefaultUpdateRepository(key, url);
|
||||
updateManager.addRepository(respository);
|
||||
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(key, true));
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
public void removeRepository(String owner)
|
||||
{
|
||||
updateManager.removeRepository(owner);
|
||||
@@ -286,8 +345,8 @@ class ExternalPluginManager
|
||||
for (UpdateRepository repository : updateManager.getRepositories())
|
||||
{
|
||||
config.append(repository.getId());
|
||||
config.append(":");
|
||||
config.append(repository.getUrl().toString());
|
||||
config.append("|");
|
||||
config.append(MiscUtils.urlToStringEncoded(repository.getUrl()));
|
||||
config.append(";");
|
||||
}
|
||||
config.deleteCharAt(config.lastIndexOf(";"));
|
||||
|
||||
@@ -6,7 +6,12 @@ import java.awt.Dimension;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
@@ -16,25 +21,29 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import lombok.SneakyThrows;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.plugins.ExternalPluginManager;
|
||||
import net.runelite.client.plugins.info.InfoPlugin;
|
||||
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;
|
||||
private static final ImageIcon ADD_HOVER_ICON;
|
||||
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 addIcon =
|
||||
ImageUtil.recolorImage(
|
||||
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_icon.png"), ColorScheme.BRAND_BLUE
|
||||
);
|
||||
ADD_ICON = new ImageIcon(addIcon);
|
||||
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
|
||||
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 ExternalPluginManager externalPluginManager;
|
||||
@@ -73,13 +82,17 @@ public class ExternalPluginManagerPanel extends PluginPanel
|
||||
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
|
||||
JLabel title = new JLabel();
|
||||
JLabel addRepo = new JLabel(ADD_ICON);
|
||||
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);
|
||||
|
||||
addRepo.setToolTipText("Add new repository");
|
||||
addRepo.addMouseListener(new MouseAdapter()
|
||||
addGHRepo.setToolTipText("Add new GitHub repository");
|
||||
addGHRepo.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
@@ -97,30 +110,98 @@ public class ExternalPluginManagerPanel extends PluginPanel
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExternalPluginManager.testRepository(owner.getText(), name.getText()))
|
||||
if (externalPluginManager.doesGhRepoExist(owner.getText(), name.getText()))
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, "This repository already exists.", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExternalPluginManager.testGHRepository(owner.getText(), name.getText()))
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, "This doesn't appear to be a valid repository.", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
externalPluginManager.addRepository(owner.getText(), name.getText());
|
||||
externalPluginManager.addGHRepository(owner.getText(), name.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
addRepo.setIcon(ADD_HOVER_ICON);
|
||||
addGHRepo.setIcon(ADD_HOVER_ICON_GH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
addRepo.setIcon(ADD_ICON);
|
||||
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)
|
||||
{
|
||||
JTextField id = new JTextField();
|
||||
JTextField url = new JTextField();
|
||||
Object[] message = {
|
||||
"Repository ID:", id,
|
||||
"Repository URL:", url
|
||||
};
|
||||
|
||||
int option = JOptionPane.showConfirmDialog(null, message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
|
||||
if (option != JOptionPane.OK_OPTION || id.getText().equals("") || url.getText().equals(""))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (externalPluginManager.doesRepoExist(id.getText()))
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, 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(null, "This doesn't appear to be a valid repository.", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExternalPluginManager.testRepository(urlActual))
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, "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);
|
||||
titlePanel.add(addRepo, BorderLayout.EAST);
|
||||
buttonHolder.add(addRawRepo, BorderLayout.WEST);
|
||||
buttonHolder.add(addGHRepo, BorderLayout.EAST);
|
||||
titlePanel.add(buttonHolder, BorderLayout.EAST);
|
||||
|
||||
return titlePanel;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package net.runelite.client.util;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
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;
|
||||
|
||||
public class MiscUtils
|
||||
{
|
||||
@@ -170,4 +173,27 @@ public class MiscUtils
|
||||
}
|
||||
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;
|
||||
return url.getProtocol()
|
||||
+ ':'
|
||||
+ (((s = url.getAuthority()) != null && s.length() > 0)
|
||||
? "//" + s : "")
|
||||
+ (((s = url.getPath()) != null) ? urlEncode(s) : "")
|
||||
+ (((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);
|
||||
}
|
||||
}
|
||||
|
||||
BIN
runelite-client/src/main/resources/net/runelite/client/plugins/openosrs/externals/add_raw_icon.png
vendored
Normal file
BIN
runelite-client/src/main/resources/net/runelite/client/plugins/openosrs/externals/add_raw_icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
runelite-client/src/main/resources/net/runelite/client/plugins/openosrs/externals/gh_icon.png
vendored
Normal file
BIN
runelite-client/src/main/resources/net/runelite/client/plugins/openosrs/externals/gh_icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user