diff --git a/pom.xml b/pom.xml index e3a1b87..6065e3a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,98 +1,100 @@ - 4.0.0 - pw.yumc - Yum - 2.7.8 - Yum - Minecraft 服务器插件管理系统 - - ${project.name} - - - src/main/resources - true - - - - - maven-compiler-plugin - 3.1 - - 1.7 - 1.7 - - - - org.apache.maven.plugins - maven-shade-plugin - 2.3 - - false - true - - - pw.yumc:YumCore - - - - - pw.yumc.YumCore - ${project.groupId}.${project.artifactId} - - - - - - package - - shade - - - - - - - - Jenkins - http://ci.yumc.pw/job/${project.artifactId}/ - - - §a全新 2.X 版本 更多守护与优化 - - §c注意 §6- §aYum更新需要§d重启服务器!§c重启服务器!§4重启服务器!; - §b2.7.7 §6- §c修复部分插件重载时提示Plugin already initialized的问题!; - §6- §c修复§eBukkitDev§c下载地址跳转问题...; - §6- §c修复§eBukkitDev§c下载为空时的异常...; - - DEV - UTF-8 - - - - yumc-repo - http://repo.yumc.pw/content/groups/public/ - - - - - jtb - YUMC - http://repo.yumc.pw/content/repositories/yumcenter/ - - - - - pw.yumc - YumCore - jar - 1.5 - - - pw.yumc - BukkitInjectedTools - jar - 1.0 - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + pw.yumc + Yum + 2.7.8 + Yum + Minecraft 服务器插件管理系统 + + ${project.name} + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + false + true + + + pw.yumc:YumCore + + + + + pw.yumc.YumCore + ${project.groupId}.${project.artifactId} + + + + + + package + + shade + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + Jenkins + http://ci.yumc.pw/job/${project.artifactId}/ + + + §a全新 2.X 版本 更多守护与优化 + + §c注意 §6- §aYum更新需要§d重启服务器!§c重启服务器!§4重启服务器!; + §b2.7.7 §6- §c修复部分插件重载时提示Plugin already initialized的问题!; + §6- §c修复§eBukkitDev§c下载地址跳转问题...; + §6- §c修复§eBukkitDev§c下载为空时的异常...; + + DEV + UTF-8 + 1.7 + 1.7 + + + + yumc-repo + http://repo.yumc.pw/content/groups/public/ + + + + + jtb + YUMC + http://repo.yumc.pw/content/repositories/yumcenter/ + + + + + pw.yumc + YumCore + jar + 1.5 + + + pw.yumc + BukkitInjectedTools + jar + 1.0 + + \ No newline at end of file diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java index ba68f63..aed45fe 100644 --- a/src/main/java/pw/yumc/Yum/Yum.java +++ b/src/main/java/pw/yumc/Yum/Yum.java @@ -70,8 +70,6 @@ public class Yum extends JavaPlugin { public void onLoad() { // 初始化配置 ConfigManager.i(); - // 初始化更新列 - // UpdatePlugin.getUpdateList(); // 启用网络注入 NetworkManager.register(this); } @@ -135,7 +133,7 @@ public class Yum extends JavaPlugin { if (tt != null) { tt.cancel(); } - task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 5000); + task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 500); } } } diff --git a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java index a9b1485..8a3367f 100644 --- a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java @@ -11,7 +11,6 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.command.SimpleCommandMap; -import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.plugin.EventExecutor; import org.bukkit.plugin.Plugin; @@ -31,6 +30,7 @@ import pw.yumc.YumCore.commands.CommandSub; import pw.yumc.YumCore.commands.annotation.Async; import pw.yumc.YumCore.commands.annotation.Cmd; import pw.yumc.YumCore.commands.annotation.Help; +import pw.yumc.YumCore.commands.annotation.Option; import pw.yumc.YumCore.commands.interfaces.Executor; import pw.yumc.YumCore.kit.PKit; import pw.yumc.YumCore.kit.StrKit; @@ -60,7 +60,7 @@ public class MonitorCommand implements Executor { private String lag = prefix + "§a当前服务器插件能耗如下§6(单位: %)"; private String lagprefix = " §6插件名称 §c主线程 §a命令 §b事件 §d任务"; - private String laglist = "§6%-2s §b%-20s §c%-25s §a%-5.2f §b%-5.2f §d%-5.2f"; + private String laglist = "§6%-2s §b%-18s §c%-25s §a%-5.2f §b%-5.2f §d%-5.2f"; private String no_error = prefix + "§a自服务器启动以来尚未发现报错!"; private String last_error = prefix + "§c最后一次错误异常由 §b%s §c造成 详细如下:"; @@ -182,17 +182,19 @@ public class MonitorCommand implements Executor { @Cmd(aliases = "l") @Help("查看插件总耗时") @Async - public void lag(CommandSender sender, int size) { + public void lag(CommandSender sender, @Option("def:8") int size) { Map mm = MonitorManager.getMonitor(); - int max = 8; sender.sendMessage(lag); sender.sendMessage(lagprefix); + int index = 0; for (Entry entry : mm.entrySet()) { - if (++size > max) { + if (++index > size) { break; } MonitorInfo mi = MonitorManager.getMonitorInfo(entry.getKey()); - sender.sendMessage(String.format(laglist, size, entry.getKey(), getPer(sender, mi.monitor), mi.cmd, mi.event, mi.task)); + if (mi.monitor != 0) { + sender.sendMessage(String.format(laglist, index, StrKit.substring(entry.getKey(), 0, 18), getPer(sender, mi.monitor), mi.cmd, mi.event, mi.task)); + } } } @@ -209,11 +211,6 @@ public class MonitorCommand implements Executor { lastError.printStackTrace(); } - @Cmd - public void lk(CommandSender sender) { - MonitorManager.sendObject(sender); - } - @Cmd(aliases = "ri") @Help("重载能耗监控器") public void reinject(CommandSender sender) { @@ -279,7 +276,7 @@ public class MonitorCommand implements Executor { } private String getPer(CommandSender sender, double per) { - String ps = sender instanceof Player ? "||" : "|"; + String ps = "≡"; double p = per / 5; StringBuilder sb = new StringBuilder(); if (p < 3) { diff --git a/src/main/java/pw/yumc/Yum/managers/ConfigManager.java b/src/main/java/pw/yumc/Yum/managers/ConfigManager.java index bab7df6..4ecb2b9 100644 --- a/src/main/java/pw/yumc/Yum/managers/ConfigManager.java +++ b/src/main/java/pw/yumc/Yum/managers/ConfigManager.java @@ -81,6 +81,10 @@ public class ConfigManager { return thread.getBoolean("MainThreadCheck", true); } + public boolean isMainThreadDebug() { + return thread.getBoolean("Debug"); + } + public boolean isMonitorDebug() { return monitor.getBoolean("Debug"); } diff --git a/src/main/java/pw/yumc/Yum/managers/MonitorManager.java b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java index 0d1c2a6..8cc9c5f 100644 --- a/src/main/java/pw/yumc/Yum/managers/MonitorManager.java +++ b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java @@ -25,7 +25,7 @@ import pw.yumc.YumCore.kit.LogKit; * @author 喵♂呜 */ public class MonitorManager { - public static String prefix = "§6[§a能耗监控§6] "; + public static String prefix = "§6[§bYum §a能耗监控§6] "; private static String errMsg = prefix + "§c命令执行异常 请反馈下列信息给腐竹!"; private static String errP = "§6插件名称: §b%s"; private static String errN = "§6异常名称: §c%s"; @@ -104,7 +104,7 @@ public class MonitorManager { int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length; for (int i = 0; i < l; i++) { StackTraceElement ste = e.getStackTrace()[i]; - elog(String.format(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName(), ste.getLineNumber())); + elog(String.format(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName() == null ? "未知" : ste.getFileName(), ste.getLineNumber())); } if (debug) { Log.console(devInfo); @@ -126,10 +126,6 @@ public class MonitorManager { sender.sendMessage(String.format(errM, e.getMessage())); } - public static void sendObject(CommandSender sender) { - sender.sendMessage(String.format("totalTime@%s monitor@%s cmd@%s event@%s task@%s", totalTime, sum(monitor.values()), sum(cmd.values()), sum(event.values()), sum(task.values()))); - } - /** * 使用 Map按value进行排序 * diff --git a/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java b/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java index 0206b91..f466c89 100644 --- a/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java +++ b/src/main/java/pw/yumc/Yum/runnables/MainThreadCheckTask.java @@ -7,6 +7,7 @@ import java.util.TimerTask; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.YumCore.bukkit.Log; import pw.yumc.YumCore.bukkit.compatible.C; import pw.yumc.YumCore.kit.PKit; @@ -20,13 +21,14 @@ import pw.yumc.YumCore.plugin.protocollib.PacketKit; */ public class MainThreadCheckTask extends TimerTask { private static Method tickMethod; - private String prefix = "§6[§bYum §a线程管理§6] "; + private String prefix = "§6[§a线程管理§6] "; private String warnPNet = "§6插件 §b%s §c在主线程进行网络操作 §4服务器处于停止状态..."; private String warnPIO = "§6插件 §b%s §c在主线程进行IO操作 §4服务器处于停止状态..."; private String warnNet = "§c主线程存在网络操作 §4服务器处于停止状态..."; private String warnIO = "§c主线程存在IO操作 §4服务器处于停止状态..."; private String deliver = "§c服务器处于停止状态 已超过 %s 秒 激活心跳 防止线程关闭..."; - private int stopTime = 0; + private String errStackTrace = " §e位于 §c%s.%s(§4%s:%s§c)"; + private double stopTime = 0; private Thread mainThread; static { @@ -46,6 +48,7 @@ public class MainThreadCheckTask extends TimerTask { // 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 + String tip = null; 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 @@ -55,30 +58,29 @@ public class MainThreadCheckTask extends TimerTask { // 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") + if (isElementEqual(topElement, "java.net.DualStackPlainSocketImpl", "connect0") || isElementEqual(topElement, "java.net.SocketInputStream", "socketRead0") || isElementEqual(topElement, "java.net.SocketOutputStream", "socketWrite0")) { Plugin plugin = PKit.getOperatePlugin(stackTrace); - if (plugin != null) { - Log.console(prefix + warnPNet, plugin.getName()); - } else { - Log.console(prefix + warnNet); - } - tick(); + tip = plugin != null ? String.format(warnPNet, plugin.getName()) : warnNet; } // 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")) { + else if (isElementEqual(topElement, "java.io.FileInputStream", "readBytes") || isElementEqual(topElement, "java.io.FileOutputStream", "writeBytes")) { Plugin plugin = PKit.getOperatePlugin(stackTrace); - if (plugin != null) { - Log.console(prefix + warnPIO, plugin.getName()); - } else { - Log.console(prefix + warnIO); + tip = plugin != null ? String.format(warnPIO, plugin.getName()) : warnIO; + } + } + if (tip != null) { + tick(); + if (stopTime > 1) { + Log.console(prefix + tip); + if (ConfigManager.i().isMainThreadDebug()) { + int l = stackTrace.length > 10 ? 10 : stackTrace.length; + for (int i = 0; i < l; i++) { + StackTraceElement ste = stackTrace[i]; + Log.console(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName() == null ? "未知" : ste.getFileName(), ste.getLineNumber()); + } } - tick(); - } else { - stopTime = 0; } } else { stopTime = 0; @@ -91,8 +93,8 @@ public class MainThreadCheckTask extends TimerTask { } private void tick() { - stopTime += 5; - if (stopTime >= 45) { + stopTime += 0.5; + if (stopTime >= 45 && stopTime % 5 == 0) { Log.console(prefix + deliver, stopTime); wttick(); } @@ -107,10 +109,10 @@ public class MainThreadCheckTask extends TimerTask { tickMethod.invoke(null); } for (final Player player : C.Player.getOnlinePlayers()) { - player.sendMessage("§4注意: §c服务器主线程处于停止状态 请等待操作完成!"); + Log.sender(player, "§4注意: §c服务器主线程处于停止状态 请等待操作完成!"); PacketKit.keep_live(player); } - } catch (final Throwable e) { + } catch (final Throwable ignored) { } } } diff --git a/src/main/resources/thread.yml b/src/main/resources/thread.yml index e85bcf0..0005117 100644 --- a/src/main/resources/thread.yml +++ b/src/main/resources/thread.yml @@ -3,9 +3,11 @@ ############################ #配置版本号 请勿修改!!! -Version: 1.0 +Version: 1.1 #是否开启线程安全检测 ThreadSafe: true #是否开启主线程IO检测 -MainThreadCheck: true \ No newline at end of file +MainThreadCheck: true +#是否开启调试模式 +Debug: false \ No newline at end of file