Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-09-12 05:16:12 +02:00
8 changed files with 136 additions and 5 deletions

View File

@@ -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;

View File

@@ -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());
}
} }

View File

@@ -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 ->
{ {

View File

@@ -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();

View File

@@ -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
* *

View File

@@ -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)
{ {

View File

@@ -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 ->

View File

@@ -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();
} }
} }