diff --git a/pom.xml b/pom.xml index 910c71f..61dbb7d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 Yum - 2.8.2 + 2.8.3 jar Minecraft 服务器插件管理系统 @@ -16,9 +16,10 @@ - §a补丁包 2.8.2 版本 + §a补丁包 2.8.3 版本 - §619-08-28 §cfix: async event on primary thread; + §619-08-28 §cfix: knownCommands not compatible; +        §cfix: async event on primary thread; §619-08-26 §cfix: 修复不兼容 1.14.4 的问题; §619-02-23 §cfix: 修复不兼容 1.13 的问题; diff --git a/src/main/java/pw/yumc/Yum/managers/PluginsManager.java b/src/main/java/pw/yumc/Yum/managers/PluginsManager.java index a6fd7ee..79ece41 100644 --- a/src/main/java/pw/yumc/Yum/managers/PluginsManager.java +++ b/src/main/java/pw/yumc/Yum/managers/PluginsManager.java @@ -1,748 +1,723 @@ -package pw.yumc.Yum.managers; - -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.PluginCommand; -import org.bukkit.command.SimpleCommandMap; -import org.bukkit.plugin.InvalidDescriptionException; -import org.bukkit.plugin.InvalidPluginException; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.PluginLoader; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.UnknownDependencyException; - -import com.google.common.base.Joiner; - -import pw.yumc.YumCore.kit.FileKit; -import pw.yumc.YumCore.kit.StrKit; - -/** - * 插件管理类 - * - * @author 喵♂呜 - * @since 2015年8月21日下午7:03:26 - */ -public class PluginsManager { - private Set ignoreList = new HashSet<>(); - private Plugin main; - - public PluginsManager(Plugin plugin) { - this.main = plugin; - } - - public static String getVersion(Plugin plugin) { - return StringUtils.substring(plugin.getDescription().getVersion(), 0, 15); - } - - /** - * 添加到忽略列表 - * - * @param name - * - 插件名称 - * @return 是否成功 - */ - public boolean addIgnore(Collection name) { - return ignoreList.addAll(name); - } - - /** - * 添加到忽略列表 - * - * @param name - * - 插件名称 - * @return 是否成功 - */ - public boolean addIgnore(String name) { - return ignoreList.add(name); - } - - /** - * 删除插件 - * - * @param sender - * - 命令发送者 - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean deletePlugin(CommandSender sender, Plugin plugin) { - return unload(sender, plugin) && getPluginFile(plugin).delete(); - } - - /** - * 删除插件 - * - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean deletePlugin(Plugin plugin) { - return deletePlugin(Bukkit.getConsoleSender(), plugin); - } - - /** - * 关闭插件 - * - * @param plugin - * - 插件 - */ - public void disable(Plugin plugin) { - if ((plugin != null) && (plugin.isEnabled())) { - Bukkit.getPluginManager().disablePlugin(plugin); - } - } - - /** - * 关闭所有插件 - */ - public void disableAll() { - for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - if (!isIgnored(plugin)) { - disable(plugin); - } - } - } - - /** - * 启用插件 - * - * @param plugin - * - 插件 - */ - public void enable(Plugin plugin) { - if ((plugin != null) && (!plugin.isEnabled())) { - Bukkit.getPluginManager().enablePlugin(plugin); - } - } - - /** - * 启用所有插件 - */ - public void enableAll() { - for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - if (!isIgnored(plugin)) { - enable(plugin); - } - } - } - - /** - * 删除插件(包括数据) - * - * @param sender - * - 命令发送者 - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean fullDeletePlugin(CommandSender sender, Plugin plugin) { - return unload(sender, plugin) && getPluginFile(plugin).delete() - && FileKit.deleteDir(sender, plugin.getDataFolder()); - } - - /** - * 获得格式化的插件名称 - * - * @param plugin - * - 插件 - * @return 格式化的插件名称 - */ - public String getFormattedName(Plugin plugin) { - return getFormattedName(plugin, false); - } - - /** - * 获得格式化的插件名称(可带版本) - * - * @param plugin - * - 插件 - * @param includeVersions - * - 是否包括版本 - * @return 格式化的插件名称 - */ - public String getFormattedName(Plugin plugin, boolean includeVersions) { - ChatColor color = plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED; - String pluginName = color + plugin.getName(); - if (includeVersions) { - pluginName = pluginName + " (" + getVersion(plugin) + ")"; - } - return pluginName; - } - - /** - * 通过名称获得插件 - * - * @param name - * - 名称 - * @return 插件 - */ - public Plugin getPluginByName(String name) { - return Bukkit.getPluginManager().getPlugin(name); - } - - /** - * 通过名称获得插件(处理带空格的插件) - * - * @param name - * - 名称 - * @return 插件 - */ - public Plugin getPluginByName(String[] args, int start) { - return getPluginByName(StrKit.consolidateStrings(args, start)); - } - - /** - * 获得插件绝对路径 - * - * @param plugin - * - 插件 - * @return 插件的绝对路径 - */ - public File getPluginFile(Plugin plugin) { - File file = null; - ClassLoader cl = plugin.getClass().getClassLoader(); - if ((cl instanceof URLClassLoader)) { - @SuppressWarnings("resource") - URLClassLoader ucl = (URLClassLoader) cl; - URL url = ucl.getURLs()[0]; - try { - file = new File(URLDecoder.decode(url.getFile(), "UTF-8")); - } catch (UnsupportedEncodingException e) { - } - } - return file; - } - - public List getPluginNames(boolean fullName) { - List plugins = new ArrayList<>(); - for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - plugins.add(fullName ? plugin.getDescription().getFullName() : plugin.getName()); - } - return plugins; - } - - /** - * 获得插件版本 - * - * @param name - * - 插件名称 - * @return 插件版本 - */ - public String getPluginVersion(String name) { - Plugin plugin = getPluginByName(name); - if ((plugin != null) && (plugin.getDescription() != null)) { return getVersion(plugin); } - return null; - } - - /** - * 获得插件命令 - * - * @param plugin - * - 插件 - * @return 插件命令 - */ - public String getUsages(Plugin plugin) { - List parsedCommands = new ArrayList<>(); - - Map> commands = plugin.getDescription().getCommands(); - - if (commands != null) { - Iterator>> commandsIt = commands.entrySet().iterator(); - while (commandsIt.hasNext()) { - Entry> thisEntry = commandsIt.next(); - if (thisEntry != null) { - parsedCommands.add(thisEntry.getKey()); - } - } - } - if (parsedCommands.isEmpty()) { return null; } - return Joiner.on(", ").join(parsedCommands); - } - - /** - * 判断插件是否在忽略列表 - * - * @param plugin - * - 插件 - * @return 是否 - */ - public boolean isIgnored(Plugin plugin) { - return isIgnored(plugin.getName()); - } - - /** - * 判断插件是否在忽略列表 - * - * @param plugin - * - 插件名称 - * @return 是否 - */ - public boolean isIgnored(String plugin) { - for (String name : ignoreList) { - if (name.equalsIgnoreCase(plugin)) { return true; } - } - return false; - } - - /** - * 载入插件 - * - * @param sender - * - 命令发送者 - * @param pluginFile - * - 插件文件 - * @return 是否成功 - */ - public boolean load(CommandSender sender, File pluginFile) { - Plugin target = null; - String name = pluginFile.getName(); - try { - try { - target = Bukkit.getPluginManager().loadPlugin(pluginFile); - } catch (UnsupportedClassVersionError e) { - sender.sendMessage("§4异常: §c" + e.getMessage()); - sender.sendMessage("§c服务器或JAVA的版本低于插件: " + name + " 所需要的版本!!"); - return false; - } catch (InvalidPluginException e) { - if (e.getMessage().equalsIgnoreCase("Plugin already initialized!")) { - sender.sendMessage("§4异常: §c" + e.getMessage()); - sender.sendMessage("§4插件: §c" + name + " 已载入到服务器!"); - sender.sendMessage("§4注意: §c当前插件无法在运行时重载 请重启服务器!"); - return false; - } - sender.sendMessage("§4异常: §c" + e.getMessage()); - sender.sendMessage("§4文件: §c" + name + " 不是一个可载入的插件!"); - sender.sendMessage("§4注意: §cMOD服重载插件3次以上需重启服务器"); - return false; - } catch (UnknownDependencyException e) { - sender.sendMessage("§4异常: §c服务器未安装必须依赖: " + e.getMessage()); - sender.sendMessage("§4插件: §c" + name + " 载入失败 缺少部分依赖项目!"); - return false; - } - if (target == null) { - sender.sendMessage("§4异常: §c服务器类加载器载入插件失败 请查看后台信息!"); - return false; - } - target.onLoad(); - Bukkit.getPluginManager().enablePlugin(target); - sender.sendMessage("§6载入: §a插件 §b" + target.getName() + " §a版本 §d" + getVersion(target) + " §a已成功载入到服务器!"); - return true; - } catch (Throwable e) { - sender.sendMessage("§4错误: §c" + e.getClass().getName() + ": " + e.getMessage()); - sender.sendMessage("§4异常: §c具体信息请查看后台异常堆栈!"); - e.printStackTrace(); - sender.sendMessage("§4载入: §c插件 §b" + target.getName() + " §c版本 §d" + getVersion(target) + " §c载入失败!"); - return false; - } - } - - /** - * 载入插件 - * - * @param sender - * - 命令发送者 - * @param name - * - 插件名称 - * @return 是否成功 - */ - public boolean load(CommandSender sender, String name) { - String filename = name; - if (sender == null) { - sender = Bukkit.getConsoleSender(); - } - if (!name.endsWith(".jar")) { - filename = name + ".jar"; - } - File pluginDir = new File("plugins"); - File updateDir = new File(pluginDir, "update"); - if (!pluginDir.isDirectory()) { - sender.sendMessage("§6载入: §c插件目录不存在或IO错误!"); - return false; - } - - File pluginFile = new File(pluginDir, filename); - - if (!pluginFile.isFile() && !new File(updateDir, filename).isFile()) { - pluginFile = null; - for (File file : pluginDir.listFiles()) { - if (file.getName().endsWith(".jar")) { - try { - PluginDescriptionFile desc = main.getPluginLoader().getPluginDescription(file); - if (desc.getName().equalsIgnoreCase(name)) { - pluginFile = file; - break; - } - } catch (InvalidDescriptionException e) { - } - } - } - if (pluginFile == null) { - sender.sendMessage("§6载入: §c在插件目录和更新目录均未找到 §b" + name + " §c插件 请确认文件是否存在!"); - return false; - } - } - return load(sender, pluginFile); - } - - /** - * 载入插件 - * - * @param pluginFile - * - 插件名称 - * @return 是否成功 - */ - public boolean load(File pluginFile) { - return load(Bukkit.getConsoleSender(), pluginFile); - } - - /** - * 载入插件 - * - * @param name - * - 插件名称 - * @return 是否成功 - */ - public boolean load(String name) { - return load(Bukkit.getConsoleSender(), name); - } - - /** - * 删除重载插件 - * - * @param sender - * - 命令发送者 - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean reload(CommandSender sender, Plugin plugin) { - if (plugin != null) { return unload(sender, plugin) && load(sender, plugin.getName()); } - return false; - } - - /** - * 删除重载插件 - * - * @param sender - * - 命令发送者 - * @param main - * - 插件 - * @return 是否成功 - */ - public boolean reload(CommandSender sender, String name) { - if (name != null) { return unload(sender, name) && load(sender, name); } - return false; - } - - /** - * 重载插件 - * - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean reload(Plugin plugin) { - return reload(Bukkit.getConsoleSender(), plugin); - } - - /** - * 重载所有插件 - */ - public void reloadAll() { - for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - if (!isIgnored(plugin)) { - unload(plugin); - } - } - Bukkit.getPluginManager().loadPlugins(Bukkit.getUpdateFolderFile().getParentFile()); - } - - /** - * 重载所有插件 - */ - public void reloadAll(CommandSender sender) { - Plugin[] plist = Bukkit.getPluginManager().getPlugins(); - for (Plugin plugin : plist) { - if (!isIgnored(plugin)) { - unload(sender, plugin); - } - } - for (Plugin plugin : plist) { - if (!isIgnored(plugin)) { - load(sender, plugin.getName()); - } - } - } - - /** - * 从忽略列表移除 - * - * @param name - * - 插件名称 - * @return 是否成功 - */ - public boolean removeIgnore(String name) { - return ignoreList.remove(name); - } - - /** - * 卸载插件 - * - * @param sender - * - 命令发送者 - * @param plugin - * - 插件 - * @return 是否成功 - */ - public boolean unload(CommandSender sender, Plugin plugin) { - return unload(sender, plugin.getName()); - } - - /** - * 卸载插件 - * - * @param sender - * - 命令发送者 - * @param name - * - 插件名称 - * @return 是否成功 - */ - @SuppressWarnings("unchecked") - public boolean unload(CommandSender sender, String name) { - if (sender == null) { - sender = Bukkit.getConsoleSender(); - } - PluginManager pluginManager = Bukkit.getPluginManager(); - SimpleCommandMap commandMap = null; - List plugins = null; - Map lookupNames = null; - Map knownCommands = null; - // Map fileAssociations = null; - if (pluginManager == null) { - sender.sendMessage("§4异常: §c插件管理类反射获取失败!"); - return false; - } - try { - Field pluginsField = pluginManager.getClass().getDeclaredField("plugins"); - pluginsField.setAccessible(true); - plugins = (List) pluginsField.get(pluginManager); - - Field lookupNamesField = pluginManager.getClass().getDeclaredField("lookupNames"); - lookupNamesField.setAccessible(true); - lookupNames = (Map) lookupNamesField.get(pluginManager); - - Field commandMapField = pluginManager.getClass().getDeclaredField("commandMap"); - commandMapField.setAccessible(true); - commandMap = (SimpleCommandMap) commandMapField.get(pluginManager); - - Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands"); - knownCommandsField.setAccessible(true); - knownCommands = (Map) knownCommandsField.get(commandMap); - - // Field fileAssociationsField = pluginManager.getClass().getDeclaredField("fileAssociations"); - // fileAssociationsField.setAccessible(true); - // fileAssociations = (Map) fileAssociationsField.get(pluginManager); - - } catch (Exception e) { - sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!"); - return false; - } - String pluginVersion = ""; - for (Plugin next : pluginManager.getPlugins()) { - if (next.getName().equals(name)) { - pluginManager.disablePlugin(next); - if ((plugins != null) && (plugins.contains(next))) { - pluginVersion = getVersion(next); - plugins.remove(next); - sender.sendMessage("§6卸载: §a从服务器插件列表删除 §b" + name + " §a的实例!"); - } - - if ((lookupNames != null) && (lookupNames.containsKey(name))) { - lookupNames.remove(name); - sender.sendMessage("§6卸载: §a从插件查找列表删除 §b" + name + " §a的实例!"); - } - - for (Iterator> it = knownCommands.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = it.next(); - if ((entry.getValue() instanceof PluginCommand)) { - PluginCommand command = (PluginCommand) entry.getValue(); - if (command.getPlugin() == next) { - command.unregister(commandMap); - it.remove(); - } - } - } - // try { - // if (fileAssociations != null) { - // for (Entry entry : fileAssociations.entrySet()) { - // Matcher match = entry.getKey().matcher(getPluginFile(next).getName()); - // if (match.find()) { - // PluginLoader pluginLoader = entry.getValue(); - // if (pluginLoader instanceof YumPluginLoader) { - // pluginLoader = ((YumPluginLoader) pluginLoader).internal_loader; - // } - // Field loadersField = pluginLoader.getClass().getDeclaredField("loaders"); - // loadersField.setAccessible(true); - // Map loaders = (Map) loadersField.get(pluginLoader); - // for (Entry entry2 : loaders.entrySet()) { - // Reflect.on(entry2.getValue()).set("pluginInit", null).set("plugin", null); - // } - // sender.sendMessage("§6卸载: §a移除插件 §b" + name + " §a的类实例缓存!"); - // } - // } - // } - // } catch (Exception e) { - // e.printStackTrace(); - // } - sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!"); - ClassLoader cl = next.getClass().getClassLoader(); - try { - ((URLClassLoader) cl).close(); - } catch (IOException ex) { - } - System.gc(); - } - } - if (!pluginVersion.isEmpty()) { - sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!"); - return true; - } - return false; - } - - /** - * 卸载插件 - * - * @param plugin - * - 卸载插件 - * @return 是否成功 - */ - public boolean unload(Plugin plugin) { - return unload(Bukkit.getConsoleSender(), plugin); - } - - /** - * 重载update文件夹的插件 - * - * @return 是否成功 - */ - public boolean upgrade(CommandSender sender) { - sender.sendMessage("§6升级: §a开始升级 服务器更新 目录下的所有插件!"); - return upgrade(sender, null, null); - } - - /** - * 重载update文件夹的插件 - * - * @param sender - * - 命令发送者 - * @param directory - * - 更新目录 - * @return 是否成功 - */ - public boolean upgrade(CommandSender sender, File directory, Plugin plugin) { - boolean result = false; - PluginLoader loader = main.getPluginLoader(); - File updateDirectory; - if (directory == null || !directory.isDirectory()) { - updateDirectory = Bukkit.getServer().getUpdateFolderFile(); - } else { - updateDirectory = directory; - } - if (updateDirectory == null) { - sender.sendMessage("§4异常: §c文件夹 §d服务器更新文件夹 §c未找到或IO错误!"); - return false; - } - if (!updateDirectory.exists()) { - updateDirectory.mkdirs(); - } - try { - sender.sendMessage("§6升级: §b从 §d" + updateDirectory.getCanonicalPath() + " §b文件夹检索插件插件!"); - } catch (SecurityException | IOException e1) { - sender.sendMessage("§4异常: §c文件夹 §d" + updateDirectory.getName() + " §c权限不足或IO错误!"); - return false; - } - File[] plugins = updateDirectory.listFiles(); - if (plugins.length == 0) { - sender.sendMessage("§6升级: §d更新文件夹未找到插件!"); - return false; - } - for (File file : updateDirectory.listFiles()) { - if (file.isDirectory()) { - continue; - } - PluginDescriptionFile description = null; - try { - description = loader.getPluginDescription(file); - String name = description.getName(); - if (plugin != null && !name.equals(plugin.getName())) { - continue; - } - Plugin oldplugin = Bukkit.getPluginManager().getPlugin(name); - result = true; - File dest = null; - if (!unload(sender, name)) { - sender.sendMessage("§6升级: §d开始安装 §b" + name + " §d插件!"); - dest = new File(Bukkit.getUpdateFolderFile().getParentFile(), File.separatorChar + file.getName()); - } else { - if (oldplugin != null) { - dest = new File(Bukkit.getUpdateFolderFile(), File.separatorChar - + getPluginFile(oldplugin).getName()); - } - sender.sendMessage("§6升级: §a开始升级 §b" + name + " §a插件!"); - } - if (dest != null) { - file.renameTo(dest); - } - load(sender, name); - } catch (InvalidDescriptionException e) { - sender.sendMessage("§4异常: §c" + e.getMessage()); - sender.sendMessage("§4文件: §c" + file.getName() + " 的plugin.yml文件存在错误!"); - } - if (file.exists()) { - file.delete(); - } - } - sender.sendMessage("§6升级: §a所有插件升级完毕!"); - return result; - } - - /** - * 重载update文件夹的插件 - * - * @return 是否成功 - */ - public boolean upgrade(CommandSender sender, Plugin plugin) { - return upgrade(sender, null, plugin); - } - - /** - * 重载update文件夹的插件 - * - * @return 是否成功 - */ - public boolean upgrade(File directory) { - Bukkit.getConsoleSender().sendMessage("§6升级: §a开始升级 §d" + directory.getName() + " §a目录下的所有插件!"); - return upgrade(Bukkit.getConsoleSender(), directory, null); - } -} +package pw.yumc.Yum.managers; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.SimpleCommandMap; +import org.bukkit.plugin.InvalidDescriptionException; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginLoader; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.UnknownDependencyException; + +import com.google.common.base.Joiner; +import pw.yumc.YumCore.bukkit.Log; +import pw.yumc.YumCore.kit.FileKit; +import pw.yumc.YumCore.kit.StrKit; +import pw.yumc.YumCore.reflect.Reflect; + +/** + * 插件管理类 + * + * @author 喵♂呜 + * @since 2015年8月21日下午7:03:26 + */ +public class PluginsManager { + private Set ignoreList = new HashSet<>(); + private Plugin main; + + public PluginsManager(Plugin plugin) { + this.main = plugin; + } + + public static String getVersion(Plugin plugin) { + return StringUtils.substring(plugin.getDescription().getVersion(), 0, 15); + } + + /** + * 添加到忽略列表 + * + * @param name + * - 插件名称 + * @return 是否成功 + */ + public boolean addIgnore(Collection name) { + return ignoreList.addAll(name); + } + + /** + * 添加到忽略列表 + * + * @param name + * - 插件名称 + * @return 是否成功 + */ + public boolean addIgnore(String name) { + return ignoreList.add(name); + } + + /** + * 删除插件 + * + * @param sender + * - 命令发送者 + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean deletePlugin(CommandSender sender, Plugin plugin) { + return unload(sender, plugin) && getPluginFile(plugin).delete(); + } + + /** + * 删除插件 + * + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean deletePlugin(Plugin plugin) { + return deletePlugin(Bukkit.getConsoleSender(), plugin); + } + + /** + * 关闭插件 + * + * @param plugin + * - 插件 + */ + public void disable(Plugin plugin) { + if ((plugin != null) && (plugin.isEnabled())) { + Bukkit.getPluginManager().disablePlugin(plugin); + } + } + + /** + * 关闭所有插件 + */ + public void disableAll() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + if (!isIgnored(plugin)) { + disable(plugin); + } + } + } + + /** + * 启用插件 + * + * @param plugin + * - 插件 + */ + public void enable(Plugin plugin) { + if ((plugin != null) && (!plugin.isEnabled())) { + Bukkit.getPluginManager().enablePlugin(plugin); + } + } + + /** + * 启用所有插件 + */ + public void enableAll() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + if (!isIgnored(plugin)) { + enable(plugin); + } + } + } + + /** + * 删除插件(包括数据) + * + * @param sender + * - 命令发送者 + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean fullDeletePlugin(CommandSender sender, Plugin plugin) { + return unload(sender, plugin) && getPluginFile(plugin).delete() + && FileKit.deleteDir(sender, plugin.getDataFolder()); + } + + /** + * 获得格式化的插件名称 + * + * @param plugin + * - 插件 + * @return 格式化的插件名称 + */ + public String getFormattedName(Plugin plugin) { + return getFormattedName(plugin, false); + } + + /** + * 获得格式化的插件名称(可带版本) + * + * @param plugin + * - 插件 + * @param includeVersions + * - 是否包括版本 + * @return 格式化的插件名称 + */ + public String getFormattedName(Plugin plugin, boolean includeVersions) { + ChatColor color = plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED; + String pluginName = color + plugin.getName(); + if (includeVersions) { + pluginName = pluginName + " (" + getVersion(plugin) + ")"; + } + return pluginName; + } + + /** + * 通过名称获得插件 + * + * @param name + * - 名称 + * @return 插件 + */ + public Plugin getPluginByName(String name) { + return Bukkit.getPluginManager().getPlugin(name); + } + + /** + * 通过名称获得插件(处理带空格的插件) + * + * @param args + * - 名称 + * @return 插件 + */ + public Plugin getPluginByName(String[] args, int start) { + return getPluginByName(StrKit.consolidateStrings(args, start)); + } + + /** + * 获得插件绝对路径 + * + * @param plugin + * - 插件 + * @return 插件的绝对路径 + */ + public File getPluginFile(Plugin plugin) { + File file = null; + ClassLoader cl = plugin.getClass().getClassLoader(); + if ((cl instanceof URLClassLoader)) { + @SuppressWarnings("resource") + URLClassLoader ucl = (URLClassLoader) cl; + URL url = ucl.getURLs()[0]; + try { + file = new File(URLDecoder.decode(url.getFile(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + } + } + return file; + } + + public List getPluginNames(boolean fullName) { + List plugins = new ArrayList<>(); + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + plugins.add(fullName ? plugin.getDescription().getFullName() : plugin.getName()); + } + return plugins; + } + + /** + * 获得插件版本 + * + * @param name + * - 插件名称 + * @return 插件版本 + */ + public String getPluginVersion(String name) { + Plugin plugin = getPluginByName(name); + if ((plugin != null) && (plugin.getDescription() != null)) { return getVersion(plugin); } + return null; + } + + /** + * 获得插件命令 + * + * @param plugin + * - 插件 + * @return 插件命令 + */ + public String getUsages(Plugin plugin) { + List parsedCommands = new ArrayList<>(); + + Map> commands = plugin.getDescription().getCommands(); + + if (commands != null) { + Iterator>> commandsIt = commands.entrySet().iterator(); + while (commandsIt.hasNext()) { + Entry> thisEntry = commandsIt.next(); + if (thisEntry != null) { + parsedCommands.add(thisEntry.getKey()); + } + } + } + if (parsedCommands.isEmpty()) { return null; } + return Joiner.on(", ").join(parsedCommands); + } + + /** + * 判断插件是否在忽略列表 + * + * @param plugin + * - 插件 + * @return 是否 + */ + public boolean isIgnored(Plugin plugin) { + return isIgnored(plugin.getName()); + } + + /** + * 判断插件是否在忽略列表 + * + * @param plugin + * - 插件名称 + * @return 是否 + */ + public boolean isIgnored(String plugin) { + for (String name : ignoreList) { + if (name.equalsIgnoreCase(plugin)) { return true; } + } + return false; + } + + /** + * 载入插件 + * + * @param sender + * - 命令发送者 + * @param pluginFile + * - 插件文件 + * @return 是否成功 + */ + public boolean load(CommandSender sender, File pluginFile) { + Plugin target = null; + String name = pluginFile.getName(); + try { + try { + target = Bukkit.getPluginManager().loadPlugin(pluginFile); + } catch (UnsupportedClassVersionError e) { + sender.sendMessage("§4异常: §c" + e.getMessage()); + sender.sendMessage("§c服务器或JAVA的版本低于插件: " + name + " 所需要的版本!!"); + return false; + } catch (InvalidPluginException e) { + if ("Plugin already initialized!".equalsIgnoreCase(e.getMessage()) || + "java.lang.IllegalArgumentException: Plugin already initialized!".equals(e.getMessage())) { + sender.sendMessage("§4异常: §c" + e.getMessage()); + sender.sendMessage("§4插件: §c" + name + " 已载入到服务器!"); + sender.sendMessage("§4注意: §c当前插件无法在运行时重载 请重启服务器!"); + return false; + } + sender.sendMessage("§4异常: §c" + e.getMessage()); + sender.sendMessage("§4文件: §c" + name + " 不是一个可载入的插件!"); + sender.sendMessage("§4注意: §cMOD服重载插件3次以上需重启服务器"); + return false; + } catch (UnknownDependencyException e) { + sender.sendMessage("§4异常: §c服务器未安装必须依赖: " + e.getMessage()); + sender.sendMessage("§4插件: §c" + name + " 载入失败 缺少部分依赖项目!"); + return false; + } + if (target == null) { + sender.sendMessage("§4异常: §c服务器类加载器载入插件失败 请查看后台信息!"); + return false; + } + target.onLoad(); + Bukkit.getPluginManager().enablePlugin(target); + sender.sendMessage("§6载入: §a插件 §b" + target.getName() + " §a版本 §d" + getVersion(target) + " §a已成功载入到服务器!"); + return true; + } catch (Throwable e) { + sender.sendMessage("§4错误: §c" + e.getClass().getName() + ": " + e.getMessage()); + sender.sendMessage("§4异常: §c具体信息请查看后台异常堆栈!"); + e.printStackTrace(); + sender.sendMessage("§4载入: §c插件 §b" + target.getName() + " §c版本 §d" + getVersion(target) + " §c载入失败!"); + return false; + } + } + + /** + * 载入插件 + * + * @param sender + * - 命令发送者 + * @param name + * - 插件名称 + * @return 是否成功 + */ + public boolean load(CommandSender sender, String name) { + String filename = name; + if (sender == null) { + sender = Bukkit.getConsoleSender(); + } + if (!name.endsWith(".jar")) { + filename = name + ".jar"; + } + File pluginDir = new File("plugins"); + File updateDir = new File(pluginDir, "update"); + if (!pluginDir.isDirectory()) { + sender.sendMessage("§6载入: §c插件目录不存在或IO错误!"); + return false; + } + + File pluginFile = new File(pluginDir, filename); + + if (!pluginFile.isFile() && !new File(updateDir, filename).isFile()) { + pluginFile = null; + for (File file : pluginDir.listFiles()) { + if (file.getName().endsWith(".jar")) { + try { + PluginDescriptionFile desc = main.getPluginLoader().getPluginDescription(file); + if (desc.getName().equalsIgnoreCase(name)) { + pluginFile = file; + break; + } + } catch (InvalidDescriptionException ignored) { + } + } + } + if (pluginFile == null) { + sender.sendMessage("§6载入: §c在插件目录和更新目录均未找到 §b" + name + " §c插件 请确认文件是否存在!"); + return false; + } + } + return load(sender, pluginFile); + } + + /** + * 载入插件 + * + * @param pluginFile + * - 插件名称 + * @return 是否成功 + */ + public boolean load(File pluginFile) { + return load(Bukkit.getConsoleSender(), pluginFile); + } + + /** + * 载入插件 + * + * @param name + * - 插件名称 + * @return 是否成功 + */ + public boolean load(String name) { + return load(Bukkit.getConsoleSender(), name); + } + + /** + * 删除重载插件 + * + * @param sender + * - 命令发送者 + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean reload(CommandSender sender, Plugin plugin) { + if (plugin != null) { return unload(sender, plugin) && load(sender, plugin.getName()); } + return false; + } + + /** + * 删除重载插件 + * + * @param sender + * - 命令发送者 + * @param name + * - 插件 + * @return 是否成功 + */ + public boolean reload(CommandSender sender, String name) { + if (name != null) { return unload(sender, name) && load(sender, name); } + return false; + } + + /** + * 重载插件 + * + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean reload(Plugin plugin) { + return reload(Bukkit.getConsoleSender(), plugin); + } + + /** + * 重载所有插件 + */ + public void reloadAll() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + if (!isIgnored(plugin)) { + unload(plugin); + } + } + Bukkit.getPluginManager().loadPlugins(Bukkit.getUpdateFolderFile().getParentFile()); + } + + /** + * 重载所有插件 + */ + public void reloadAll(CommandSender sender) { + Plugin[] plist = Bukkit.getPluginManager().getPlugins(); + for (Plugin plugin : plist) { + if (!isIgnored(plugin)) { + unload(sender, plugin); + } + } + for (Plugin plugin : plist) { + if (!isIgnored(plugin)) { + load(sender, plugin.getName()); + } + } + } + + /** + * 从忽略列表移除 + * + * @param name + * - 插件名称 + * @return 是否成功 + */ + public boolean removeIgnore(String name) { + return ignoreList.remove(name); + } + + /** + * 卸载插件 + * + * @param sender + * - 命令发送者 + * @param plugin + * - 插件 + * @return 是否成功 + */ + public boolean unload(CommandSender sender, Plugin plugin) { + return unload(sender, plugin.getName()); + } + + /** + * 卸载插件 + * + * @param sender + * - 命令发送者 + * @param name + * - 插件名称 + * @return 是否成功 + */ + @SuppressWarnings("unchecked") + public boolean unload(CommandSender sender, String name) { + if (sender == null) { + sender = Bukkit.getConsoleSender(); + } + PluginManager pluginManager = Bukkit.getPluginManager(); + SimpleCommandMap commandMap = null; + List plugins = null; + Map lookupNames = null; + Map knownCommands = null; + if (pluginManager == null) { + sender.sendMessage("§4异常: §c插件管理类反射获取失败!"); + return false; + } + try { + Class clazz = pluginManager.getClass(); + Field pluginsField = pluginManager.getClass().getDeclaredField("plugins"); + pluginsField.setAccessible(true); + plugins = (List) pluginsField.get(pluginManager); + + Field lookupNamesField = pluginManager.getClass().getDeclaredField("lookupNames"); + lookupNamesField.setAccessible(true); + lookupNames = (Map) lookupNamesField.get(pluginManager); + + Field commandMapField = pluginManager.getClass().getDeclaredField("commandMap"); + commandMapField.setAccessible(true); + commandMap = (SimpleCommandMap) commandMapField.get(pluginManager); + + knownCommands = Reflect.on(commandMap).field("knownCommands").get(); + } catch (Exception e) { + sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!"); + Log.d(e); + return false; + } + String pluginVersion = ""; + for (Plugin next : pluginManager.getPlugins()) { + if (next.getName().equals(name)) { + pluginManager.disablePlugin(next); + if ((plugins != null) && (plugins.contains(next))) { + pluginVersion = getVersion(next); + plugins.remove(next); + sender.sendMessage("§6卸载: §a从服务器插件列表删除 §b" + name + " §a的实例!"); + } + + if ((lookupNames != null) && (lookupNames.containsKey(name))) { + lookupNames.remove(name); + sender.sendMessage("§6卸载: §a从插件查找列表删除 §b" + name + " §a的实例!"); + } + + for (Iterator> it = knownCommands.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = it.next(); + if ((entry.getValue() instanceof PluginCommand)) { + PluginCommand command = (PluginCommand) entry.getValue(); + if (command.getPlugin() == next) { + command.unregister(commandMap); + it.remove(); + } + } + } + + sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!"); + ClassLoader cl = next.getClass().getClassLoader(); + try { + ((URLClassLoader) cl).close(); + } catch (IOException ignored) { + } + System.gc(); + } + } + if (!pluginVersion.isEmpty()) { + sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!"); + return true; + } + return false; + } + + /** + * 卸载插件 + * + * @param plugin + * - 卸载插件 + * @return 是否成功 + */ + public boolean unload(Plugin plugin) { + return unload(Bukkit.getConsoleSender(), plugin); + } + + /** + * 重载update文件夹的插件 + * + * @return 是否成功 + */ + public boolean upgrade(CommandSender sender) { + sender.sendMessage("§6升级: §a开始升级 服务器更新 目录下的所有插件!"); + return upgrade(sender, null, null); + } + + /** + * 重载update文件夹的插件 + * + * @param sender + * - 命令发送者 + * @param directory + * - 更新目录 + * @return 是否成功 + */ + public boolean upgrade(CommandSender sender, File directory, Plugin plugin) { + boolean result = false; + PluginLoader loader = main.getPluginLoader(); + File updateDirectory; + if (directory == null || !directory.isDirectory()) { + updateDirectory = Bukkit.getServer().getUpdateFolderFile(); + } else { + updateDirectory = directory; + } + if (updateDirectory == null) { + sender.sendMessage("§4异常: §c文件夹 §d服务器更新文件夹 §c未找到或IO错误!"); + return false; + } + if (!updateDirectory.exists()) { + updateDirectory.mkdirs(); + } + try { + sender.sendMessage("§6升级: §b从 §d" + updateDirectory.getCanonicalPath() + " §b文件夹检索插件插件!"); + } catch (SecurityException | IOException e1) { + sender.sendMessage("§4异常: §c文件夹 §d" + updateDirectory.getName() + " §c权限不足或IO错误!"); + return false; + } + File[] plugins = updateDirectory.listFiles(); + if (plugins.length == 0) { + sender.sendMessage("§6升级: §d更新文件夹未找到插件!"); + return false; + } + for (File file : updateDirectory.listFiles()) { + if (file.isDirectory()) { + continue; + } + PluginDescriptionFile description = null; + try { + description = loader.getPluginDescription(file); + String name = description.getName(); + if (plugin != null && !name.equals(plugin.getName())) { + continue; + } + Plugin oldplugin = Bukkit.getPluginManager().getPlugin(name); + result = true; + File dest = null; + if (!unload(sender, name)) { + sender.sendMessage("§6升级: §d开始安装 §b" + name + " §d插件!"); + dest = new File(Bukkit.getUpdateFolderFile().getParentFile(), File.separatorChar + file.getName()); + } else { + if (oldplugin != null) { + dest = new File(Bukkit.getUpdateFolderFile(), File.separatorChar + + getPluginFile(oldplugin).getName()); + } + sender.sendMessage("§6升级: §a开始升级 §b" + name + " §a插件!"); + } + if (dest != null) { + file.renameTo(dest); + } + load(sender, name); + } catch (InvalidDescriptionException e) { + sender.sendMessage("§4异常: §c" + e.getMessage()); + sender.sendMessage("§4文件: §c" + file.getName() + " 的plugin.yml文件存在错误!"); + } + if (file.exists()) { + file.delete(); + } + } + sender.sendMessage("§6升级: §a所有插件升级完毕!"); + return result; + } + + /** + * 重载update文件夹的插件 + * + * @return 是否成功 + */ + public boolean upgrade(CommandSender sender, Plugin plugin) { + return upgrade(sender, null, plugin); + } + + /** + * 重载update文件夹的插件 + * + * @return 是否成功 + */ + public boolean upgrade(File directory) { + Bukkit.getConsoleSender().sendMessage("§6升级: §a开始升级 §d" + directory.getName() + " §a目录下的所有插件!"); + return upgrade(Bukkit.getConsoleSender(), directory, null); + } +}