Add Fake Plugin factory
This commit is contained in:
parent
6295f456a8
commit
f1f8688e44
@ -0,0 +1,84 @@
|
||||
package eu.mikroskeem.utils.bukkit.fakeplugin;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.Delegate;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class AbstractFakePlugin extends PluginBase implements PluginLoader {
|
||||
public final Plugin loadPlugin(File file) throws InvalidPluginException, UnknownDependencyException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public final PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public Pattern[] getPluginFileFilters() {
|
||||
return new Pattern[0];
|
||||
}
|
||||
|
||||
public Map<Class<? extends Event>, Set<RegisteredListener>> createRegisteredListeners(Listener listener, Plugin plugin) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public void enablePlugin(Plugin plugin) {}
|
||||
public void disablePlugin(Plugin plugin) {}
|
||||
|
||||
@Override public boolean isEnabled() { return true; }
|
||||
public PluginLoader getPluginLoader()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
private interface Excludes {
|
||||
PluginLoader getPluginLoader();
|
||||
PluginDescriptionFile getDescription();
|
||||
String getName();
|
||||
boolean isEnabled();
|
||||
}
|
||||
|
||||
/* Forward most calls to parent plugin */
|
||||
@Delegate(excludes = AbstractFakePlugin.Excludes.class, types = {
|
||||
CommandExecutor.class, TabCompleter.class, Plugin.class
|
||||
})
|
||||
private final Plugin plugin;
|
||||
|
||||
@Getter private PluginDescriptionFile description;
|
||||
public AbstractFakePlugin(Plugin plugin,
|
||||
String pluginName,
|
||||
String pluginVersion,
|
||||
String mainClass,
|
||||
String descriptionStr,
|
||||
String author){
|
||||
this.plugin = plugin;
|
||||
|
||||
/* Generate plugin description file */
|
||||
StringJoiner sj = new StringJoiner("\n");
|
||||
sj.add(String.format("name: %s", pluginName));
|
||||
sj.add(String.format("version: %s", pluginVersion==null?"1.0-STUB":pluginVersion));
|
||||
sj.add(String.format("description: %s", descriptionStr));
|
||||
sj.add(String.format("author: %s", author));
|
||||
sj.add(String.format("main: %s", mainClass));
|
||||
|
||||
try {
|
||||
description = new PluginDescriptionFile(new StringReader(sj.toString()));
|
||||
} catch (InvalidDescriptionException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return description.getFullName();
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package eu.mikroskeem.utils.bukkit.fakeplugin;
|
||||
|
||||
import eu.mikroskeem.utils.reflect.Reflect;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.SimplePluginManager;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class FakePluginFactory {
|
||||
private final List<AbstractFakePlugin> fakePlugins = new ArrayList<>();
|
||||
|
||||
private final Plugin plugin;
|
||||
private final List<Plugin> plugins;
|
||||
@Getter private final Map<String, Plugin> lookupNames;
|
||||
private final boolean isPaper;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public FakePluginFactory(Plugin parentPlugin){
|
||||
this.plugin = parentPlugin;
|
||||
Field lookupNamesField, pluginsField;
|
||||
if(plugin.getServer().getPluginManager().getClass() != SimplePluginManager.class){
|
||||
throw new RuntimeException("Server PluginManager is not SimplePluginManager");
|
||||
}
|
||||
isPaper = Reflect.getMethod(Bukkit.class, "getTPS") != null;
|
||||
try {
|
||||
pluginsField = checkNotNull(Reflect.getField(
|
||||
SimplePluginManager.class,
|
||||
"plugins"));
|
||||
lookupNamesField = checkNotNull(Reflect.getField(
|
||||
SimplePluginManager.class,
|
||||
"lookupNames"));
|
||||
plugins = (List<Plugin>) checkNotNull(Reflect.readField(pluginsField,
|
||||
plugin.getServer().getPluginManager()));
|
||||
lookupNames = (Map<String, Plugin>) checkNotNull(Reflect.readField(lookupNamesField,
|
||||
plugin.getServer().getPluginManager()));
|
||||
} catch (NullPointerException e){
|
||||
throw new RuntimeException("Failed to get 'plugins' and 'lookupNames' field!");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized <T extends AbstractFakePlugin> T newPlugin(String name, String version, String mainClass){
|
||||
T fakePlugin = (T) new AbstractFakePlugin(plugin, name, version, mainClass, null, null){};
|
||||
fakePlugins.add(fakePlugin);
|
||||
return fakePlugin;
|
||||
}
|
||||
|
||||
public synchronized <T extends AbstractFakePlugin> void addPlugin(T plugin){
|
||||
/* Note: took me 5 hours to realize lookupNames map keys are lower case (on PaperSpigot)
|
||||
* Note 2: Took me another 5 hours to realize lower case lookupNames keys are *only* on PaperSpigot
|
||||
*/
|
||||
String lookupName = isPaper?plugin.getName().toLowerCase(Locale.ENGLISH):plugin.getName();
|
||||
lookupNames.put(lookupName, plugin);
|
||||
plugins.add(plugin);
|
||||
fakePlugins.add(plugin);
|
||||
}
|
||||
|
||||
public synchronized <T extends AbstractFakePlugin> void removePlugin(T plugin){
|
||||
if (plugins.contains(plugin)) plugins.remove(plugin);
|
||||
if (lookupNames.containsKey(plugin.getName())) {
|
||||
String lookupName = isPaper?plugin.getName().toLowerCase(Locale.ENGLISH):plugin.getName();
|
||||
lookupNames.remove(lookupName);
|
||||
}
|
||||
if (fakePlugins.contains(plugin)) fakePlugins.remove(plugin);
|
||||
}
|
||||
|
||||
/* Note: Not needed, SimplePluginManager handles plugin removal already
|
||||
synchronized void removeAllPlugins() {
|
||||
fakePlugins.forEach(this::removePlugin);
|
||||
}
|
||||
*/
|
||||
}
|
Loading…
Reference in New Issue
Block a user