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 {};
/**
* 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;
/**
@@ -62,6 +74,9 @@ public @interface PluginDescriptor
boolean developerPlugin() default false;
/**
* If this plugin should be loaded when there is no {@link net.runelite.api.Client}
*/
boolean loadWhenOutdated() default false;
boolean loadInSafeMode() default true;

View File

@@ -41,8 +41,10 @@ import com.google.inject.Module;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -405,6 +407,19 @@ public class PluginManager
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);
try
@@ -470,6 +485,18 @@ public class PluginManager
final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
final String keyName = Strings.isNullOrEmpty(pluginDescriptor.configName()) ? plugin.getClass().getSimpleName() : pluginDescriptor.configName();
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)
@@ -671,4 +698,40 @@ public class PluginManager
}
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)
{
pluginToggle.setConflicts(pluginConfig.getConflicts());
pluginToggle.setSelected(pluginManager.isPluginEnabled(pluginConfig.getPlugin()));
pluginToggle.addItemListener(i ->
{

View File

@@ -75,11 +75,11 @@ public class ConfigPlugin extends Plugin
pluginListPanel.addFakePlugin(new PluginConfigurationDescriptor(
"RuneLite", "RuneLite client settings",
new String[]{"client", "notification", "size", "position", "window", "chrome", "focus", "font", "overlay", "tooltip", "infobox"},
null, runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig)
runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig)
),
new PluginConfigurationDescriptor(
"Chat Color", "Recolor chat text", new String[]{"colour", "messages"},
null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
));
pluginListPanel.rebuildPluginList();

View File

@@ -24,8 +24,10 @@
*/
package net.runelite.client.plugins.config;
import java.util.List;
import javax.annotation.Nullable;
import javax.swing.JMenuItem;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigDescriptor;
@@ -35,6 +37,7 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.util.LinkBrowser;
@Value
@RequiredArgsConstructor
class PluginConfigurationDescriptor
{
private final String name;
@@ -52,11 +55,19 @@ class PluginConfigurationDescriptor
@Nullable
private final ConfigDescriptor configDescriptor;
@Nullable
private final List<String> conflicts;
boolean hasConfigurables()
{
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
*

View File

@@ -77,7 +77,7 @@ class PluginListItem extends JPanel implements SearchablePlugin
private final List<String> keywords = new ArrayList<>();
private final JToggleButton pinButton;
private final JToggleButton onOffToggle;
private final PluginToggleButton onOffToggle;
static
{
@@ -232,6 +232,7 @@ class PluginListItem extends JPanel implements SearchablePlugin
add(nameLabel, BorderLayout.CENTER);
onOffToggle = new PluginToggleButton();
onOffToggle.setConflicts(pluginConfig.getConflicts());
buttonPanel.add(onOffToggle);
if (pluginConfig.getPlugin() != null)
{

View File

@@ -207,6 +207,9 @@ class PluginListPanel extends PluginPanel
PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
Config config = pluginManager.getPluginConfigProxy(plugin);
ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
List<String> conflicts = pluginManager.conflictsForPlugin(plugin).stream()
.map(Plugin::getName)
.collect(Collectors.toList());
return new PluginConfigurationDescriptor(
descriptor.name(),
@@ -214,7 +217,8 @@ class PluginListPanel extends PluginPanel
descriptor.tags(),
plugin,
config,
configDescriptor);
configDescriptor,
conflicts);
})
)
.map(desc ->

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.config;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JToggleButton;
import net.runelite.client.ui.ColorScheme;
@@ -52,12 +53,47 @@ class PluginToggleButton extends JToggleButton
));
}
private String conflictString = "";
public PluginToggleButton()
{
super(OFF_SWITCHER);
setSelectedIcon(ON_SWITCHER);
SwingUtil.removeButtonDecorations(this);
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();
}
}