diff --git a/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java b/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java index 4d64898bce..53e83b4869 100644 --- a/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java +++ b/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java @@ -1,22 +1,28 @@ package com.openosrs.client; +import com.google.common.base.Strings; import java.io.File; import java.io.IOException; import java.util.Properties; import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; public class OpenOSRS { public static final File OPENOSRS_DIR = new File(System.getProperty("user.home"), ".openosrs"); public static final File EXTERNALPLUGIN_DIR = new File(OPENOSRS_DIR, "plugins"); + public static final String PLUGIN_DEVELOPMENT_PATH = "plugin.development.path"; public static final String SYSTEM_VERSION; public static final String SYSTEM_API_VERSION; + @Getter(AccessLevel.PACKAGE) + private static final Properties properties = new Properties(); + public static String uuid = UUID.randomUUID().toString(); static { - Properties properties = new Properties(); try { properties.load(OpenOSRS.class.getResourceAsStream("/openosrs.properties")); @@ -25,10 +31,25 @@ public class OpenOSRS { e.printStackTrace(); } + SYSTEM_VERSION = properties.getProperty("oprs.version", "0.0.0"); SYSTEM_API_VERSION = properties.getProperty("oprs.api.version"); } + public static String[] getPluginDevelopmentPath() + { + // First check if property supplied as environment variable PLUGIN_DEVELOPMENT_PATHS + String developmentPluginPaths = System.getenv(PLUGIN_DEVELOPMENT_PATH.replace('.', '_').toUpperCase()); + + if (Strings.isNullOrEmpty(developmentPluginPaths)) + { + // Otherwise check the property file + developmentPluginPaths = properties.getProperty(PLUGIN_DEVELOPMENT_PATH); + } + + return Strings.isNullOrEmpty(developmentPluginPaths) ? new String[0] : developmentPluginPaths.split(";"); + } + public static void preload() { } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java index 30abbfa8eb..cbbe334f48 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java @@ -5,6 +5,7 @@ import java.io.Closeable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -19,6 +20,7 @@ import org.pf4j.CompoundPluginLoader; import org.pf4j.CompoundPluginRepository; import org.pf4j.DefaultPluginManager; import org.pf4j.DependencyResolver; +import org.pf4j.DevelopmentPluginRepository; import org.pf4j.JarPluginLoader; import org.pf4j.JarPluginRepository; import org.pf4j.ManifestPluginDescriptorFinder; @@ -35,12 +37,9 @@ import org.pf4j.RuntimeMode; @Slf4j class OPRSExternalPf4jPluginManager extends DefaultPluginManager { - private final OPRSExternalPluginManager externalPluginManager; - - public OPRSExternalPf4jPluginManager(OPRSExternalPluginManager externalPluginManager) + public OPRSExternalPf4jPluginManager() { super(OpenOSRS.EXTERNALPLUGIN_DIR.toPath()); - this.externalPluginManager = externalPluginManager; } @Override @@ -68,8 +67,30 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager { CompoundPluginRepository compoundPluginRepository = new CompoundPluginRepository(); - JarPluginRepository jarPluginRepository = new JarPluginRepository(getPluginsRoot()); - compoundPluginRepository.add(jarPluginRepository); + if (isNotDevelopment()) + { + JarPluginRepository jarPluginRepository = new JarPluginRepository(getPluginsRoot()); + compoundPluginRepository.add(jarPluginRepository); + } + + if (isDevelopment()) + { + for (String developmentPluginPath : OpenOSRS.getPluginDevelopmentPath()) + { + DevelopmentPluginRepository developmentPluginRepository = new DevelopmentPluginRepository(Paths.get(developmentPluginPath)) + { + @Override + public boolean deletePluginPath(Path pluginPath) + { + // Do nothing, because we'd be deleting our sources! + return filter.accept(pluginPath.toFile()); + } + }; + + developmentPluginRepository.setFilter(new OPRSExternalPluginFileFilter()); + compoundPluginRepository.add(developmentPluginRepository); + } + } return compoundPluginRepository; } @@ -121,6 +142,12 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager { if (!(e instanceof PluginAlreadyLoadedException)) { + if (!OPRSExternalPluginManager.isDevelopmentMode()) + { + String plugin = pluginPath.toString().substring(pluginsRoots.get(0).toString().length() + 1); + duplicatePlugins.add(plugin); + } + log.error("Could not load plugin {}", pluginPath, e); } } @@ -220,7 +247,7 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager @Override public RuntimeMode getRuntimeMode() { - return RuntimeMode.DEPLOYMENT; + return OPRSExternalPluginManager.isDevelopmentMode() ? RuntimeMode.DEVELOPMENT : RuntimeMode.DEPLOYMENT; } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java index dd6c86d1ee..81c63f272d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java @@ -33,6 +33,7 @@ import com.google.inject.CreationException; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; +import com.openosrs.client.OpenOSRS; import static com.openosrs.client.OpenOSRS.EXTERNALPLUGIN_DIR; import static com.openosrs.client.OpenOSRS.SYSTEM_API_VERSION; import com.openosrs.client.config.OpenOSRSConfig; @@ -108,6 +109,8 @@ public class OPRSExternalPluginManager private final ConfigManager configManager; private final Map pluginsMap = new HashMap<>(); @Getter(AccessLevel.PUBLIC) + private static final boolean developmentMode = OpenOSRS.getPluginDevelopmentPath().length > 0; + @Getter(AccessLevel.PUBLIC) private final Map> pluginsInfoMap = new HashMap<>(); private final Groups groups; @Getter(AccessLevel.PUBLIC) @@ -143,7 +146,7 @@ public class OPRSExternalPluginManager private void initPluginManager() { - externalPluginManager = new OPRSExternalPf4jPluginManager(this); + externalPluginManager = new OPRSExternalPf4jPluginManager(); externalPluginManager.setSystemVersion(SYSTEM_API_VERSION); } @@ -826,29 +829,39 @@ public class OPRSExternalPluginManager try { - PluginInfo.PluginRelease latest = updateManager.getLastPluginRelease(pluginId); - - // Null version returns the last release version of this plugin for given system version - if (latest == null) + if (!developmentMode) { - try + PluginInfo.PluginRelease latest = updateManager.getLastPluginRelease(pluginId); + + // Null version returns the last release version of this plugin for given system version + if (latest == null) { - SwingUtil.syncExec(() -> - JOptionPane.showMessageDialog(ClientUI.getFrame(), - pluginId + " is outdated and cannot be installed", - "Installation error", - JOptionPane.ERROR_MESSAGE)); - } - catch (InvocationTargetException | InterruptedException ignored) - { - return false; + try + { + SwingUtil.syncExec(() -> + JOptionPane.showMessageDialog(ClientUI.getFrame(), + pluginId + " is outdated and cannot be installed", + "Installation error", + JOptionPane.ERROR_MESSAGE)); + } + catch (InvocationTargetException | InterruptedException ignored) + { + return false; + } + + return true; } - return true; + updateManager.installPlugin(pluginId, null); + scanAndInstantiate(loadPlugin(pluginId), true, true); + } + else + { + // In development mode our plugin will already be present in a repository, so we can just load it + externalPluginManager.loadPlugins(); + externalPluginManager.startPlugin(pluginId); } - updateManager.installPlugin(pluginId, null); - scanAndInstantiate(loadPlugin(pluginId), true, true); ExternalPluginsChanged event = new ExternalPluginsChanged(null); eventBus.post(event); groups.broadcastSring("STARTEXTERNAL;" + pluginId); @@ -908,6 +921,11 @@ public class OPRSExternalPluginManager log.info("Not updating external plugins since there is more than 1 client open"); return; } + else if (developmentMode) + { + log.info("Not updating because we're running in developer mode"); + return; + } OpenOSRSSplashScreen.stage(.59, "Updating external plugins");