Merge remote-tracking branch 'runelite/master'
This commit is contained in:
@@ -53,6 +53,18 @@ public @interface PluginDescriptor
|
|||||||
*/
|
*/
|
||||||
String[] tags() default {};
|
String[] tags() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of plugin names that are mutually exclusive with this plugin. Any plugins
|
||||||
|
* with a name or conflicts value that matches this will be disabled when this plugin
|
||||||
|
* is started
|
||||||
|
*/
|
||||||
|
String[] conflicts() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this plugin should be defaulted to on. Plugin-Hub plugins should always
|
||||||
|
* have this set to true (the default), since having them off by defaults means
|
||||||
|
* the user has to install the plugin, then separately enable it, which is confusing.
|
||||||
|
*/
|
||||||
boolean enabledByDefault() default true;
|
boolean enabledByDefault() default true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,6 +74,9 @@ public @interface PluginDescriptor
|
|||||||
|
|
||||||
boolean developerPlugin() default false;
|
boolean developerPlugin() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this plugin should be loaded when there is no {@link net.runelite.api.Client}
|
||||||
|
*/
|
||||||
boolean loadWhenOutdated() default false;
|
boolean loadWhenOutdated() default false;
|
||||||
|
|
||||||
boolean loadInSafeMode() default true;
|
boolean loadInSafeMode() default true;
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ import com.google.inject.Module;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -405,6 +407,19 @@ public class PluginManager
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Plugin> conflicts = conflictsForPlugin(plugin);
|
||||||
|
for (Plugin conflict : conflicts)
|
||||||
|
{
|
||||||
|
if (isPluginEnabled(conflict))
|
||||||
|
{
|
||||||
|
setPluginEnabled(conflict, false);
|
||||||
|
}
|
||||||
|
if (activePlugins.contains(conflict))
|
||||||
|
{
|
||||||
|
stopPlugin(conflict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
activePlugins.add(plugin);
|
activePlugins.add(plugin);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -470,6 +485,18 @@ public class PluginManager
|
|||||||
final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||||
final String keyName = Strings.isNullOrEmpty(pluginDescriptor.configName()) ? plugin.getClass().getSimpleName() : pluginDescriptor.configName();
|
final String keyName = Strings.isNullOrEmpty(pluginDescriptor.configName()) ? plugin.getClass().getSimpleName() : pluginDescriptor.configName();
|
||||||
configManager.setConfiguration(RuneLiteConfig.GROUP_NAME, keyName.toLowerCase(), String.valueOf(enabled));
|
configManager.setConfiguration(RuneLiteConfig.GROUP_NAME, keyName.toLowerCase(), String.valueOf(enabled));
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
List<Plugin> conflicts = conflictsForPlugin(plugin);
|
||||||
|
for (Plugin conflict : conflicts)
|
||||||
|
{
|
||||||
|
if (isPluginEnabled(conflict))
|
||||||
|
{
|
||||||
|
setPluginEnabled(conflict, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPluginEnabled(Plugin plugin)
|
public boolean isPluginEnabled(Plugin plugin)
|
||||||
@@ -671,4 +698,40 @@ public class PluginManager
|
|||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Plugin> conflictsForPlugin(Plugin plugin)
|
||||||
|
{
|
||||||
|
Set<String> conflicts;
|
||||||
|
{
|
||||||
|
PluginDescriptor desc = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||||
|
conflicts = new HashSet<>(Arrays.asList(desc.conflicts()));
|
||||||
|
conflicts.add(desc.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins.stream()
|
||||||
|
.filter(p ->
|
||||||
|
{
|
||||||
|
if (p == plugin)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginDescriptor desc = p.getClass().getAnnotation(PluginDescriptor.class);
|
||||||
|
if (conflicts.contains(desc.name()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String conflict : desc.conflicts())
|
||||||
|
{
|
||||||
|
if (conflicts.contains(conflict))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ class ConfigPanel extends PluginPanel
|
|||||||
|
|
||||||
if (pluginConfig.getPlugin() != null)
|
if (pluginConfig.getPlugin() != null)
|
||||||
{
|
{
|
||||||
|
pluginToggle.setConflicts(pluginConfig.getConflicts());
|
||||||
pluginToggle.setSelected(pluginManager.isPluginEnabled(pluginConfig.getPlugin()));
|
pluginToggle.setSelected(pluginManager.isPluginEnabled(pluginConfig.getPlugin()));
|
||||||
pluginToggle.addItemListener(i ->
|
pluginToggle.addItemListener(i ->
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,11 +75,11 @@ public class ConfigPlugin extends Plugin
|
|||||||
pluginListPanel.addFakePlugin(new PluginConfigurationDescriptor(
|
pluginListPanel.addFakePlugin(new PluginConfigurationDescriptor(
|
||||||
"RuneLite", "RuneLite client settings",
|
"RuneLite", "RuneLite client settings",
|
||||||
new String[]{"client", "notification", "size", "position", "window", "chrome", "focus", "font", "overlay", "tooltip", "infobox"},
|
new String[]{"client", "notification", "size", "position", "window", "chrome", "focus", "font", "overlay", "tooltip", "infobox"},
|
||||||
null, runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig)
|
runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig)
|
||||||
),
|
),
|
||||||
new PluginConfigurationDescriptor(
|
new PluginConfigurationDescriptor(
|
||||||
"Chat Color", "Recolor chat text", new String[]{"colour", "messages"},
|
"Chat Color", "Recolor chat text", new String[]{"colour", "messages"},
|
||||||
null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
|
chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
|
||||||
));
|
));
|
||||||
pluginListPanel.rebuildPluginList();
|
pluginListPanel.rebuildPluginList();
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,10 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.config;
|
package net.runelite.client.plugins.config;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import net.runelite.client.config.Config;
|
import net.runelite.client.config.Config;
|
||||||
import net.runelite.client.config.ConfigDescriptor;
|
import net.runelite.client.config.ConfigDescriptor;
|
||||||
@@ -35,6 +37,7 @@ import net.runelite.client.plugins.Plugin;
|
|||||||
import net.runelite.client.util.LinkBrowser;
|
import net.runelite.client.util.LinkBrowser;
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
|
@RequiredArgsConstructor
|
||||||
class PluginConfigurationDescriptor
|
class PluginConfigurationDescriptor
|
||||||
{
|
{
|
||||||
private final String name;
|
private final String name;
|
||||||
@@ -52,11 +55,19 @@ class PluginConfigurationDescriptor
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final ConfigDescriptor configDescriptor;
|
private final ConfigDescriptor configDescriptor;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final List<String> conflicts;
|
||||||
|
|
||||||
boolean hasConfigurables()
|
boolean hasConfigurables()
|
||||||
{
|
{
|
||||||
return configDescriptor != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden());
|
return configDescriptor != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PluginConfigurationDescriptor(String name, String description, String[] tags, Config config, ConfigDescriptor configDescriptor)
|
||||||
|
{
|
||||||
|
this(name, description, tags, null, config, configDescriptor, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a menu item for linking to a support page for the plugin
|
* Creates a menu item for linking to a support page for the plugin
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class PluginListItem extends JPanel implements SearchablePlugin
|
|||||||
private final List<String> keywords = new ArrayList<>();
|
private final List<String> keywords = new ArrayList<>();
|
||||||
|
|
||||||
private final JToggleButton pinButton;
|
private final JToggleButton pinButton;
|
||||||
private final JToggleButton onOffToggle;
|
private final PluginToggleButton onOffToggle;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -232,6 +232,7 @@ class PluginListItem extends JPanel implements SearchablePlugin
|
|||||||
add(nameLabel, BorderLayout.CENTER);
|
add(nameLabel, BorderLayout.CENTER);
|
||||||
|
|
||||||
onOffToggle = new PluginToggleButton();
|
onOffToggle = new PluginToggleButton();
|
||||||
|
onOffToggle.setConflicts(pluginConfig.getConflicts());
|
||||||
buttonPanel.add(onOffToggle);
|
buttonPanel.add(onOffToggle);
|
||||||
if (pluginConfig.getPlugin() != null)
|
if (pluginConfig.getPlugin() != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -207,6 +207,9 @@ class PluginListPanel extends PluginPanel
|
|||||||
PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||||
Config config = pluginManager.getPluginConfigProxy(plugin);
|
Config config = pluginManager.getPluginConfigProxy(plugin);
|
||||||
ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
|
ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
|
||||||
|
List<String> conflicts = pluginManager.conflictsForPlugin(plugin).stream()
|
||||||
|
.map(Plugin::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return new PluginConfigurationDescriptor(
|
return new PluginConfigurationDescriptor(
|
||||||
descriptor.name(),
|
descriptor.name(),
|
||||||
@@ -214,7 +217,8 @@ class PluginListPanel extends PluginPanel
|
|||||||
descriptor.tags(),
|
descriptor.tags(),
|
||||||
plugin,
|
plugin,
|
||||||
config,
|
config,
|
||||||
configDescriptor);
|
configDescriptor,
|
||||||
|
conflicts);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.map(desc ->
|
.map(desc ->
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.config;
|
|||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.List;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.JToggleButton;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
@@ -52,12 +53,47 @@ class PluginToggleButton extends JToggleButton
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String conflictString = "";
|
||||||
|
|
||||||
public PluginToggleButton()
|
public PluginToggleButton()
|
||||||
{
|
{
|
||||||
super(OFF_SWITCHER);
|
super(OFF_SWITCHER);
|
||||||
setSelectedIcon(ON_SWITCHER);
|
setSelectedIcon(ON_SWITCHER);
|
||||||
SwingUtil.removeButtonDecorations(this);
|
SwingUtil.removeButtonDecorations(this);
|
||||||
setPreferredSize(new Dimension(25, 0));
|
setPreferredSize(new Dimension(25, 0));
|
||||||
SwingUtil.addModalTooltip(this, "Disable plugin", "Enable plugin");
|
addItemListener(l -> updateTooltip());
|
||||||
|
updateTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTooltip()
|
||||||
|
{
|
||||||
|
setToolTipText(isSelected() ? "Disable plugin" : "<html>Enable plugin" + conflictString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConflicts(List<String> conflicts)
|
||||||
|
{
|
||||||
|
if (conflicts != null && !conflicts.isEmpty())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder("<br>Conflicts with ");
|
||||||
|
for (int i = 0; i < conflicts.size() - 2; i++)
|
||||||
|
{
|
||||||
|
sb.append(conflicts.get(i));
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
if (conflicts.size() > 2)
|
||||||
|
{
|
||||||
|
sb.append(conflicts.get(conflicts.size() - 2));
|
||||||
|
sb.append(" and ");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(conflicts.get(conflicts.size() - 1));
|
||||||
|
conflictString = sb.toString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conflictString = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user