From 44842a38ece6ce26d7fa0cb16029cfe392e5d44f Mon Sep 17 00:00:00 2001 From: 502647092 Date: Fri, 24 Jun 2016 18:32:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=B8=BB=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E9=98=BB=E6=96=AD=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.修复网络监测 2.修复配置文件错误 Signed-off-by: 502647092 --- pom.xml | 2 +- src/main/java/pw/yumc/Yum/Yum.java | 76 ++++++++++++------- src/main/java/pw/yumc/Yum/api/YumAPI.java | 29 +++---- .../Yum/listeners/PluginNetworkListener.java | 20 +++-- .../pw/yumc/Yum/managers/ConfigManager.java | 13 ++-- .../pw/yumc/Yum/managers/NetworkManager.java | 15 ++-- .../Yum/runnables/MainThreadCheckTask.java | 53 +++++++++++++ src/main/resources/network.yml | 1 + 8 files changed, 144 insertions(+), 65 deletions(-) create mode 100644 src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java diff --git a/pom.xml b/pom.xml index f0fda46..263485a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 pw.yumc Yum - 2.1 + 2.2 Yum Minecraft 服务器插件管理系统 diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java index d0c5c10..fde2308 100644 --- a/src/main/java/pw/yumc/Yum/Yum.java +++ b/src/main/java/pw/yumc/Yum/Yum.java @@ -3,7 +3,10 @@ */ package pw.yumc.Yum; +import java.util.Timer; + import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.java.JavaPlugin; import cn.citycraft.CommonData.UpdatePlugin; @@ -17,6 +20,7 @@ import pw.yumc.Yum.listeners.PluginNetworkListener; import pw.yumc.Yum.listeners.SecurityListener; import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.Yum.managers.NetworkManager; +import pw.yumc.Yum.runnables.MainThreadCheckTask; /** * MC插件仓库 @@ -25,15 +29,50 @@ import pw.yumc.Yum.managers.NetworkManager; * @since 2015年8月21日下午5:14:39 */ public class Yum extends JavaPlugin { - NetworkManager netmgr; + @Override + public FileConfiguration getConfig() { + return ConfigManager.i().config; + } - public void initCommands() { + @Override + public void onDisable() { + NetworkManager.unregister(); + } + + @Override + public void onEnable() { + new YumAPI(this); + initCommands(); + initListeners(); + initRunnable(); + new VersionChecker(this); + YumAPI.updaterepo(Bukkit.getConsoleSender()); + YumAPI.updatecheck(Bukkit.getConsoleSender()); + } + + @Override + public void onLoad() { + // 初始化配置 + ConfigManager.i(); + // 初始化更新列 + UpdatePlugin.getUpdateList(); + // 启用网络注入 + NetworkManager.register(this); + } + + /** + * 初始化命令 + */ + private void initCommands() { new YumCommand(this); new NetCommand(this); new FileCommand(this); } - public void initListeners() { + /** + * 初始化监听 + */ + private void initListeners() { if (ConfigManager.i().isSetOpEnable()) { try { final ClassLoader cl = Class.forName("pw.yumc.injected.event.SetOpEvent").getClassLoader(); @@ -52,30 +91,15 @@ public class Yum extends JavaPlugin { new PluginNetworkListener(this); PluginKit.scp("§a网络管理系统已启用..."); } + new } - @Override - public void onDisable() { - netmgr.unregister(); - } - - @Override - public void onEnable() { - new YumAPI(this); - initCommands(); - initListeners(); - new VersionChecker(this); - YumAPI.updaterepo(Bukkit.getConsoleSender()); - YumAPI.updatecheck(Bukkit.getConsoleSender()); - } - - @Override - public void onLoad() { - // 初始化配置 - ConfigManager.i(); - // 初始化更新列 - UpdatePlugin.getUpdateList(); - // 启用网络注入 - netmgr = new NetworkManager().register(this); + /** + * 初始化任务 + */ + private void initRunnable() { + final Timer task = new Timer(); + PluginKit.scp("§a线程管理系统已启用..."); + task.scheduleAtFixedRate(new MainThreadCheckTask(Thread.currentThread()), 0, 3000); } } diff --git a/src/main/java/pw/yumc/Yum/api/YumAPI.java b/src/main/java/pw/yumc/Yum/api/YumAPI.java index 162d81a..45c1e3b 100644 --- a/src/main/java/pw/yumc/Yum/api/YumAPI.java +++ b/src/main/java/pw/yumc/Yum/api/YumAPI.java @@ -11,6 +11,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; import cn.citycraft.CommonData.UpdatePlugin; +import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.Yum.managers.DownloadManager; import pw.yumc.Yum.managers.PluginsManager; import pw.yumc.Yum.managers.RepositoryManager; @@ -29,20 +30,6 @@ public class YumAPI { private static RepositoryManager repo; private static boolean runlock = false; - /** - * 初始化Yum管理中心 - * - * @param plugin - * 插件实体 - */ - public YumAPI(final Plugin plugin) { - YumAPI.main = plugin; - plugman = new PluginsManager(main); - download = new DownloadManager(main); - repo = new RepositoryManager(main); - plugman.addIgnore(main.getConfig().getStringList("ignorelist")); - } - /** * 删除插件 * @@ -366,4 +353,18 @@ public class YumAPI { public static void upgrade(final CommandSender sender, final Plugin plugin) { plugman.upgrade(sender, plugin); } + + /** + * 初始化Yum管理中心 + * + * @param plugin + * 插件实体 + */ + public YumAPI(final Plugin plugin) { + YumAPI.main = plugin; + plugman = new PluginsManager(main); + download = new DownloadManager(main); + repo = new RepositoryManager(main); + plugman.addIgnore(ConfigManager.i().getIgnoreList()); + } } diff --git a/src/main/java/pw/yumc/Yum/listeners/PluginNetworkListener.java b/src/main/java/pw/yumc/Yum/listeners/PluginNetworkListener.java index 16ad896..7e3a790 100644 --- a/src/main/java/pw/yumc/Yum/listeners/PluginNetworkListener.java +++ b/src/main/java/pw/yumc/Yum/listeners/PluginNetworkListener.java @@ -1,32 +1,38 @@ package pw.yumc.Yum.listeners; -import java.io.IOException; - import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; -import cn.citycraft.PluginHelper.kit.ExceptionKit; +import cn.citycraft.PluginHelper.kit.PluginKit; import pw.yumc.Yum.Yum; import pw.yumc.Yum.events.PluginNetworkEvent; import pw.yumc.Yum.managers.ConfigManager; public class PluginNetworkListener implements Listener { + public String prefix = "§6[§bYum §a网络管理§6] "; public PluginNetworkListener(final Yum yum) { Bukkit.getPluginManager().registerEvents(this, yum); } + @EventHandler public void onPluginNetworkConect(final PluginNetworkEvent e) { final Plugin plugin = e.getPlugin(); final String urlinfo = e.getUrl().toString(); final boolean isPrimaryThread = e.isPrimaryThread(); - 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请注意服务器网络安全!"; + final String str = prefix + (isPrimaryThread ? "§c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!" : "§c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!"); if (plugin != null) { - Bukkit.getConsoleSender().sendMessage(String.format(str, plugin.getName(), urlinfo)); + if (ConfigManager.i().getNetworkBlackList().contains(plugin.getName())) { + PluginKit.sc(prefix + "§4已阻止黑名单插件 §b" + plugin.getName() + " §4访问网络!"); + PluginKit.sc(prefix + "§4地址: " + urlinfo); + return; + } + PluginKit.sc(String.format(str, plugin.getName(), urlinfo)); if (!ConfigManager.i().isAllowPrimaryThread() && isPrimaryThread) { - Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!"); - ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 不允许在主线程访问网络!")); + PluginKit.sc(prefix + "§4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!"); + e.setCancelled(true); } } } diff --git a/src/main/java/pw/yumc/Yum/managers/ConfigManager.java b/src/main/java/pw/yumc/Yum/managers/ConfigManager.java index 3080a81..2f939ed 100644 --- a/src/main/java/pw/yumc/Yum/managers/ConfigManager.java +++ b/src/main/java/pw/yumc/Yum/managers/ConfigManager.java @@ -8,18 +8,15 @@ import cn.citycraft.PluginHelper.config.FileConfig; import cn.citycraft.PluginHelper.kit.PKit; public class ConfigManager { - private static List blackList; - private static List ignoreList; - private final static String ENABLE = "Enable"; private final static String BLACK = "Black"; private final static String IGNORE = "Ignore"; private final static ConfigManager i = new ConfigManager(PKit.i()); - private final FileConfig config; - private final FileConfig setop; - private final FileConfig network; + public final FileConfig config; + public final FileConfig setop; + public final FileConfig network; public static ConfigManager i() { return i; @@ -32,11 +29,11 @@ public class ConfigManager { } public List getBlackList() { - return blackList; + return config.getStringList("blacklist"); } public List getIgnoreList() { - return ignoreList; + return config.getStringList("ignorelist"); } public List getNetworkBlackList() { diff --git a/src/main/java/pw/yumc/Yum/managers/NetworkManager.java b/src/main/java/pw/yumc/Yum/managers/NetworkManager.java index 9872f65..1217b78 100644 --- a/src/main/java/pw/yumc/Yum/managers/NetworkManager.java +++ b/src/main/java/pw/yumc/Yum/managers/NetworkManager.java @@ -8,8 +8,8 @@ import java.net.URI; import java.util.List; import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; +import cn.citycraft.PluginHelper.kit.ExceptionKit; import cn.citycraft.PluginHelper.kit.PluginKit; import pw.yumc.Yum.Yum; import pw.yumc.Yum.events.PluginNetworkEvent; @@ -22,20 +22,19 @@ import pw.yumc.Yum.events.PluginNetworkEvent; */ public class NetworkManager { - public NetworkManager register(final Yum plugin) { + public static void register(final Yum plugin) { Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!"); ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin)); - return this; } - public void unregister() { + public static void unregister() { final ProxySelector cur = ProxySelector.getDefault(); if (cur instanceof YumProxySelector) { ProxySelector.setDefault(((YumProxySelector) cur).getDefaultSelector()); } } - class YumProxySelector extends ProxySelector { + static class YumProxySelector extends ProxySelector { private final ProxySelector defaultSelector; public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) { @@ -53,12 +52,10 @@ public class NetworkManager { @Override public List select(final URI uri) { - final boolean isPrimaryThread = Bukkit.isPrimaryThread(); - final Plugin plugin = PluginKit.getOperatePlugin(); - final PluginNetworkEvent pne = new PluginNetworkEvent(plugin, uri, isPrimaryThread); + final PluginNetworkEvent pne = new PluginNetworkEvent(PluginKit.getOperatePlugin(), uri, Bukkit.isPrimaryThread()); Bukkit.getPluginManager().callEvent(pne); if (pne.isCancelled()) { - return null; + ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 不允许在主线程访问网络!")); } return defaultSelector.select(uri); } diff --git a/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java b/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java new file mode 100644 index 0000000..8b95a10 --- /dev/null +++ b/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java @@ -0,0 +1,53 @@ +package pw.yumc.Yum.runnables; + +import java.lang.Thread.State; +import java.util.TimerTask; +import java.util.logging.Level; + +import cn.citycraft.PluginHelper.kit.PKit; + +/** + * + * @since 2016年6月22日 下午4:57:32 + * @author 喵♂呜 + */ +public class MainThreadCheckTask extends TimerTask { + + private final Thread mainThread; + + public MainThreadCheckTask(final Thread mainThread) { + this.mainThread = mainThread; + } + + @Override + public void run() { + // According to this post the thread is still in Runnable although it's waiting for + // file/http ressources + // https://stackoverflow.com/questions/20795295/why-jstack-out-says-thread-state-is-runnable-while-socketread + if (mainThread.getState() == State.RUNNABLE) { + // Based on this post we have to check the top element of the stack + // https://stackoverflow.com/questions/20891386/how-to-detect-thread-being-blocked-by-io + final StackTraceElement[] stackTrace = mainThread.getStackTrace(); + final StackTraceElement topElement = stackTrace[0]; + if (topElement.isNativeMethod()) { + // Socket/SQL (connect) - java.net.DualStackPlainSocketImpl.connect0 + // Socket/SQL (read) - java.net.SocketInputStream.socketRead0 + // Socket/SQL (write) - java.net.SocketOutputStream.socketWrite0 + if (isElementEqual(topElement, "java.net.DualStackPlainSocketImpl", "connect0") + || isElementEqual(topElement, "java.net.SocketInputStream", "socketRead0") + || isElementEqual(topElement, "java.net.SocketOutputStream", "socketWrite0")) { + PKit.i().getLogger().log(Level.WARNING, "主线程存在网络操作 服务器处于停止状态...", stackTrace); + } + // File (in) - java.io.FileInputStream.readBytes + // File (out) - java.io.FileOutputStream.writeBytes + else if (isElementEqual(topElement, "java.io.FileInputStream", "readBytes") || isElementEqual(topElement, "java.io.FileOutputStream", "writeBytes")) { + PKit.i().getLogger().log(Level.WARNING, "主线程存在IO操作 服务器处于停止状态...", stackTrace); + } + } + } + } + + private boolean isElementEqual(final StackTraceElement traceElement, final String className, final String methodName) { + return traceElement.getClassName().equals(className) && traceElement.getMethodName().equals(methodName); + } +} diff --git a/src/main/resources/network.yml b/src/main/resources/network.yml index 963bde5..c39e0cc 100644 --- a/src/main/resources/network.yml +++ b/src/main/resources/network.yml @@ -3,6 +3,7 @@ Enable: true #黑名单列表 Black: - BukkitInjectedTools +- FeatherBoard #忽略检测列表 Ignore: - Essentials \ No newline at end of file