v2.0.2 - Improve reloading and cleaning up of BungeeCord plugins.

- Cleanup PluginClassLoader properly
- Cancel plugin tasks properly
- Fixed automatic updater on bungee
This commit is contained in:
Frank van der Heijden 2020-07-05 21:59:26 +02:00
parent f728c3e6bb
commit 584ce8be4d
No known key found for this signature in database
GPG key ID: 26DA56488D314D11
5 changed files with 53 additions and 16 deletions

View file

@ -9,9 +9,14 @@ import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.bungee.entities.BungeeReflection;
import net.frankheijden.serverutils.bungee.listeners.BungeeListener;
import net.frankheijden.serverutils.bungee.managers.BungeePluginManager;
import net.frankheijden.serverutils.bungee.reflection.RPluginClassLoader;
import net.frankheijden.serverutils.bungee.reflection.RPluginManager;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.Config;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.entities.CloseableResult;
import net.frankheijden.serverutils.common.entities.Result;
import net.frankheijden.serverutils.common.utils.MapUtils;
import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
@ -47,9 +52,20 @@ public class ServerUtils extends Plugin {
reload();
getProxy().getPluginManager().registerListener(this, new BungeeListener());
loadClasses();
ServerUtilsApp.tryCheckForUpdates();
}
/**
* Loads some classes in memory so they're available during updating.
*/
private void loadClasses() {
new RPluginManager();
new MapUtils();
new CloseableResult(Result.SUCCESS);
new RPluginClassLoader();
}
public static ServerUtils getInstance() {
return instance;
}

View file

@ -123,6 +123,7 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin> {
public CloseableResult reloadPlugin(Plugin plugin) {
CloseableResult result = unloadPlugin(plugin);
if (result.getResult() != Result.SUCCESS) return result;
result.tryClose();
File file = getPluginFile(plugin.getDescription().getName());
if (file == null) return result.set(Result.FILE_DELETED);
@ -145,13 +146,16 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin> {
plugin.onDisable();
proxy.getPluginManager().unregisterCommands(plugin);
proxy.getPluginManager().unregisterListeners(plugin);
proxy.getScheduler().cancel(plugin);
Closeable closeable;
try {
RPluginManager.clearPlugin(proxy.getPluginManager(), plugin);
closeable = (Closeable) RPluginClassLoader.getPluginClassLoader(plugin);
} catch (Exception ex) {
ex.printStackTrace();
return new CloseableResult(Result.ERROR);
}
return new CloseableResult(getCloseable(plugin));
return new CloseableResult(closeable);
}
public static File getPluginFileExact(String fileName) {
@ -216,17 +220,6 @@ public class BungeePluginManager extends AbstractPluginManager<Plugin> {
return entry;
}
/**
* Retrieves the closable classloader of the plugin, if possible.
* @param plugin The plugin.
* @return The closable instance.
*/
public static Closeable getCloseable(Plugin plugin) {
ClassLoader loader = plugin.getClass().getClassLoader();
if (loader instanceof Closeable) return (Closeable) loader;
return null;
}
@Override
public File getPluginsFolder() {
return plugin.getProxy().getPluginsFolder();

View file

@ -1,13 +1,18 @@
package net.frankheijden.serverutils.bungee.reflection;
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Map;
import java.util.Set;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
public class RPluginClassLoader {
@ -21,7 +26,9 @@ public class RPluginClassLoader {
loaderClass = Class.forName("net.md_5.bungee.api.plugin.PluginClassloader");
constructor = loaderClass.getDeclaredConstructor(ProxyServer.class, PluginDescription.class, URL[].class);
constructor.setAccessible(true);
fields = getAllFields(loaderClass);
fields = getAllFields(loaderClass,
fieldOf("allLoaders", ALL_VERSIONS),
fieldOf("plugin", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
@ -30,4 +37,26 @@ public class RPluginClassLoader {
public static Object newInstance(ProxyServer proxy, PluginDescription desc, URL... urls) throws Exception {
return constructor.newInstance(proxy, desc, urls);
}
/**
* Retrieves the PluginClassLoader of a specific plugin.
* @param plugin The plugin to lookup the PluginClassLoader for.
* @return The PluginClassLoader.
* @throws ReflectiveOperationException Iff a reflection error occurred.
*/
@SuppressWarnings("unchecked")
public static Object getPluginClassLoader(Plugin plugin) throws ReflectiveOperationException {
Set<Object> allLoaders = (Set<Object>) get(fields, null, "allLoaders");
if (allLoaders == null) return null;
Object matchingLoader = null;
for (Object loader : allLoaders) {
if (plugin.equals(get(fields, loader, "plugin"))) {
matchingLoader = loader;
break;
}
}
if (matchingLoader != null) allLoaders.remove(matchingLoader);
return matchingLoader;
}
}