Merge pull request #2394 from ThatGamerBlue/external-raw-oprs
externalmanager: add ability to load a repository from any url
This commit is contained in:
@@ -8,6 +8,42 @@ import com.google.inject.CreationException;
|
|||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.RuneLiteProperties;
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.config.OpenOSRSConfig;
|
||||||
|
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;
|
||||||
|
import org.pf4j.JarPluginLoader;
|
||||||
|
import org.pf4j.JarPluginRepository;
|
||||||
|
import org.pf4j.ManifestPluginDescriptorFinder;
|
||||||
|
import org.pf4j.PluginAlreadyLoadedException;
|
||||||
|
import org.pf4j.PluginDependency;
|
||||||
|
import org.pf4j.PluginDescriptorFinder;
|
||||||
|
import org.pf4j.PluginLoader;
|
||||||
|
import org.pf4j.PluginRepository;
|
||||||
|
import org.pf4j.PluginRuntimeException;
|
||||||
|
import org.pf4j.PluginWrapper;
|
||||||
|
import org.pf4j.RuntimeMode;
|
||||||
|
import org.pf4j.update.DefaultUpdateRepository;
|
||||||
|
import org.pf4j.update.PluginInfo;
|
||||||
|
import org.pf4j.update.UpdateManager;
|
||||||
|
import org.pf4j.update.UpdateRepository;
|
||||||
|
import org.pf4j.update.VerifyException;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@@ -32,43 +68,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.runelite.client.RuneLite;
|
|
||||||
import static net.runelite.client.RuneLite.EXTERNALPLUGIN_DIR;
|
import static net.runelite.client.RuneLite.EXTERNALPLUGIN_DIR;
|
||||||
import static net.runelite.client.RuneLite.SYSTEM_VERSION;
|
import static net.runelite.client.RuneLite.SYSTEM_VERSION;
|
||||||
import net.runelite.client.RuneLiteProperties;
|
|
||||||
import net.runelite.client.config.Config;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
|
||||||
import net.runelite.client.config.OpenOSRSConfig;
|
|
||||||
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.SwingUtil;
|
|
||||||
import org.pf4j.DefaultPluginManager;
|
|
||||||
import org.pf4j.DependencyResolver;
|
|
||||||
import org.pf4j.JarPluginLoader;
|
|
||||||
import org.pf4j.JarPluginRepository;
|
|
||||||
import org.pf4j.ManifestPluginDescriptorFinder;
|
|
||||||
import org.pf4j.PluginAlreadyLoadedException;
|
|
||||||
import org.pf4j.PluginDependency;
|
|
||||||
import org.pf4j.PluginDescriptorFinder;
|
|
||||||
import org.pf4j.PluginLoader;
|
|
||||||
import org.pf4j.PluginRepository;
|
|
||||||
import org.pf4j.PluginRuntimeException;
|
|
||||||
import org.pf4j.PluginWrapper;
|
|
||||||
import org.pf4j.RuntimeMode;
|
|
||||||
import org.pf4j.update.DefaultUpdateRepository;
|
|
||||||
import org.pf4j.update.PluginInfo;
|
|
||||||
import org.pf4j.update.UpdateManager;
|
|
||||||
import org.pf4j.update.UpdateRepository;
|
|
||||||
import org.pf4j.update.VerifyException;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -85,7 +86,6 @@ class ExternalPluginManager
|
|||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
|
private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
|
||||||
private final Map<String, String> pluginsMap = new HashMap<>();
|
private final Map<String, String> pluginsMap = new HashMap<>();
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Getter(AccessLevel.PUBLIC)
|
||||||
private UpdateManager updateManager;
|
private UpdateManager updateManager;
|
||||||
|
|
||||||
@@ -111,7 +111,9 @@ class ExternalPluginManager
|
|||||||
{
|
{
|
||||||
boolean debug = RuneLiteProperties.getLauncherVersion() == null && RuneLiteProperties.getPluginPath() != null;
|
boolean debug = RuneLiteProperties.getLauncherVersion() == null && RuneLiteProperties.getPluginPath() != null;
|
||||||
|
|
||||||
this.externalPluginManager = new DefaultPluginManager(debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release") : EXTERNALPLUGIN_DIR.toPath())
|
this.externalPluginManager = new DefaultPluginManager(
|
||||||
|
debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release")
|
||||||
|
: EXTERNALPLUGIN_DIR.toPath())
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected PluginDescriptorFinder createPluginDescriptorFinder()
|
protected PluginDescriptorFinder createPluginDescriptorFinder()
|
||||||
@@ -189,22 +191,41 @@ class ExternalPluginManager
|
|||||||
this.externalPluginManager.setSystemVersion(SYSTEM_VERSION);
|
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
|
private static URL toRepositoryUrl(String owner, String name) throws MalformedURLException
|
||||||
{
|
{
|
||||||
return new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/");
|
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
|
try
|
||||||
{
|
{
|
||||||
repositories.add(new DefaultUpdateRepository("github", new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/")));
|
return testRepository(toRepositoryUrl(owner, name));
|
||||||
}
|
}
|
||||||
catch (MalformedURLException e)
|
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());
|
DefaultPluginManager testPluginManager = new DefaultPluginManager(EXTERNALPLUGIN_DIR.toPath());
|
||||||
UpdateManager updateManager = new UpdateManager(testPluginManager, repositories);
|
UpdateManager updateManager = new UpdateManager(testPluginManager, repositories);
|
||||||
|
|
||||||
@@ -243,6 +264,58 @@ class ExternalPluginManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void startExternalUpdateManager()
|
public void startExternalUpdateManager()
|
||||||
|
{
|
||||||
|
if (!tryLoadNewFormat())
|
||||||
|
{
|
||||||
|
loadOldFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
|
||||||
|
saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
if (!url.endsWith("/"))
|
||||||
|
{
|
||||||
|
url = url.concat("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.contains("https://raw.githubusercontent.com/"))
|
||||||
|
{
|
||||||
|
id = "gh:" + id.substring(id.indexOf("https://raw.githubusercontent.com/")).replace("/master", "")
|
||||||
|
.replace("https://raw.githubusercontent.com/", "");
|
||||||
|
|
||||||
|
if (id.endsWith("/"))
|
||||||
|
{
|
||||||
|
id = id.substring(0, id.lastIndexOf("/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories.add(new DefaultUpdateRepository(id, new URL(url)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ArrayIndexOutOfBoundsException | MalformedURLException e)
|
||||||
|
{
|
||||||
|
repositories.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadOldFormat()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -260,18 +333,13 @@ class ExternalPluginManager
|
|||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRepository(String owner, String name)
|
public void addGHRepository(String owner, String name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DefaultUpdateRepository respository = new DefaultUpdateRepository(owner + toRepositoryUrl(owner, name), toRepositoryUrl(owner, name));
|
addRepository("gh:" + owner + "/" + name, toRepositoryUrl(owner, name));
|
||||||
updateManager.addRepository(respository);
|
|
||||||
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(owner + toRepositoryUrl(owner, name), true));
|
|
||||||
saveConfig();
|
|
||||||
}
|
}
|
||||||
catch (MalformedURLException e)
|
catch (MalformedURLException e)
|
||||||
{
|
{
|
||||||
@@ -279,6 +347,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)
|
public void removeRepository(String owner)
|
||||||
{
|
{
|
||||||
updateManager.removeRepository(owner);
|
updateManager.removeRepository(owner);
|
||||||
@@ -293,8 +369,8 @@ class ExternalPluginManager
|
|||||||
for (UpdateRepository repository : updateManager.getRepositories())
|
for (UpdateRepository repository : updateManager.getRepositories())
|
||||||
{
|
{
|
||||||
config.append(repository.getId());
|
config.append(repository.getId());
|
||||||
config.append(":");
|
config.append("|");
|
||||||
config.append(repository.getUrl().toString());
|
config.append(MiscUtils.urlToStringEncoded(repository.getUrl()));
|
||||||
config.append(";");
|
config.append(";");
|
||||||
}
|
}
|
||||||
config.deleteCharAt(config.lastIndexOf(";"));
|
config.deleteCharAt(config.lastIndexOf(";"));
|
||||||
@@ -335,7 +411,8 @@ class ExternalPluginManager
|
|||||||
}
|
}
|
||||||
else if (pluginDescriptor.type() == PluginType.EXTERNAL)
|
else if (pluginDescriptor.type() == PluginType.EXTERNAL)
|
||||||
{
|
{
|
||||||
log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL", clazz);
|
log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL",
|
||||||
|
clazz);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,16 +452,21 @@ class ExternalPluginManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig) throws PluginInstantiationException
|
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig)
|
||||||
|
throws PluginInstantiationException
|
||||||
{
|
{
|
||||||
net.runelite.client.plugins.PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class);
|
net.runelite.client.plugins.PluginDependency[] pluginDependencies =
|
||||||
|
clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class);
|
||||||
List<Plugin> deps = new ArrayList<>();
|
List<Plugin> deps = new ArrayList<>();
|
||||||
for (net.runelite.client.plugins.PluginDependency pluginDependency : pluginDependencies)
|
for (net.runelite.client.plugins.PluginDependency pluginDependency : pluginDependencies)
|
||||||
{
|
{
|
||||||
Optional<Plugin> dependency = Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream()).filter(p -> p.getClass() == pluginDependency.value()).findFirst();
|
Optional<Plugin> dependency =
|
||||||
|
Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream())
|
||||||
|
.filter(p -> p.getClass() == pluginDependency.value()).findFirst();
|
||||||
if (!dependency.isPresent())
|
if (!dependency.isPresent())
|
||||||
{
|
{
|
||||||
throw new PluginInstantiationException("Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName());
|
throw new PluginInstantiationException(
|
||||||
|
"Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName());
|
||||||
}
|
}
|
||||||
deps.add(dependency.get());
|
deps.add(dependency.get());
|
||||||
}
|
}
|
||||||
@@ -446,7 +528,9 @@ class ExternalPluginManager
|
|||||||
{
|
{
|
||||||
runelitePluginManager.startPlugin(plugin);
|
runelitePluginManager.startPlugin(plugin);
|
||||||
runelitePluginManager.add(plugin);
|
runelitePluginManager.add(plugin);
|
||||||
eventBus.post(ExternalPluginChanged.class, new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin, true));
|
eventBus.post(ExternalPluginChanged.class,
|
||||||
|
new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin,
|
||||||
|
true));
|
||||||
}
|
}
|
||||||
catch (PluginInstantiationException e)
|
catch (PluginInstantiationException e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package net.runelite.client.plugins.openosrs.externals;
|
package net.runelite.client.plugins.openosrs.externals;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import java.awt.Color;
|
import net.runelite.client.plugins.ExternalPluginManager;
|
||||||
import java.awt.Dimension;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
import java.awt.event.MouseAdapter;
|
import net.runelite.client.ui.PluginPanel;
|
||||||
import java.awt.event.MouseEvent;
|
import net.runelite.client.util.ImageUtil;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -16,25 +14,33 @@ import javax.swing.JScrollPane;
|
|||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import net.runelite.client.eventbus.EventBus;
|
import java.awt.BorderLayout;
|
||||||
import net.runelite.client.plugins.ExternalPluginManager;
|
import java.awt.Color;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import java.awt.Dimension;
|
||||||
import net.runelite.client.ui.PluginPanel;
|
import java.awt.event.MouseAdapter;
|
||||||
import net.runelite.client.util.ImageUtil;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
public class ExternalPluginManagerPanel extends PluginPanel
|
public class ExternalPluginManagerPanel extends PluginPanel
|
||||||
{
|
{
|
||||||
private static final ImageIcon ADD_ICON;
|
private static final ImageIcon ADD_ICON_RAW;
|
||||||
private static final ImageIcon ADD_HOVER_ICON;
|
private static final ImageIcon ADD_HOVER_ICON_RAW;
|
||||||
|
private static final ImageIcon ADD_ICON_GH;
|
||||||
|
private static final ImageIcon ADD_HOVER_ICON_GH;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
final BufferedImage addIcon =
|
final BufferedImage addIconRaw =
|
||||||
ImageUtil.recolorImage(
|
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_raw_icon.png");
|
||||||
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_icon.png"), ColorScheme.BRAND_BLUE
|
final BufferedImage addIconGh = ImageUtil
|
||||||
);
|
.resizeImage(ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "gh_icon.png"), 14, 14);
|
||||||
ADD_ICON = new ImageIcon(addIcon);
|
ADD_ICON_RAW = new ImageIcon(addIconRaw);
|
||||||
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
|
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;
|
private final ExternalPluginManager externalPluginManager;
|
||||||
@@ -73,13 +79,17 @@ public class ExternalPluginManagerPanel extends PluginPanel
|
|||||||
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
|
|
||||||
JLabel title = new JLabel();
|
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.setText("External Plugin Manager");
|
||||||
title.setForeground(Color.WHITE);
|
title.setForeground(Color.WHITE);
|
||||||
|
|
||||||
addRepo.setToolTipText("Add new repository");
|
addGHRepo.setToolTipText("Add new GitHub repository");
|
||||||
addRepo.addMouseListener(new MouseAdapter()
|
addGHRepo.addMouseListener(new MouseAdapter()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent mouseEvent)
|
public void mousePressed(MouseEvent mouseEvent)
|
||||||
@@ -91,36 +101,120 @@ public class ExternalPluginManagerPanel extends PluginPanel
|
|||||||
"Github Repository name:", name
|
"Github Repository name:", name
|
||||||
};
|
};
|
||||||
|
|
||||||
int option = JOptionPane.showConfirmDialog(null, message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
|
int option =
|
||||||
|
JOptionPane.showConfirmDialog(null, message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
|
||||||
if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals(""))
|
if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals(""))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExternalPluginManager.testRepository(owner.getText(), name.getText()))
|
if (externalPluginManager.doesGhRepoExist(owner.getText(), name.getText()))
|
||||||
{
|
{
|
||||||
JOptionPane.showMessageDialog(null, "This doesn't appear to be a valid repository.", "Error!", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, "This repository already exists.", "Error!",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
externalPluginManager.addRepository(owner.getText(), name.getText());
|
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.addGHRepository(owner.getText(), name.getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseEntered(MouseEvent mouseEvent)
|
public void mouseEntered(MouseEvent mouseEvent)
|
||||||
{
|
{
|
||||||
addRepo.setIcon(ADD_HOVER_ICON);
|
addGHRepo.setIcon(ADD_HOVER_ICON_GH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent mouseEvent)
|
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 (id.getText().startsWith("gh:") || id.getText().contains("|"))
|
||||||
|
{
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
"Repository id cannot begin with \"gh:\"\nor contain the pipe character '|'.", "Error!",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
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(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;
|
return titlePanel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,12 @@ public class RepositoryBox extends JPanel
|
|||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
String name = updateRepository.getId().replace(updateRepository.getUrl().toString(), "");
|
String name = updateRepository.getId();
|
||||||
String urlString = updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", "");
|
String urlString = updateRepository.getUrl().toString();
|
||||||
|
if (urlString.startsWith("/"))
|
||||||
|
{
|
||||||
|
urlString = urlString.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
JPanel titleWrapper = new JPanel(new BorderLayout());
|
JPanel titleWrapper = new JPanel(new BorderLayout());
|
||||||
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
@@ -145,11 +149,31 @@ public class RepositoryBox extends JPanel
|
|||||||
titleWrapper.add(titleActions, BorderLayout.EAST);
|
titleWrapper.add(titleActions, BorderLayout.EAST);
|
||||||
|
|
||||||
JMultilineLabel repository = new JMultilineLabel();
|
JMultilineLabel repository = new JMultilineLabel();
|
||||||
repository.setText(urlString.split("/", 2)[1]);
|
repository.setText(formatURL(urlString));
|
||||||
repository.setFont(smallFont);
|
repository.setFont(smallFont);
|
||||||
repository.setDisabledTextColor(Color.WHITE);
|
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(titleWrapper, BorderLayout.NORTH);
|
||||||
add(repository, BorderLayout.CENTER);
|
add(repository, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatURL(String url)
|
||||||
|
{
|
||||||
|
if (url.contains("githubusercontent"))
|
||||||
|
{
|
||||||
|
url = url.replace("raw.githubusercontent", "github").replace("/master/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package net.runelite.client.util;
|
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.Client;
|
||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.WorldType;
|
import net.runelite.api.WorldType;
|
||||||
import net.runelite.api.coords.WorldPoint;
|
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;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class MiscUtils
|
public class MiscUtils
|
||||||
{
|
{
|
||||||
@@ -170,4 +175,28 @@ public class MiscUtils
|
|||||||
}
|
}
|
||||||
return str;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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: 384 B |
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: 580 B |
Reference in New Issue
Block a user