diff --git a/src/main/java/net/frankheijden/serverutils/commands/CommandServerUtils.java b/src/main/java/net/frankheijden/serverutils/commands/CommandServerUtils.java index bccccbd..d6daff7 100644 --- a/src/main/java/net/frankheijden/serverutils/commands/CommandServerUtils.java +++ b/src/main/java/net/frankheijden/serverutils/commands/CommandServerUtils.java @@ -121,10 +121,16 @@ public class CommandServerUtils extends BaseCommand { @Subcommand("unloadplugin") @CommandCompletion("@plugins") @CommandPermission("serverutils.unloadplugin") - @Description("Unloads the specified plugin.") + @Description("Disables and unloads the specified plugin.") public void onUnloadPlugin(CommandSender sender, String pluginName) { - Result result = PluginManager.disablePlugin(pluginName); - result.sendTo(sender, "unload", pluginName); + Result disableResult = PluginManager.disablePlugin(pluginName); + if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) { + disableResult.sendTo(sender, "disabl", pluginName); + return; + } + + Result unloadResult = PluginManager.unloadPlugin(pluginName); + unloadResult.sendTo(sender, "unload", pluginName); } @Subcommand("reloadplugin") @@ -136,6 +142,24 @@ public class CommandServerUtils extends BaseCommand { result.sendTo(sender, "reload", pluginName); } + @Subcommand("enableplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.enableplugin") + @Description("Enables the loaded plugin.") + public void onEnablePlugin(CommandSender sender, String pluginName) { + Result result = PluginManager.enablePlugin(pluginName); + result.sendTo(sender, "enabl", pluginName); + } + + @Subcommand("disableplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.disableplugin") + @Description("Disables the specified plugin.") + public void onDisablePlugin(CommandSender sender, String pluginName) { + Result result = PluginManager.disablePlugin(pluginName); + result.sendTo(sender, "disabl", pluginName); + } + @Subcommand("plugininfo") @CommandCompletion("@plugins") @CommandPermission("serverutils.plugininfo") diff --git a/src/main/java/net/frankheijden/serverutils/config/Messenger.java b/src/main/java/net/frankheijden/serverutils/config/Messenger.java index 68675ba..019b987 100644 --- a/src/main/java/net/frankheijden/serverutils/config/Messenger.java +++ b/src/main/java/net/frankheijden/serverutils/config/Messenger.java @@ -16,9 +16,12 @@ public class Messenger { "error", "&cAn error occurred while %action%ing &4%what%&c, please check the console!", "not_exists", "&cAn error occurred while %action%ing &4%what%&c, plugin does not exist!", "not_enabled", "&cAn error occurred while %action%ing &4%what%&c, plugin is not enabled!", + "already_loaded", "&cAn error occurred while %action%ing &4%what%&c, plugin is already loaded!", "already_enabled", "&cAn error occurred while %action%ing &4%what%&c, plugin is already enabled!", + "already_disabled", "&cAn error occurred while %action%ing &4%what%&c, plugin is already disabled!", "file_changed", "&cAccessing the jar file while %action%ing &4%what%&c went wrong, please load the plugin manually!", "invalid_description", "&cAn error occurred while %action%ing &4%what%&c, plugin doesn't have a valid description!", + "invalid_plugin", "&cAn error occurred while %action%ing &4%what%&c, plugin is invalid!", "update", Defaults.of( "available", "&8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=--------------\n" + " &3Current version: &b%old%\n" diff --git a/src/main/java/net/frankheijden/serverutils/managers/LoadResult.java b/src/main/java/net/frankheijden/serverutils/managers/LoadResult.java index 78fa6ce..61de87c 100644 --- a/src/main/java/net/frankheijden/serverutils/managers/LoadResult.java +++ b/src/main/java/net/frankheijden/serverutils/managers/LoadResult.java @@ -6,11 +6,15 @@ public class LoadResult { private final Plugin plugin; private final Result result; - public LoadResult(Plugin plugin, Result result) { + private LoadResult(Plugin plugin, Result result) { this.plugin = plugin; this.result = result; } + public LoadResult(Plugin plugin) { + this(plugin, Result.SUCCESS); + } + public LoadResult(Result result) { this(null, result); } diff --git a/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java b/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java index 6d38e8d..8b26f5c 100644 --- a/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java +++ b/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java @@ -8,8 +8,11 @@ import org.bukkit.plugin.*; import org.bukkit.plugin.java.PluginClassLoader; import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static net.frankheijden.serverutils.reflection.ReflectionUtils.set; @@ -21,8 +24,13 @@ public class PluginManager { public static LoadResult loadPlugin(File file) { if (!file.exists()) return new LoadResult(Result.NOT_EXISTS); + + Plugin loadedPlugin = getLoadedPlugin(file); + if (loadedPlugin != null) return new LoadResult(Result.ALREADY_LOADED); + + Plugin plugin; try { - return new LoadResult(Bukkit.getPluginManager().loadPlugin(file), Result.SUCCESS); + plugin = Bukkit.getPluginManager().loadPlugin(file); } catch (InvalidDescriptionException ex) { return new LoadResult(Result.INVALID_DESCRIPTION); } catch (InvalidPluginException ex) { @@ -33,9 +41,12 @@ public class PluginManager { } } ex.printStackTrace(); + return new LoadResult(Result.ERROR); } - return new LoadResult(Result.ERROR); + if (plugin == null) return new LoadResult(Result.INVALID_PLUGIN); + plugin.onLoad(); + return new LoadResult(plugin); } public static Result disablePlugin(String pluginName) { @@ -44,11 +55,9 @@ public class PluginManager { public static Result disablePlugin(Plugin plugin) { if (plugin == null) return Result.NOT_ENABLED; + if (!plugin.isEnabled()) return Result.ALREADY_DISABLED; try { Bukkit.getPluginManager().disablePlugin(plugin); - RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin); - RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName()); - clearClassLoader(RJavaPlugin.getClassLoader(plugin)); RCraftingManager.removeRecipesFor(plugin); } catch (Exception ex) { ex.printStackTrace(); @@ -58,17 +67,39 @@ public class PluginManager { return Result.SUCCESS; } - public static void clearClassLoader(ClassLoader loader) throws IllegalAccessException { + public static Result unloadPlugin(String pluginName) { + return unloadPlugin(Bukkit.getPluginManager().getPlugin(pluginName)); + } + + public static Result unloadPlugin(Plugin plugin) { + if (plugin == null) return Result.NOT_EXISTS; + try { + RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin); + RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName()); + clearClassLoader(RJavaPlugin.getClassLoader(plugin)); + } catch (Exception ex) { + ex.printStackTrace(); + return Result.ERROR; + } + return Result.SUCCESS; + } + + public static void clearClassLoader(ClassLoader loader) throws IllegalAccessException, IOException { if (loader == null) return; if (loader instanceof PluginClassLoader) { clearClassLoader((PluginClassLoader) loader); } } - public static void clearClassLoader(PluginClassLoader loader) throws IllegalAccessException { + public static void clearClassLoader(PluginClassLoader loader) throws IllegalAccessException, IOException { if (loader == null) return; set(RPluginClassLoader.getFields(), loader, "plugin", null); set(RPluginClassLoader.getFields(), loader, "pluginInit", null); + loader.close(); + } + + public static Result enablePlugin(String pluginName) { + return enablePlugin(Bukkit.getPluginManager().getPlugin(pluginName)); } public static Result enablePlugin(Plugin plugin) { @@ -89,7 +120,10 @@ public class PluginManager { public static Result reloadPlugin(Plugin plugin) { Result disableResult = disablePlugin(plugin); - if (disableResult != Result.SUCCESS) return disableResult; + if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) return disableResult; + + Result unloadResult = unloadPlugin(plugin); + if (unloadResult != Result.SUCCESS) return unloadResult; File pluginFile; try { @@ -138,4 +172,43 @@ public class PluginManager { if (knownCommands == null) return null; return knownCommands.get(command); } + + public static Map getFileAssociations() { + try { + return RSimplePluginManager.getFileAssociations(Bukkit.getPluginManager()); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + return null; + } + } + + public static PluginLoader getPluginLoader(File file) { + Map fileAssociations = getFileAssociations(); + if (fileAssociations == null) return null; + + for (Pattern filter : fileAssociations.keySet()) { + Matcher match = filter.matcher(file.getName()); + if (match.find()) { + return fileAssociations.get(filter); + } + } + return null; + } + + public static Plugin getLoadedPlugin(File file) { + PluginDescriptionFile descriptionFile; + try { + descriptionFile = getPluginDescription(file); + } catch (InvalidDescriptionException ex) { + return null; + } + if (descriptionFile == null) return null; + return Bukkit.getPluginManager().getPlugin(descriptionFile.getName()); + } + + public static PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException { + PluginLoader loader = getPluginLoader(file); + if (loader == null) return null; + return loader.getPluginDescription(file); + } } diff --git a/src/main/java/net/frankheijden/serverutils/managers/Result.java b/src/main/java/net/frankheijden/serverutils/managers/Result.java index 27befba..0216cc5 100644 --- a/src/main/java/net/frankheijden/serverutils/managers/Result.java +++ b/src/main/java/net/frankheijden/serverutils/managers/Result.java @@ -6,9 +6,12 @@ import org.bukkit.command.CommandSender; public enum Result { NOT_EXISTS, NOT_ENABLED, + ALREADY_LOADED, ALREADY_ENABLED, + ALREADY_DISABLED, FILE_CHANGED, INVALID_DESCRIPTION, + INVALID_PLUGIN, ERROR, SUCCESS; diff --git a/src/main/java/net/frankheijden/serverutils/reflection/RSimplePluginManager.java b/src/main/java/net/frankheijden/serverutils/reflection/RSimplePluginManager.java index 57f5c77..ccb9546 100644 --- a/src/main/java/net/frankheijden/serverutils/reflection/RSimplePluginManager.java +++ b/src/main/java/net/frankheijden/serverutils/reflection/RSimplePluginManager.java @@ -1,10 +1,10 @@ package net.frankheijden.serverutils.reflection; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.SimplePluginManager; +import org.bukkit.plugin.*; import java.lang.reflect.Field; import java.util.*; +import java.util.regex.Pattern; import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf; import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS; @@ -21,15 +21,21 @@ public class RSimplePluginManager { simplePluginManagerClass = SimplePluginManager.class; fields = getAllFields(simplePluginManagerClass, fieldOf("plugins", ALL_VERSIONS), - fieldOf("lookupNames", ALL_VERSIONS)); + fieldOf("lookupNames", ALL_VERSIONS), + fieldOf("fileAssociations", ALL_VERSIONS)); } catch (Exception ex) { ex.printStackTrace(); } } + @SuppressWarnings("unchecked") + public static Map getFileAssociations(Object manager) throws IllegalAccessException { + return (Map) get(fields, manager, "fileAssociations"); + } + @SuppressWarnings("unchecked") public static List getPlugins(Object manager) throws IllegalAccessException { - return (List) fields.get("plugins").get(manager); + return (List) get(fields, manager, "plugins"); } @SuppressWarnings("unchecked")