Fix BungeeCord multi plugin management
This commit is contained in:
parent
ff1bfc2514
commit
94664286e5
5 changed files with 32 additions and 77 deletions
|
|
@ -4,10 +4,10 @@ import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
@ -21,7 +21,6 @@ import net.frankheijden.serverutils.bungee.events.BungeePluginDisableEvent;
|
||||||
import net.frankheijden.serverutils.bungee.events.BungeePluginEnableEvent;
|
import net.frankheijden.serverutils.bungee.events.BungeePluginEnableEvent;
|
||||||
import net.frankheijden.serverutils.bungee.events.BungeePluginLoadEvent;
|
import net.frankheijden.serverutils.bungee.events.BungeePluginLoadEvent;
|
||||||
import net.frankheijden.serverutils.bungee.events.BungeePluginUnloadEvent;
|
import net.frankheijden.serverutils.bungee.events.BungeePluginUnloadEvent;
|
||||||
import net.frankheijden.serverutils.bungee.reflection.RLibraryLoader;
|
|
||||||
import net.frankheijden.serverutils.bungee.reflection.RPluginClassLoader;
|
import net.frankheijden.serverutils.bungee.reflection.RPluginClassLoader;
|
||||||
import net.frankheijden.serverutils.bungee.reflection.RPluginManager;
|
import net.frankheijden.serverutils.bungee.reflection.RPluginManager;
|
||||||
import net.frankheijden.serverutils.common.entities.ServerUtilsPluginDescription;
|
import net.frankheijden.serverutils.common.entities.ServerUtilsPluginDescription;
|
||||||
|
|
@ -34,6 +33,7 @@ import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.plugin.PluginDescription;
|
import net.md_5.bungee.api.plugin.PluginDescription;
|
||||||
|
import net.md_5.bungee.api.plugin.PluginManager;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
public class BungeePluginManager extends AbstractPluginManager<Plugin, BungeePluginDescription> {
|
public class BungeePluginManager extends AbstractPluginManager<Plugin, BungeePluginDescription> {
|
||||||
|
|
@ -72,35 +72,25 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin, BungeePlu
|
||||||
public PluginResults<Plugin> loadPluginDescriptions(List<BungeePluginDescription> descriptions) {
|
public PluginResults<Plugin> loadPluginDescriptions(List<BungeePluginDescription> descriptions) {
|
||||||
PluginResults<Plugin> loadResults = new PluginResults<>();
|
PluginResults<Plugin> loadResults = new PluginResults<>();
|
||||||
|
|
||||||
|
PluginManager proxyPluginManager = proxy.getPluginManager();
|
||||||
|
Map<String, PluginDescription> toLoad = RPluginManager.getToLoad(proxyPluginManager);
|
||||||
|
if (toLoad == null) toLoad = new HashMap<>(descriptions.size());
|
||||||
|
|
||||||
for (BungeePluginDescription description : descriptions) {
|
for (BungeePluginDescription description : descriptions) {
|
||||||
PluginDescription desc = description.getDescription();
|
PluginDescription desc = description.getDescription();
|
||||||
Plugin plugin;
|
toLoad.put(desc.getName(), desc);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
RPluginManager.setToLoad(proxyPluginManager, toLoad);
|
||||||
Object libraryLoader = RPluginManager.getLibraryLoader(proxy.getPluginManager());
|
proxyPluginManager.loadPlugins();
|
||||||
ClassLoader classLoader = RLibraryLoader.createLoader(libraryLoader, desc);
|
|
||||||
URLClassLoader loader = (URLClassLoader) RPluginClassLoader.newInstance(
|
|
||||||
proxy,
|
|
||||||
desc,
|
|
||||||
desc.getFile(),
|
|
||||||
classLoader
|
|
||||||
);
|
|
||||||
|
|
||||||
Class<?> main = loader.loadClass(desc.getMain());
|
for (BungeePluginDescription description : descriptions) {
|
||||||
plugin = (Plugin) main.getDeclaredConstructor().newInstance();
|
Optional<Plugin> pluginOptional = getPlugin(description.getId());
|
||||||
|
if (!pluginOptional.isPresent()) return loadResults.addResult(description.getId(), Result.ERROR);
|
||||||
|
|
||||||
RPluginManager.getPlugins(proxy.getPluginManager()).put(description.getId(), plugin);
|
Plugin plugin = pluginOptional.get();
|
||||||
proxy.getPluginManager().callEvent(new BungeePluginLoadEvent(plugin, PluginEvent.Stage.PRE));
|
proxyPluginManager.callEvent(new BungeePluginLoadEvent(plugin, PluginEvent.Stage.PRE));
|
||||||
plugin.onLoad();
|
proxyPluginManager.callEvent(new BungeePluginLoadEvent(plugin, PluginEvent.Stage.POST));
|
||||||
} catch (Throwable th) {
|
|
||||||
proxy.getLogger().log(Level.WARNING, "Error loading plugin " + description.getId(), th);
|
|
||||||
return loadResults.addResult(description.getId(), Result.ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy.getLogger().log(Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[] {
|
|
||||||
desc.getName(), desc.getVersion(), desc.getAuthor()
|
|
||||||
});
|
|
||||||
proxy.getPluginManager().callEvent(new BungeePluginLoadEvent(plugin, PluginEvent.Stage.POST));
|
|
||||||
loadResults.addResult(description.getId(), plugin);
|
loadResults.addResult(description.getId(), plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +124,7 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin, BungeePlu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPluginEnabled(String pluginId) {
|
public boolean isPluginEnabled(String pluginId) {
|
||||||
return proxy.getPluginManager().getPlugin(pluginId) != null;
|
return false; // Not supported on BungeeCord.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -170,11 +160,12 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin, BungeePlu
|
||||||
proxy.getPluginManager().unregisterCommands(plugin);
|
proxy.getPluginManager().unregisterCommands(plugin);
|
||||||
proxy.getPluginManager().unregisterListeners(plugin);
|
proxy.getPluginManager().unregisterListeners(plugin);
|
||||||
proxy.getScheduler().cancel(plugin);
|
proxy.getScheduler().cancel(plugin);
|
||||||
|
plugin.getExecutorService().shutdown();
|
||||||
|
|
||||||
List<Closeable> closeables = new ArrayList<>();
|
List<Closeable> closeables = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
RPluginManager.clearPlugin(proxy.getPluginManager(), plugin);
|
RPluginManager.clearPlugin(proxy.getPluginManager(), plugin);
|
||||||
addIfInstance(closeables, RPluginClassLoader.getPluginClassLoader(plugin));
|
addIfInstance(closeables, RPluginClassLoader.removePluginClassLoader(plugin));
|
||||||
addIfInstance(closeables, plugin.getClass().getClassLoader());
|
addIfInstance(closeables, plugin.getClass().getClassLoader());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package net.frankheijden.serverutils.bungee.reflection;
|
|
||||||
|
|
||||||
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
|
||||||
import net.md_5.bungee.api.plugin.PluginDescription;
|
|
||||||
|
|
||||||
public class RLibraryLoader {
|
|
||||||
|
|
||||||
private static final MinecraftReflection reflection = MinecraftReflection
|
|
||||||
.of("net.md_5.bungee.api.plugin.LibraryLoader");
|
|
||||||
|
|
||||||
private RLibraryLoader() {}
|
|
||||||
|
|
||||||
public static ClassLoader createLoader(Object instance, PluginDescription desc) {
|
|
||||||
return instance == null ? null : reflection.invoke(instance, "createLoader", desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
package net.frankheijden.serverutils.bungee.reflection;
|
package net.frankheijden.serverutils.bungee.reflection;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import dev.frankheijden.minecraftreflection.ClassObject;
|
|
||||||
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.plugin.PluginDescription;
|
|
||||||
|
|
||||||
public class RPluginClassLoader {
|
public class RPluginClassLoader {
|
||||||
|
|
||||||
|
|
@ -16,23 +12,9 @@ public class RPluginClassLoader {
|
||||||
private RPluginClassLoader() {}
|
private RPluginClassLoader() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of a PluginClassLoader from given parameters.
|
* Removes the PluginClassLoader of a specific plugin.
|
||||||
*/
|
*/
|
||||||
public static Object newInstance(ProxyServer proxy, PluginDescription desc, File file, ClassLoader classLoader) {
|
public static Object removePluginClassLoader(Plugin plugin) {
|
||||||
return reflection.newInstance(
|
|
||||||
ClassObject.of(ProxyServer.class, proxy),
|
|
||||||
ClassObject.of(PluginDescription.class, desc),
|
|
||||||
ClassObject.of(File.class, file),
|
|
||||||
ClassObject.of(ClassLoader.class, classLoader)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the PluginClassLoader of a specific plugin.
|
|
||||||
* @param plugin The plugin to lookup the PluginClassLoader for.
|
|
||||||
* @return The PluginClassLoader.
|
|
||||||
*/
|
|
||||||
public static Object getPluginClassLoader(Plugin plugin) {
|
|
||||||
Set<Object> allLoaders = reflection.get(null, "allLoaders");
|
Set<Object> allLoaders = reflection.get(null, "allLoaders");
|
||||||
if (allLoaders == null) return null;
|
if (allLoaders == null) return null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
||||||
import net.frankheijden.serverutils.common.utils.MapUtils;
|
import net.frankheijden.serverutils.common.utils.MapUtils;
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.api.plugin.PluginDescription;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
public class RPluginManager {
|
public class RPluginManager {
|
||||||
|
|
@ -26,10 +27,6 @@ public class RPluginManager {
|
||||||
MapUtils.remove(reflection.get(instance, "toLoad"), pluginName);
|
MapUtils.remove(reflection.get(instance, "toLoad"), pluginName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Plugin> getPlugins(Object instance) {
|
|
||||||
return reflection.get(instance, "plugins");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Yaml getYaml(Object instance) {
|
public static Yaml getYaml(Object instance) {
|
||||||
return reflection.get(instance, "yaml");
|
return reflection.get(instance, "yaml");
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +35,14 @@ public class RPluginManager {
|
||||||
return reflection.get(instance, "commandMap");
|
return reflection.get(instance, "commandMap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<String, PluginDescription> getToLoad(Object pluginManager) {
|
||||||
|
return reflection.get(pluginManager, "toLoad");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setToLoad(Object pluginManager, Map<String, PluginDescription> toLoad) {
|
||||||
|
reflection.set(pluginManager, "toLoad", toLoad);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the registered plugin of the command.
|
* Retrieves the registered plugin of the command.
|
||||||
* @param instance The PluginManager instance.
|
* @param instance The PluginManager instance.
|
||||||
|
|
@ -53,8 +58,4 @@ public class RPluginManager {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getLibraryLoader(Object instance) {
|
|
||||||
return reflection.get(instance, "libraryLoader");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,7 @@ public class CloseablePluginResults<T> extends PluginResults<T> implements Close
|
||||||
*/
|
*/
|
||||||
public void tryClose() {
|
public void tryClose() {
|
||||||
try {
|
try {
|
||||||
for (PluginResult<T> pluginResult : this) {
|
close();
|
||||||
if (pluginResult instanceof CloseablePluginResult) {
|
|
||||||
((CloseablePluginResult<T>) pluginResult).close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
@ -77,5 +73,6 @@ public class CloseablePluginResults<T> extends PluginResults<T> implements Close
|
||||||
((CloseablePluginResult<T>) pluginResult).close();
|
((CloseablePluginResult<T>) pluginResult).close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
System.gc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue