diff --git a/pom.xml b/pom.xml
index 11d90f2..2e0391f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
pw.yumc
Yum
- 2.6.4
+ 2.6.5
Yum
Minecraft 服务器插件管理系统
@@ -60,6 +60,7 @@
&a全新 2.X 版本 更多守护与优化
+ &b2.6.5 &6- &c修复list命令 &a添加全局能耗统计...;
&b2.6.4 &6- &e添加从&bBukkitDev&e下载和更新...;
&b2.6.3 &6- &a注入操作延时执行 防止部分任务未注册 添加手动注入...;
&b2.6.2 &6- &d能耗监控添加忽略列表 &3详见monitor.yml...;
diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java
index ff1c3ee..c9e456c 100644
--- a/src/main/java/pw/yumc/Yum/Yum.java
+++ b/src/main/java/pw/yumc/Yum/Yum.java
@@ -33,6 +33,7 @@ import pw.yumc.Yum.runnables.MainThreadCheckTask;
* @since 2015年8月21日下午5:14:39
*/
public class Yum extends JavaPlugin {
+ public static boolean disable = false;;
public static Thread mainThread = null;
public static Timer task = new Timer();
public static TimerTask tt;
@@ -45,6 +46,7 @@ public class Yum extends JavaPlugin {
@Override
public void onDisable() {
NetworkManager.unregister();
+ disable = true;
}
@Override
@@ -59,6 +61,10 @@ public class Yum extends JavaPlugin {
new VersionChecker(this);
YumAPI.updateRepo(Bukkit.getConsoleSender());
YumAPI.updateCheck(Bukkit.getConsoleSender());
+ if (disable) {
+ YumAPI.updateInject();
+ disable = false;
+ }
}
@Override
diff --git a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java
index a828778..e6a98ae 100644
--- a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java
+++ b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java
@@ -32,6 +32,8 @@ import pw.yumc.Yum.inject.CommandInjector;
import pw.yumc.Yum.inject.ListenerInjector;
import pw.yumc.Yum.inject.TaskInjector;
import pw.yumc.Yum.managers.ConfigManager;
+import pw.yumc.Yum.managers.MonitorManager;
+import pw.yumc.Yum.managers.MonitorManager.MonitorInfo;
/**
*
@@ -49,16 +51,20 @@ public class MonitorCommand implements HandlerCommands {
private final String avg = "§6平均耗时: §d%.5f毫秒!";
private final String avg_warn = "§6平均耗时: §c%.5f毫秒!";
- private final String injected = "§a插件 §b%s §a成功注入能耗监控器!";
- private final String uninjected = "§a插件 §b%s §a成功撤销能耗监控器!";
- private final String notEnable = "§c插件 §b%s §c未成功加载 无法执行注入!";
+ private final String reinject = prefix + "§a能耗监控器重载完毕!";
+ private final String injected = prefix + "§a插件 §b%s §a成功注入能耗监控器!";
+ private final String uninjected = prefix + "§a插件 §b%s §a成功撤销能耗监控器!";
+ private final String notEnable = prefix + "§c插件 §b%s §c未成功加载 无法执行注入!";
+
+ private final String lagprefix = "§6插件名称 §c主线程耗时 §a命令耗时 §b事件耗时 §d任务耗时";
+ private final String laglist = "§b%-15s §c%-11.2f §a%-9.2f §b%-9.2f §d%-9.2f";
private final String no_error = prefix + "§a自服务器启动以来尚未发现报错!";
private final String last_error = prefix + "§c最后一次错误异常由 §b%s §c造成 详细如下:";
private final String p_n_f = prefix + "§c插件 §b%s §c不存在!";
- private final double um = 1000000.0;
+ private final double um = 1000000.00;
public MonitorCommand(final Yum yum) {
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
@@ -140,7 +146,7 @@ public class MonitorCommand implements HandlerCommands {
}
for (final String event : eventTotalTime.keySet()) {
final StringBuffer str = new StringBuffer();
- str.append("§6- §e" + event + " ");
+ str.append(String.format("§6- §e%-25s ", event));
str.append(String.format(total, eventTotalTime.get(event) / um));
str.append(String.format(count, eventCount.get(event)));
if (eventCount.get(event) != 0) {
@@ -162,9 +168,24 @@ public class MonitorCommand implements HandlerCommands {
}
if (plugin.isEnabled()) {
YumAPI.inject(plugin);
- sender.sendMessage(String.format(prefix + injected, pname));
+ sender.sendMessage(String.format(injected, pname));
} else {
- sender.sendMessage(String.format(prefix + notEnable, pname));
+ sender.sendMessage(String.format(notEnable, pname));
+ }
+ }
+
+ @HandlerCommand(name = "lag", aliases = "l", description = "查看插件总耗时")
+ public void lag(final InvokeCommandEvent e) {
+ final CommandSender sender = e.getSender();
+ final Map mm = MonitorManager.getMonitor();
+ int i = 0;
+ sender.sendMessage(lagprefix);
+ for (final Entry entry : mm.entrySet()) {
+ if (i++ > 5) {
+ break;
+ }
+ final MonitorInfo mi = MonitorManager.getMonitorInfo(entry.getKey());
+ sender.sendMessage(String.format(laglist, entry.getKey(), mi.monitor, mi.cmd, mi.event, mi.task));
}
}
@@ -182,6 +203,13 @@ public class MonitorCommand implements HandlerCommands {
}
}
+ @HandlerCommand(name = "reinject", aliases = "i", description = "重载能耗监控器")
+ public void reinject(final InvokeCommandEvent e) {
+ final CommandSender sender = e.getSender();
+ YumAPI.updateInject();
+ sender.sendMessage(reinject);
+ }
+
@HandlerCommand(name = "task", description = "查看插件任务能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
public void task(final InvokeCommandEvent e) {
final String pname = e.getArgs()[0];
@@ -199,8 +227,7 @@ public class MonitorCommand implements HandlerCommands {
if (task instanceof TaskInjector) {
final TaskInjector executor = (TaskInjector) task;
final StringBuffer str = new StringBuffer();
- final Class extends Runnable> taskName = executor.getOriginalTask().getClass();
- str.append("§6- §e" + (StrKit.isBlank(taskName.getSimpleName()) ? taskName.getName() : taskName.getSimpleName()) + " ");
+ str.append("§6- §e" + getClassName(executor.getOriginalTask().getClass()) + " ");
str.append(String.format(total, executor.totalTime / um));
str.append(String.format(count, executor.count));
if (executor.count != 0) {
@@ -223,7 +250,11 @@ public class MonitorCommand implements HandlerCommands {
}
if (plugin.isEnabled()) {
YumAPI.uninject(plugin);
- sender.sendMessage(String.format(prefix + uninjected, pname));
+ sender.sendMessage(String.format(uninjected, pname));
}
}
+
+ private String getClassName(final Class> clazz) {
+ return StrKit.isBlank(clazz.getSimpleName()) ? clazz.getName().substring(clazz.getName().lastIndexOf(".") + 1) : clazz.getSimpleName();
+ }
}
diff --git a/src/main/java/pw/yumc/Yum/commands/YumCommand.java b/src/main/java/pw/yumc/Yum/commands/YumCommand.java
index 2a9207c..0e2bb1a 100644
--- a/src/main/java/pw/yumc/Yum/commands/YumCommand.java
+++ b/src/main/java/pw/yumc/Yum/commands/YumCommand.java
@@ -253,7 +253,9 @@ public class YumCommand implements HandlerCommands, Listener {
fm.then(unload).command("yum unload " + pname);
fm.then(" ");
fm.then(reload).command("yum re " + pname);
+ fm.then(" ");
fm.then(delete).command("yum del " + pname);
+ fm.send(sender);
}
}
diff --git a/src/main/java/pw/yumc/Yum/inject/CommandInjector.java b/src/main/java/pw/yumc/Yum/inject/CommandInjector.java
index 2c86199..45c3cf3 100644
--- a/src/main/java/pw/yumc/Yum/inject/CommandInjector.java
+++ b/src/main/java/pw/yumc/Yum/inject/CommandInjector.java
@@ -18,6 +18,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.kit.StrKit;
import pw.yumc.Yum.commands.MonitorCommand;
+import pw.yumc.Yum.managers.MonitorManager;
public class CommandInjector implements TabExecutor {
private final String prefix = "§6[§bYum §a命令监控§6] ";
@@ -43,11 +44,13 @@ public class CommandInjector implements TabExecutor {
final PluginCommand pluginCommand = (PluginCommand) command;
final Plugin plugin = pluginCommand.getPlugin();
if (plugin.equals(toInjectPlugin)) {
- final CommandExecutor executor = Reflect.on(command).get("executor");
+ CommandExecutor executor = Reflect.on(command).get("executor");
+ TabCompleter completer = Reflect.on(command).get("completer");;
if (executor instanceof CommandInjector) {
- return;
+ final CommandInjector cInjector = (CommandInjector) executor;
+ executor = cInjector.getOriginalExecutor();
+ completer = cInjector.getOriginalCompleter();
}
- final TabCompleter completer = Reflect.on(command).get("completer");
final CommandInjector commandInjector = new CommandInjector(executor, completer, toInjectPlugin);
Reflect.on(command).set("executor", commandInjector);
Reflect.on(command).set("completer", commandInjector);
@@ -100,6 +103,7 @@ public class CommandInjector implements TabExecutor {
}
totalTime += lag;
count++;
+ MonitorManager.addCmd(plugin.getName(), lag);
return result;
} catch (Throwable e) {
while (e.getCause() != null) {
diff --git a/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java b/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java
index 206f847..1c9731d 100644
--- a/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java
+++ b/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java
@@ -17,6 +17,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.commands.MonitorCommand;
import pw.yumc.Yum.managers.ConfigManager;
+import pw.yumc.Yum.managers.MonitorManager;
public class ListenerInjector implements EventExecutor {
private final String prefix = "§6[§bYum §a事件监控§6] ";
@@ -40,9 +41,9 @@ public class ListenerInjector implements EventExecutor {
if (listener instanceof TimedRegisteredListener) {
return;
}
- final EventExecutor originalExecutor = Reflect.on(listener).get("executor");
+ EventExecutor originalExecutor = Reflect.on(listener).get("executor");
if (originalExecutor instanceof ListenerInjector) {
- return;
+ originalExecutor = ((ListenerInjector) originalExecutor).getOriginalExecutor();
}
final ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
Reflect.on(listener).set("executor", listenerInjector);
@@ -82,6 +83,7 @@ public class ListenerInjector implements EventExecutor {
eventTotalTime.put(en, end - start);
eventCount.put(en, 1);
}
+ MonitorManager.addEvent(plugin.getName(), lag);
} else {
originalExecutor.execute(listener, event);
}
diff --git a/src/main/java/pw/yumc/Yum/inject/TaskInjector.java b/src/main/java/pw/yumc/Yum/inject/TaskInjector.java
index cfc13d4..c569c46 100644
--- a/src/main/java/pw/yumc/Yum/inject/TaskInjector.java
+++ b/src/main/java/pw/yumc/Yum/inject/TaskInjector.java
@@ -11,6 +11,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.kit.StrKit;
import pw.yumc.Yum.commands.MonitorCommand;
+import pw.yumc.Yum.managers.MonitorManager;
public class TaskInjector implements Runnable {
private final String prefix = "§6[§bYum §a任务监控§6] ";
@@ -38,9 +39,9 @@ public class TaskInjector implements Runnable {
for (final BukkitTask pendingTask : pendingTasks) {
// 忽略异步任务
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
- final Runnable originalTask = Reflect.on(pendingTask).get("task");
+ Runnable originalTask = Reflect.on(pendingTask).get("task");
if (originalTask instanceof TaskInjector) {
- return;
+ originalTask = ((TaskInjector) originalTask).getOriginalTask();
}
final TaskInjector taskInjector = new TaskInjector(originalTask, plugin);
Reflect.on(pendingTask).set("task", taskInjector);
@@ -80,6 +81,7 @@ public class TaskInjector implements Runnable {
}
totalTime += lag;
count++;
+ MonitorManager.addTask(plugin.getName(), lag);
} catch (Throwable e) {
while (e.getCause() != null) {
e = e.getCause();
diff --git a/src/main/java/pw/yumc/Yum/listeners/PluginListener.java b/src/main/java/pw/yumc/Yum/listeners/PluginListener.java
index 11eabb8..1da56f7 100644
--- a/src/main/java/pw/yumc/Yum/listeners/PluginListener.java
+++ b/src/main/java/pw/yumc/Yum/listeners/PluginListener.java
@@ -9,6 +9,7 @@ import org.bukkit.event.server.PluginEnableEvent;
import cn.citycraft.PluginHelper.kit.PKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.api.YumAPI;
+import pw.yumc.Yum.managers.MonitorManager;
/**
*
@@ -29,6 +30,7 @@ public class PluginListener implements Listener {
@EventHandler
public void onPluginEnable(final PluginEnableEvent e) {
+ MonitorManager.reset(e.getPlugin().getName());
PluginKit.runTaskLater(new Runnable() {
@Override
public void run() {
diff --git a/src/main/java/pw/yumc/Yum/managers/MonitorManager.java b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java
new file mode 100644
index 0000000..b7c46b0
--- /dev/null
+++ b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java
@@ -0,0 +1,98 @@
+package pw.yumc.Yum.managers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ *
+ * @since 2016年7月19日 下午3:55:54
+ * @author 喵♂呜
+ */
+public class MonitorManager {
+ private static Map monitor = new HashMap<>();
+ private static Map task = new HashMap<>();
+ private static Map event = new HashMap<>();
+ private static Map cmd = new HashMap<>();
+
+ private final static double um = 1000000.00;
+
+ public static void addCmd(final String pname, final long time) {
+ monitor.put(pname, monitor.get(pname) + time);
+ cmd.put(pname, cmd.get(pname) + time);
+ }
+
+ public static void addEvent(final String pname, final long time) {
+ monitor.put(pname, monitor.get(pname) + time);
+ event.put(pname, event.get(pname) + time);
+ }
+
+ public static void addTask(final String pname, final long time) {
+ monitor.put(pname, monitor.get(pname) + time);
+ task.put(pname, task.get(pname) + time);
+ }
+
+ public static Map getMonitor() {
+ return sortMapByValue(monitor);
+ }
+
+ public static MonitorInfo getMonitorInfo(final String pname) {
+ return new MonitorInfo(monitor.get(pname) / um, cmd.get(pname) / um, event.get(pname) / um, task.get(pname) / um);
+ }
+
+ public static void reset(final String pname) {
+ monitor.put(pname, 0L);
+ task.put(pname, 0L);
+ event.put(pname, 0L);
+ cmd.put(pname, 0L);
+ }
+
+ /**
+ * 使用 Map按value进行排序
+ *
+ * @param map
+ * @return
+ */
+ public static Map sortMapByValue(final Map oriMap) {
+ if (oriMap == null || oriMap.isEmpty()) {
+ return null;
+ }
+ final Map sortedMap = new LinkedHashMap();
+ final List> entryList = new ArrayList>(oriMap.entrySet());
+ Collections.sort(entryList, new MonitorComparator());
+ final Iterator> iter = entryList.iterator();
+ Entry tmpEntry = null;
+ while (iter.hasNext()) {
+ tmpEntry = iter.next();
+ sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
+ }
+ return sortedMap;
+ }
+
+ public static class MonitorInfo {
+ public double monitor;
+ public double cmd;
+ public double event;
+ public double task;
+
+ public MonitorInfo(final double monitor, final double cmd, final double event, final double task) {
+ this.monitor = monitor;
+ this.cmd = cmd;
+ this.event = event;
+ this.task = task;
+ }
+ }
+
+ static class MonitorComparator implements Comparator> {
+ @Override
+ public int compare(final Entry o1, final Entry o2) {
+ return o2.getValue().compareTo(o1.getValue());
+ }
+ }
+}