From d298c2c6a6a1a8c8eb44460470bb205fa15fa1be Mon Sep 17 00:00:00 2001 From: 502647092 Date: Thu, 31 Mar 2016 20:31:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pw/yumc/Yum/Yum.java | 6 ++- .../pw/yumc/Yum/commands/FileCommand.java | 4 +- .../java/pw/yumc/Yum/commands/NetCommand.java | 3 +- .../java/pw/yumc/Yum/commands/YumCommand.java | 2 +- .../pw/yumc/Yum/manager/NetworkManager.java | 51 ++++--------------- .../pw/yumc/Yum/manager/PluginsManager.java | 36 ++++++++++--- .../pw/yumc/Yum/manager/SecurityManager.java | 36 +++++++++++++ src/main/resources/plugin.yml | 7 +++ 8 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 src/main/java/pw/yumc/Yum/manager/SecurityManager.java diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java index 82e9fb5..c9a79c8 100644 --- a/src/main/java/pw/yumc/Yum/Yum.java +++ b/src/main/java/pw/yumc/Yum/Yum.java @@ -11,8 +11,10 @@ import cn.citycraft.PluginHelper.config.FileConfig; import cn.citycraft.PluginHelper.utils.VersionChecker; import pw.yumc.Yum.api.YumAPI; import pw.yumc.Yum.commands.FileCommand; +import pw.yumc.Yum.commands.NetCommand; import pw.yumc.Yum.commands.YumCommand; import pw.yumc.Yum.manager.NetworkManager; +import pw.yumc.Yum.manager.SecurityManager; /** * MC插件仓库 @@ -21,7 +23,7 @@ import pw.yumc.Yum.manager.NetworkManager; * @since 2015年8月21日下午5:14:39 */ public class Yum extends JavaPlugin { - public FileConfig config; + FileConfig config; NetworkManager netmgr; @Override @@ -38,7 +40,9 @@ public class Yum extends JavaPlugin { public void onEnable() { new YumAPI(this); new YumCommand(this); + new NetCommand(this); new FileCommand(this); + new SecurityManager(this); new VersionChecker(this); YumAPI.updaterepo(Bukkit.getConsoleSender()); YumAPI.updatecheck(Bukkit.getConsoleSender()); diff --git a/src/main/java/pw/yumc/Yum/commands/FileCommand.java b/src/main/java/pw/yumc/Yum/commands/FileCommand.java index 0a674c3..84cbad6 100644 --- a/src/main/java/pw/yumc/Yum/commands/FileCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/FileCommand.java @@ -28,7 +28,7 @@ public class FileCommand implements HandlerCommands { plugin = yum; dl = YumAPI.getDownload(); final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file"); - cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyFileCommandConsole", true)); + cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true)); cmdhandler.registerCommands(this); } @@ -131,7 +131,7 @@ public class FileCommand implements HandlerCommands { sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!"); return; } - for (final String name : plugin.config.getStringList("blacklist")) { + for (final String name : plugin.getConfig().getStringList("blacklist")) { if (file.getAbsolutePath().toLowerCase().endsWith(name)) { sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c不允许被删除!"); return; diff --git a/src/main/java/pw/yumc/Yum/commands/NetCommand.java b/src/main/java/pw/yumc/Yum/commands/NetCommand.java index 4695cc2..aec8360 100644 --- a/src/main/java/pw/yumc/Yum/commands/NetCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/NetCommand.java @@ -7,9 +7,10 @@ import cn.citycraft.PluginHelper.commands.InvokeSubCommand; import pw.yumc.Yum.Yum; public class NetCommand implements HandlerCommands { + public NetCommand(final Yum yum) { final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net"); - cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyNetCommandConsole", false)); + cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyNetCommandConsole", false)); cmdhandler.registerCommands(this); } diff --git a/src/main/java/pw/yumc/Yum/commands/YumCommand.java b/src/main/java/pw/yumc/Yum/commands/YumCommand.java index 39c0ab8..467c803 100644 --- a/src/main/java/pw/yumc/Yum/commands/YumCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/YumCommand.java @@ -45,7 +45,7 @@ public class YumCommand implements HandlerCommands, Listener { plugman = YumAPI.getPlugman(); Bukkit.getPluginManager().registerEvents(this, yum); final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum"); - cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyCommandConsole", false)); + cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false)); cmdhandler.registerCommands(this); } diff --git a/src/main/java/pw/yumc/Yum/manager/NetworkManager.java b/src/main/java/pw/yumc/Yum/manager/NetworkManager.java index ab8e451..2e629b1 100644 --- a/src/main/java/pw/yumc/Yum/manager/NetworkManager.java +++ b/src/main/java/pw/yumc/Yum/manager/NetworkManager.java @@ -5,7 +5,6 @@ import java.net.Proxy; import java.net.ProxySelector; import java.net.SocketAddress; import java.net.URI; -import java.util.HashMap; import java.util.List; import org.bukkit.Bukkit; @@ -13,6 +12,7 @@ import org.bukkit.plugin.Plugin; import cn.citycraft.PluginHelper.config.FileConfig; import cn.citycraft.PluginHelper.kit.ExceptionKit; +import cn.citycraft.PluginHelper.kit.PluginKit; import pw.yumc.Yum.Yum; /** @@ -24,7 +24,7 @@ import pw.yumc.Yum.Yum; public class NetworkManager { public NetworkManager register(final Yum plugin) { - Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §a注入网络管理系统 将托管服务器网络!"); + Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!"); ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin)); return this; } @@ -41,7 +41,6 @@ public class NetworkManager { private final boolean allowPrimaryThread; private final FileConfig config; private final ProxySelector defaultSelector; - private final HashMap pluginMap = new HashMap<>(); public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) { this.config = plugin.getConfig(); @@ -61,19 +60,17 @@ public class NetworkManager { @Override public List select(final URI uri) { - if (debug || Bukkit.isPrimaryThread()) { - final Plugin plugin = this.getRequestingPlugin(); + final boolean isPrimaryThread = Bukkit.isPrimaryThread(); + if (debug || isPrimaryThread) { + final Plugin plugin = PluginKit.getOperatePlugin(); final String urlinfo = uri.toString(); - if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml")) { - final String str = debug ? "§6[§bYum-网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!" : "§6[§bYum-网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!"; - if (plugin == null) { - Bukkit.getConsoleSender().sendMessage(String.format(str, "未知(请查看堆栈)", urlinfo)); - Thread.dumpStack(); - } else if (!plugin.getName().equalsIgnoreCase("Yum")) { + if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml") && !urlinfo.toLowerCase().contains("502647092")) { + final String str = isPrimaryThread ? "§6[§bYum §a网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!" : "§6[§bYum §a网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!"; + if (plugin != null) { Bukkit.getConsoleSender().sendMessage(String.format(str, plugin.getName(), urlinfo)); - if (!allowPrimaryThread) { - Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!"); - ExceptionKit.throwException(new IOException("[Yum-网络管理] 已开启网络防护 不允许在主线程访问网络!")); + if (!allowPrimaryThread && isPrimaryThread) { + Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!"); + ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 不允许在主线程访问网络!")); } } } @@ -81,32 +78,6 @@ public class NetworkManager { return defaultSelector.select(uri); } - private void collectPlugin() { - if (Bukkit.getPluginManager().getPlugins().length != pluginMap.keySet().size() - 1) { - pluginMap.clear(); - for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - pluginMap.put(plugin.getClass().getClassLoader(), plugin); - } - } - } - - private Plugin getRequestingPlugin() { - collectPlugin(); - final StackTraceElement[] stacktrace = new Exception().getStackTrace(); - for (final StackTraceElement element : stacktrace) { - try { - final ClassLoader loader = Class.forName(element.getClassName(), false, getClass().getClassLoader()).getClassLoader(); - if (pluginMap.containsKey(loader)) { - final Plugin p = pluginMap.get(loader); - if (element.getClassName().contains("pw.yumc.Yum.utils.") || !p.getName().equalsIgnoreCase("Yum")) { - return p; - } - } - } catch (final ClassNotFoundException ex) { - } - } - return null; - } } } diff --git a/src/main/java/pw/yumc/Yum/manager/PluginsManager.java b/src/main/java/pw/yumc/Yum/manager/PluginsManager.java index cb2d485..76b6643 100644 --- a/src/main/java/pw/yumc/Yum/manager/PluginsManager.java +++ b/src/main/java/pw/yumc/Yum/manager/PluginsManager.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -30,6 +31,7 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.UnknownDependencyException; +import org.bukkit.plugin.java.JavaPluginLoader; import com.google.common.base.Joiner; @@ -536,8 +538,7 @@ public class PluginsManager { List plugins = null; Map lookupNames = null; Map knownCommands = null; - // ###移除类加载器后会导致插件无法载入### - // Map fileAssociations = null; + final Map fileAssociations = null; if (pluginManager == null) { sender.sendMessage("§4异常: §c插件管理类反射获取失败!"); return false; @@ -558,11 +559,11 @@ public class PluginsManager { final Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands"); knownCommandsField.setAccessible(true); knownCommands = (Map) knownCommandsField.get(commandMap); - - // ###移除类加载器后会导致插件无法载入### + // XXX 暂时用不到 // final Field fileAssociationsField = pluginManager.getClass().getDeclaredField("fileAssociations"); // fileAssociationsField.setAccessible(true); - // fileAssociations = (Map) fileAssociationsField.get(pluginManager); + // fileAssociations = (Map) fileAssociationsField.get(pluginManager); + } catch (final Exception e) { sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!"); return false; @@ -592,16 +593,39 @@ public class PluginsManager { } } } + // try { + // if (fileAssociations != null) { + // // XXX 不能移除 会导致无法加载 + // for (final Iterator> filter = fileAssociations.entrySet().iterator(); filter.hasNext();) { + // final Entry entry = filter.next(); + // final Matcher match = entry.getKey().matcher(getPluginFile(next).getName()); + // if (match.find()) { + // final JavaPluginLoader pluginLoader = entry.getValue(); + // final Field loadersField = pluginLoader.getClass().getDeclaredField("loaders"); + // loadersField.setAccessible(true); + // final Map loaders = (Map) loadersField.get(pluginLoader); + // // XXX 不能移除 会导致无法调用其他插件 + // loaders.clear(); + // sender.sendMessage("§6卸载: §a移除插件 §b" + name + " §a的类实例缓存!"); + // } + // } + // } + // } catch (final Exception e) { + // e.printStackTrace(); + // } sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!"); final ClassLoader cl = next.getClass().getClassLoader(); try { ((URLClassLoader) cl).close(); } catch (final IOException ex) { + ex.printStackTrace(); } System.gc(); } } - if (!pluginVersion.isEmpty()) { + if (!pluginVersion.isEmpty()) + + { sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!"); return true; } diff --git a/src/main/java/pw/yumc/Yum/manager/SecurityManager.java b/src/main/java/pw/yumc/Yum/manager/SecurityManager.java new file mode 100644 index 0000000..e654ecb --- /dev/null +++ b/src/main/java/pw/yumc/Yum/manager/SecurityManager.java @@ -0,0 +1,36 @@ +package pw.yumc.Yum.manager; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; + +import cn.citycraft.PluginHelper.kit.PluginKit; +import pw.yumc.Yum.Yum; +import pw.yumc.injected.event.SetOpEvent; + +/** + * + * @since 2016年3月31日 下午3:01:22 + * @author 喵♂呜 + */ +public class SecurityManager implements Listener { + public String warn = "§6[§bYum §a安全系统§6] §c插件 §e%s §c已设置玩家 §a%s §c为OP §4请注意服务器安全!"; + public String prevent = "§6[§bYum §a安全系统§6] §c黑名单插件 §e%s §c尝试设置玩家 §a%s §c为OP §a安全系统已成功拦截!"; + + public SecurityManager(final Yum yum) { + Bukkit.getPluginManager().registerEvents(this, yum); + } + + @EventHandler + public void setop(final SetOpEvent event) { + final Plugin plugin = PluginKit.getOperatePlugin(); + if (plugin != null) { + if (plugin.getName().equalsIgnoreCase("BukkitInjectedTools")) { + Bukkit.getConsoleSender().sendMessage(String.format(prevent, plugin, event.getOfflinePlayer().getName())); + } else { + Bukkit.getConsoleSender().sendMessage(String.format(warn, plugin, event.getOfflinePlayer().getName())); + } + } + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 12b85c2..84245a7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,6 +2,7 @@ name: ${project.artifactId} description: ${project.description} main: ${project.groupId}.${project.artifactId}.${project.artifactId} version: ${project.version}-git-${env.GIT_COMMIT} +load: STARTUP author: 喵♂呜 website: ${ciManagement.url} commands: @@ -23,6 +24,12 @@ commands: usage: §6使用§a/file help§6查看帮助! permission: file.use permission-message: §c你没有 的权限来执行此命令! + security: + description: MC安全管理命令 + aliases: [f] + usage: §6使用§a/security help§6查看帮助! + permission: file.use + permission-message: §c你没有 的权限来执行此命令! permissions: yum.use: description: 插件管理系统使用权限!