From 844ae43eef0bd0b9f74173c653e4a16774748b61 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Tue, 26 Jul 2016 20:17:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E6=96=B0=E7=89=88?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E7=B1=BB=E5=BA=93=20=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- pom.xml | 16 +- src/main/java/pw/yumc/Yum/Yum.java | 2 + .../pw/yumc/Yum/commands/FileCommand.java | 114 ++++--- .../pw/yumc/Yum/commands/MonitorCommand.java | 71 ++-- .../java/pw/yumc/Yum/commands/NetCommand.java | 31 +- .../yumc/Yum/commands/PluginTabComplete.java | 12 +- .../java/pw/yumc/Yum/commands/YumCommand.java | 314 +++++++++--------- .../pw/yumc/Yum/inject/CommandInjector.java | 15 +- .../pw/yumc/Yum/inject/ListenerInjector.java | 19 +- .../java/pw/yumc/Yum/inject/TaskInjector.java | 9 +- .../pw/yumc/Yum/managers/MonitorManager.java | 89 +++-- src/main/resources/config.yml | 8 +- 12 files changed, 397 insertions(+), 303 deletions(-) diff --git a/pom.xml b/pom.xml index 228535c..11a761e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 pw.yumc Yum - 2.6.8 + 2.7.0 Yum Minecraft 服务器插件管理系统 @@ -33,6 +33,7 @@ cn.citycraft:PluginHelper + pw.yumc:YumCore @@ -41,7 +42,7 @@ ${project.groupId}.${project.artifactId} - pw.yumc.PluginHelper + pw.yumc.YumCore ${project.groupId}.${project.artifactId} @@ -65,9 +66,8 @@ &a全新 2.X 版本 更多守护与优化 &c注意 &6- &aYum更新需要&d重启服务器!&c重启服务器!&4重启服务器!; - &b2.6.8 &6- &c修复PerWorldPlugins的监控错误...; - &b2.6.7 &6- &d兼容PerWorldPlugins...; - &b2.6.6 &6- &c修复快捷点击按钮触发命令错误...; + &b2.7.0 &6- &a完善能耗监控流程...; + &b &6- &a报错能耗添加日志记录; DEBUG UTF-8 @@ -102,6 +102,12 @@ jar 1.0 + + pw.yumc + YumCore + jar + 1.0 + pw.yumc BukkitInjectedTools diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java index ff1c3ee..684d366 100644 --- a/src/main/java/pw/yumc/Yum/Yum.java +++ b/src/main/java/pw/yumc/Yum/Yum.java @@ -23,6 +23,7 @@ import pw.yumc.Yum.listeners.PluginNetworkListener; import pw.yumc.Yum.listeners.SecurityListener; import pw.yumc.Yum.listeners.ThreadSafetyListener; import pw.yumc.Yum.managers.ConfigManager; +import pw.yumc.Yum.managers.MonitorManager; import pw.yumc.Yum.managers.NetworkManager; import pw.yumc.Yum.runnables.MainThreadCheckTask; @@ -59,6 +60,7 @@ public class Yum extends JavaPlugin { new VersionChecker(this); YumAPI.updateRepo(Bukkit.getConsoleSender()); YumAPI.updateCheck(Bukkit.getConsoleSender()); + MonitorManager.init(); } @Override diff --git a/src/main/java/pw/yumc/Yum/commands/FileCommand.java b/src/main/java/pw/yumc/Yum/commands/FileCommand.java index f007f0f..d01c8f9 100644 --- a/src/main/java/pw/yumc/Yum/commands/FileCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/FileCommand.java @@ -7,15 +7,16 @@ import java.io.InputStreamReader; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import cn.citycraft.PluginHelper.commands.HandlerCommand; -import cn.citycraft.PluginHelper.commands.HandlerCommands; -import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; -import cn.citycraft.PluginHelper.commands.InvokeSubCommand; -import cn.citycraft.PluginHelper.kit.PluginKit; import cn.citycraft.PluginHelper.kit.StrKit; import cn.citycraft.PluginHelper.utils.FileUtil; import pw.yumc.Yum.Yum; import pw.yumc.Yum.api.YumAPI; +import pw.yumc.YumCore.commands.CommandArgument; +import pw.yumc.YumCore.commands.CommandExecutor; +import pw.yumc.YumCore.commands.CommandManager; +import pw.yumc.YumCore.commands.annotation.Async; +import pw.yumc.YumCore.commands.annotation.Cmd; +import pw.yumc.YumCore.commands.annotation.Help; /** * File命令基类 @@ -23,7 +24,7 @@ import pw.yumc.Yum.api.YumAPI; * @since 2016年1月9日 上午10:02:39 * @author 喵♂呜 */ -public class FileCommand implements HandlerCommands { +public class FileCommand implements CommandExecutor { private static String prefix = "§6[§bYum §a文件管理§6] "; private static String file_not_found = prefix + "§b%s §c文件未找到!"; @@ -34,6 +35,7 @@ public class FileCommand implements HandlerCommands { private static String waitCommand = prefix + "§a命令已发送,请等待执行完毕..."; private static String runResult = prefix + "§a命令运行结果如下:"; + private static String noResult = prefix + "§d当前命令没有返回结果!"; private static String runError = prefix + "§c命令运行错误: %s %s"; private static String addStartupSuccess = "§a成功添加开机自动启..."; @@ -44,13 +46,13 @@ public class FileCommand implements HandlerCommands { public FileCommand(final Yum yum) { plugin = yum; - final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file"); - cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true)); - cmdhandler.registerCommands(this); + new CommandManager("file", this, PluginTabComplete.instence); } - @HandlerCommand(name = "copy", aliases = "cp", minimumArguments = 2, description = "复制文件", possibleArguments = "<源文件> <目标目录>") - public void copy(final InvokeCommandEvent e) { + @Cmd(aliases = "cp", minimumArguments = 2) + @Help(value = "复制文件", possibleArguments = "<源文件> <目标目录>") + @Async + public void copy(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); final File src = new File(args[0]); @@ -70,29 +72,34 @@ public class FileCommand implements HandlerCommands { } } - @HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除文件(服务器JAR为根目录)", possibleArguments = "<文件相对目录>") - public void delete(final InvokeCommandEvent e) { + @Cmd(aliases = "del", minimumArguments = 1) + @Help(value = "删除文件(服务器JAR为根目录)", possibleArguments = "<文件相对目录>") + @Async + public void delete(final CommandArgument e) { final String[] args = e.getArgs(); - final String fpath = args[0]; + String fpath = args[0]; final File file = new File(fpath); final CommandSender sender = e.getSender(); + fpath = file.getAbsolutePath(); if (!file.exists()) { - sender.sendMessage("§c文件 " + file.getAbsolutePath() + " 不存在!"); + sender.sendMessage(String.format(file_not_found, fpath)); } else { if (file.isDirectory()) { - sender.sendMessage("§e" + file.getAbsolutePath() + " §c是一个目录 请使用file rm!"); + sender.sendMessage(String.format(file_is_dir, fpath)); return; } try { - sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!")); + sender.sendMessage("§d文件 §e" + fpath + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!")); } catch (final Exception ex) { - sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " 删除失败: " + ex.getMessage()); + sender.sendMessage("§d文件 §e" + fpath + " 删除失败: " + ex.getMessage()); } } } - @HandlerCommand(name = "download", aliases = { "d" }, minimumArguments = 1, description = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]") - public void download(final InvokeCommandEvent e) { + @Cmd(aliases = "d", minimumArguments = 1) + @Help(value = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]") + @Async + public void download(final CommandArgument e) { final String[] args = e.getArgs(); String urlstr = args[0]; if (!urlstr.startsWith("http")) { @@ -107,8 +114,10 @@ public class FileCommand implements HandlerCommands { YumAPI.getDownload().run(e.getSender(), urlstr, file); } - @HandlerCommand(name = "ls", aliases = { "l" }, description = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>") - public void ls(final InvokeCommandEvent e) { + @Cmd(aliases = "ls") + @Help(value = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>") + @Async + public void ls(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); File dir = new File("."); @@ -137,8 +146,10 @@ public class FileCommand implements HandlerCommands { } } - @HandlerCommand(name = "rename", aliases = { "rn" }, minimumArguments = 2, description = "重命名文件(服务器JAR为根目录)", possibleArguments = "<文件相对路径> <文件名称>") - public void rename(final InvokeCommandEvent e) { + @Cmd(aliases = "rn", minimumArguments = 2) + @Help(value = "重命名文件(服务器JAR为根目录)", possibleArguments = "<文件相对路径> <文件名称>") + @Async + public void rename(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); final String fpath = args[0]; @@ -156,8 +167,10 @@ public class FileCommand implements HandlerCommands { } } - @HandlerCommand(name = "rm", minimumArguments = 1, description = "删除文件夹(服务器JAR为根目录)", possibleArguments = "<相对目录>") - public void rm(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "删除文件夹(服务器JAR为根目录)", possibleArguments = "<相对目录>") + @Async + public void rm(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); final String fpath = args[0]; @@ -184,34 +197,37 @@ public class FileCommand implements HandlerCommands { } } - @HandlerCommand(name = "run", aliases = "r", minimumArguments = 1, description = "运行一个命令或文件", possibleArguments = "<命令或文件绝对路径>") - public void run(final InvokeCommandEvent e) { + @Cmd(aliases = "r", minimumArguments = 1) + @Help(value = "运行一个命令或文件", possibleArguments = "<命令或文件绝对路径>") + @Async + public void run(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); - PluginKit.runTaskAsync(new Runnable() { - @Override - public void run() { - try { - final Process process = Runtime.getRuntime().exec(StrKit.join(args, " ")); - sender.sendMessage(waitCommand); - final BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line = null; - final StringBuilder build = new StringBuilder(); - while ((line = br.readLine()) != null) { - build.append(line); - build.append("\n"); - } - sender.sendMessage(runResult); - sender.sendMessage(build.toString().split("\n")); - } catch (final Exception e2) { - sender.sendMessage(String.format(runError, e2.getClass().getSimpleName(), e2.getMessage())); - } + try { + final Process process = Runtime.getRuntime().exec(StrKit.join(args, " ")); + sender.sendMessage(waitCommand); + final BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = null; + final StringBuilder build = new StringBuilder(); + while ((line = br.readLine()) != null) { + build.append(line); + build.append("\n"); } - }); + if (build.toString().replace("\n", "").isEmpty()) { + sender.sendMessage(noResult); + } else { + sender.sendMessage(runResult); + sender.sendMessage(build.toString().split("\n")); + } + } catch (final Exception e2) { + sender.sendMessage(String.format(runError, e2.getClass().getSimpleName(), e2.getMessage())); + } } - @HandlerCommand(name = "startup", minimumArguments = 1, description = "添加开机自动启", possibleArguments = "<命令或文件绝对路径>") - public void startup(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "添加开机自启动", possibleArguments = "<文件绝对路径>") + @Async + public void startup(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); final File src = new File(args[0]); diff --git a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java index bc93a9b..d0f506b 100644 --- a/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/MonitorCommand.java @@ -8,7 +8,6 @@ import java.util.Map.Entry; import org.bukkit.Bukkit; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.command.SimpleCommandMap; @@ -20,10 +19,6 @@ import org.bukkit.plugin.RegisteredListener; import org.bukkit.plugin.TimedRegisteredListener; import org.bukkit.scheduler.BukkitTask; -import cn.citycraft.PluginHelper.commands.HandlerCommand; -import cn.citycraft.PluginHelper.commands.HandlerCommands; -import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; -import cn.citycraft.PluginHelper.commands.InvokeSubCommand; import cn.citycraft.PluginHelper.ext.kit.Reflect; import cn.citycraft.PluginHelper.kit.PluginKit; import cn.citycraft.PluginHelper.kit.StrKit; @@ -34,13 +29,19 @@ import pw.yumc.Yum.inject.ListenerInjector; import pw.yumc.Yum.inject.TaskInjector; import pw.yumc.Yum.managers.MonitorManager; import pw.yumc.Yum.managers.MonitorManager.MonitorInfo; +import pw.yumc.YumCore.commands.CommandArgument; +import pw.yumc.YumCore.commands.CommandExecutor; +import pw.yumc.YumCore.commands.CommandManager; +import pw.yumc.YumCore.commands.annotation.Async; +import pw.yumc.YumCore.commands.annotation.Cmd; +import pw.yumc.YumCore.commands.annotation.Help; /** * * @since 2016年7月6日 下午5:13:32 * @author 喵♂呜 */ -public class MonitorCommand implements HandlerCommands { +public class MonitorCommand implements CommandExecutor { public static Throwable lastError = null; private final String prefix = "§6[§bYum §a能耗监控§6] "; @@ -66,13 +67,13 @@ public class MonitorCommand implements HandlerCommands { private final double um = 1000000.00; public MonitorCommand(final Yum yum) { - final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor"); - cmdhandler.registerCommands(this); - cmdhandler.registerCommands(PluginTabComplete.instence); + new CommandManager("monitor", this, PluginTabComplete.instence); } - @HandlerCommand(name = "cmd", aliases = "c", description = "查看插件命令能耗", minimumArguments = 1, possibleArguments = "[插件名称]") - public void cmd(final InvokeCommandEvent e) { + @Cmd(aliases = "c", minimumArguments = 1) + @Help(value = "查看插件命令能耗", possibleArguments = "[插件名称]") + @Async + public void cmd(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); if (Bukkit.getPluginManager().getPlugin(pname) == null) { @@ -93,7 +94,7 @@ public class MonitorCommand implements HandlerCommands { } } for (final Entry command : temp.entrySet()) { - final CommandExecutor executor = Reflect.on(command.getValue()).get("executor"); + final org.bukkit.command.CommandExecutor executor = Reflect.on(command.getValue()).get("executor"); if (executor instanceof CommandInjector) { final CommandInjector injected = (CommandInjector) executor; final StringBuffer str = new StringBuffer(); @@ -108,8 +109,10 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "event", aliases = "e", description = "查看插件事件能耗", minimumArguments = 1, possibleArguments = "[插件名称]") - public void event(final InvokeCommandEvent e) throws InstantiationException, IllegalAccessException, NoSuchFieldException { + @Cmd(aliases = "e", minimumArguments = 1) + @Help(value = "查看插件事件能耗", possibleArguments = "[插件名称]") + @Async + public void event(final CommandArgument e) throws InstantiationException, IllegalAccessException, NoSuchFieldException { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname); @@ -130,7 +133,7 @@ public class MonitorCommand implements HandlerCommands { } EventExecutor executor = Reflect.on(listener).get("executor"); if (listener.getClass().getName().contains("PWPRegisteredListener")) { - final Field f = Reflect.on(listener).getDeclaredField(RegisteredListener.class, "executor"); + final Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor"); f.setAccessible(true); executor = (EventExecutor) f.get(listener); } @@ -160,8 +163,9 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "inject", aliases = "i", description = "注入能耗监控器", minimumArguments = 1, possibleArguments = "[插件名称]") - public void inject(final InvokeCommandEvent e) { + @Cmd(aliases = "i", minimumArguments = 1) + @Help(value = "注入能耗监控器", possibleArguments = "[插件名称]") + public void inject(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname); @@ -177,8 +181,10 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "lag", aliases = "l", description = "查看插件总耗时") - public void lag(final InvokeCommandEvent e) { + @Cmd(aliases = "l") + @Help("查看插件总耗时") + @Async + public void lag(final CommandArgument e) { final CommandSender sender = e.getSender(); final Map mm = MonitorManager.getMonitor(); int i = 0; @@ -193,8 +199,10 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "lasterror", aliases = "la", description = "查看最后一次报错") - public void lasterror(final InvokeCommandEvent e) { + @Cmd(aliases = "la") + @Help("查看最后一次报错") + @Async + public void lasterror(final CommandArgument e) { final CommandSender sender = e.getSender(); if (lastError == null) { sender.sendMessage(no_error); @@ -207,15 +215,23 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "reinject", aliases = "i", description = "重载能耗监控器") - public void reinject(final InvokeCommandEvent e) { + @Cmd + public void lk(final CommandArgument e) { + MonitorManager.sendObject(e.getSender()); + } + + @Cmd(aliases = "ri") + @Help("重载能耗监控器") + public void reinject(final CommandArgument e) { final CommandSender sender = e.getSender(); YumAPI.updateInject(); sender.sendMessage(reinject); } - @HandlerCommand(name = "task", description = "查看插件任务能耗", minimumArguments = 1, possibleArguments = "[插件名称]") - public void task(final InvokeCommandEvent e) { + @Cmd(aliases = "t", minimumArguments = 1) + @Help(value = "查看插件任务能耗", possibleArguments = "[插件名称]") + @Async + public void task(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname); @@ -243,8 +259,9 @@ public class MonitorCommand implements HandlerCommands { } } - @HandlerCommand(name = "uninject", aliases = "ui", description = "撤销能耗监控器", minimumArguments = 1, possibleArguments = "[插件名称]") - public void uninject(final InvokeCommandEvent e) { + @Cmd(aliases = "ui", minimumArguments = 1) + @Help(value = "撤销能耗监控器", possibleArguments = "[插件名称]") + public void uninject(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname); diff --git a/src/main/java/pw/yumc/Yum/commands/NetCommand.java b/src/main/java/pw/yumc/Yum/commands/NetCommand.java index cfb919b..b1110e2 100644 --- a/src/main/java/pw/yumc/Yum/commands/NetCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/NetCommand.java @@ -7,13 +7,16 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import cn.citycraft.PluginHelper.commands.HandlerCommand; -import cn.citycraft.PluginHelper.commands.HandlerCommands; -import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; -import cn.citycraft.PluginHelper.commands.InvokeSubCommand; import pw.yumc.Yum.Yum; import pw.yumc.Yum.managers.ConfigManager; +import pw.yumc.YumCore.commands.CommandArgument; +import pw.yumc.YumCore.commands.CommandExecutor; +import pw.yumc.YumCore.commands.CommandManager; +import pw.yumc.YumCore.commands.annotation.Async; +import pw.yumc.YumCore.commands.annotation.Cmd; +import pw.yumc.YumCore.commands.annotation.Help; -public class NetCommand implements HandlerCommands { +public class NetCommand implements CommandExecutor { public static HashMap netlist = new HashMap<>(); private final String prefix = "§6[§bYum §a网络管理§6] "; @@ -27,9 +30,7 @@ public class NetCommand implements HandlerCommands { private final String p_n_f = prefix + "§c插件 §b%s §c不存在!"; public NetCommand(final Yum yum) { - final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net"); - cmdhandler.registerCommands(this); - cmdhandler.registerCommands(PluginTabComplete.instence); + new CommandManager("net", this, PluginTabComplete.instence); } public static void addNetCount(final String pname) { @@ -40,8 +41,10 @@ public class NetCommand implements HandlerCommands { } } - @HandlerCommand(name = "list", aliases = "l", permission = "", description = "列出联网的插件") - public void list(final InvokeCommandEvent e) { + @Cmd(aliases = "l") + @Help("列出联网的插件详情") + @Async + public void list(final CommandArgument e) { final CommandSender sender = e.getSender(); if (netlist.isEmpty()) { sender.sendMessage(no_net); @@ -54,8 +57,9 @@ public class NetCommand implements HandlerCommands { } } - @HandlerCommand(name = "off", minimumArguments = 1, description = "禁止插件联网", possibleArguments = "[插件名称]") - public void off(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "禁止插件联网", possibleArguments = "[插件名称]") + public void off(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); if (Bukkit.getPluginManager().getPlugin(pname) == null) { @@ -66,8 +70,9 @@ public class NetCommand implements HandlerCommands { sender.sendMessage(String.format(add, pname, "§c黑名单")); } - @HandlerCommand(name = "on", minimumArguments = 1, description = "允许插件联网", possibleArguments = "[插件名称]") - public void on(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "允许插件联网", possibleArguments = "[插件名称]") + public void on(final CommandArgument e) { final String pname = e.getArgs()[0]; final CommandSender sender = e.getSender(); if (Bukkit.getPluginManager().getPlugin(pname) == null) { diff --git a/src/main/java/pw/yumc/Yum/commands/PluginTabComplete.java b/src/main/java/pw/yumc/Yum/commands/PluginTabComplete.java index 021aa61..5279a16 100644 --- a/src/main/java/pw/yumc/Yum/commands/PluginTabComplete.java +++ b/src/main/java/pw/yumc/Yum/commands/PluginTabComplete.java @@ -4,22 +4,22 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import cn.citycraft.PluginHelper.commands.HandlerCommands; -import cn.citycraft.PluginHelper.commands.HandlerTabComplete; -import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; import cn.citycraft.PluginHelper.utils.StrKit; import pw.yumc.Yum.api.YumAPI; +import pw.yumc.YumCore.commands.CommandArgument; +import pw.yumc.YumCore.commands.CommandExecutor; +import pw.yumc.YumCore.commands.annotation.Tab; /** * * @since 2016年7月7日 上午8:36:47 * @author 喵♂呜 */ -public class PluginTabComplete implements HandlerCommands { +public class PluginTabComplete implements CommandExecutor { public static PluginTabComplete instence = new PluginTabComplete(); - @HandlerTabComplete() - public List listtab(final InvokeCommandEvent e) { + @Tab + public List listtab(final CommandArgument e) { final String[] args = e.getArgs(); if (args[0].equalsIgnoreCase("install") || args[0].equalsIgnoreCase("i")) { return StrKit.copyPartialMatches(args[1], YumAPI.getRepo().getAllPluginName(), new ArrayList()); diff --git a/src/main/java/pw/yumc/Yum/commands/YumCommand.java b/src/main/java/pw/yumc/Yum/commands/YumCommand.java index 8ea2898..ef27487 100644 --- a/src/main/java/pw/yumc/Yum/commands/YumCommand.java +++ b/src/main/java/pw/yumc/Yum/commands/YumCommand.java @@ -19,10 +19,6 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import cn.citycraft.PluginHelper.callback.CallBack.One; -import cn.citycraft.PluginHelper.commands.HandlerCommand; -import cn.citycraft.PluginHelper.commands.HandlerCommands; -import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; -import cn.citycraft.PluginHelper.commands.InvokeSubCommand; import cn.citycraft.PluginHelper.kit.PluginKit; import cn.citycraft.PluginHelper.kit.ZipKit; import cn.citycraft.PluginHelper.tellraw.FancyMessage; @@ -35,6 +31,13 @@ import pw.yumc.Yum.models.BukkitDev; import pw.yumc.Yum.models.BukkitDev.Files; import pw.yumc.Yum.models.BukkitDev.Projects; import pw.yumc.Yum.models.RepoSerialization.Repositories; +import pw.yumc.YumCore.commands.CommandArgument; +import pw.yumc.YumCore.commands.CommandExecutor; +import pw.yumc.YumCore.commands.CommandManager; +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.Sort; /** * Yum命令基类 @@ -42,18 +45,18 @@ import pw.yumc.Yum.models.RepoSerialization.Repositories; * @since 2016年1月9日 上午10:02:24 * @author 喵♂呜 */ -public class YumCommand implements HandlerCommands, Listener { +public class YumCommand implements Listener, CommandExecutor { private final String prefix = "§6[§bYum §a插件管理§6] "; private final String searchlimit = prefix + "§c为保证搜索速度和准确性 关键词必须大于 3 个字符!"; - private final String searching = prefix + "§a正在从 §eBukkitDev 获取 §b%s §a的相关数据..."; - private final String not_found_from_bukkit = prefix + "§c未在 §eBukkitDev 搜索到 %s 的相关插件!"; + private final String searching = prefix + "§a正在从 §eBukkitDev §a获取 §b%s §a的相关数据..."; + private final String not_found_from_bukkit = prefix + "§c未在 §eBukkitDev §c搜索到 §b%s §c的相关插件!"; private final String result = prefix + "§6关键词 §b%s §6的搜索结果如下:"; private final String bukkitlistprefix = " §6插件ID §3插件名称 §d发布类型 §a操作"; private final String bukkitlist = "§6- §e%-6s §b%-25s §d%-10s"; - private final String fsearching = prefix + "§a正在从 §eBukkitDev 获取ID §b%s §a的文件列表..."; - private final String not_found_id_from_bukkit = prefix + "§c未在 §eBukkitDev 搜索到ID为 %s 的相关插件!"; + private final String fsearching = prefix + "§a正在从 §eBukkitDev §a获取ID §b%s §a的文件列表..."; + private final String not_found_id_from_bukkit = prefix + "§c未在 §eBukkitDev §c搜索到ID为 §b%s §c的相关插件!"; private final String filelistprefix = " §6插件名称 §3游戏版本 §d发布类型 §a操作"; private final String filelist = "§6- §b%-20s §3%-15s §d%-10s"; @@ -74,14 +77,12 @@ public class YumCommand implements HandlerCommands, Listener { public YumCommand(final Yum yum) { main = yum; Bukkit.getPluginManager().registerEvents(this, yum); - final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum"); - cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false)); - cmdhandler.registerCommands(this); - cmdhandler.registerCommands(PluginTabComplete.instence); + new CommandManager("yum", this, PluginTabComplete.instence); } - @HandlerCommand(name = "bukkitrepo", aliases = "br", minimumArguments = 2, description = "从BukkitDev查看安装插件", possibleArguments = "<操作符> <项目ID|项目名称> [地址]") - public void bukkitrepo(final InvokeCommandEvent e) { + @Cmd(aliases = "br", minimumArguments = 2) + @Help(value = "从BukkitDev查看安装插件", possibleArguments = "<操作符> <项目ID|项目名称> [地址]") + public void bukkitrepo(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); PluginKit.runTaskAsync(new Runnable() { @@ -154,13 +155,16 @@ public class YumCommand implements HandlerCommands, Listener { } default: break; + } } }); } - @HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除插件", possibleArguments = "<插件名称>", sort = 6) - public void delete(final InvokeCommandEvent e) { + @Cmd(aliases = "del", minimumArguments = 1) + @Help(value = "删除插件", possibleArguments = "<插件名称>") + @Sort(6) + public void delete(final CommandArgument e) { final String pluginname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); @@ -176,8 +180,10 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "find", aliases = { "f" }, minimumArguments = 1, possibleArguments = "<插件类名>", description = "通过类名查找插件", sort = 10) - public void find(final InvokeCommandEvent e) { + @Cmd(aliases = "f", minimumArguments = 1) + @Help(value = "通过类名查找插件", possibleArguments = "<插件类名>") + @Sort(10) + public void find(final CommandArgument e) { final String classname = e.getArgs()[0]; final CommandSender sender = e.getSender(); try { @@ -191,8 +197,10 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "fulldelete", aliases = { "fdel" }, minimumArguments = 1, description = "删除插件以及数据文件夹", possibleArguments = "<插件名称>", sort = 7) - public void fulldelete(final InvokeCommandEvent e) { + @Cmd(aliases = "fdel", minimumArguments = 1) + @Help(value = "删除插件以及数据文件夹", possibleArguments = "<插件名称>") + @Sort(7) + public void fulldelete(final CommandArgument e) { final String pluginname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); @@ -208,8 +216,11 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "info", minimumArguments = 1, description = "查看插件详情", possibleArguments = "<插件名称>", sort = 2) - public void info(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "查看插件详情", possibleArguments = "<插件名称>") + @Sort(2) + @Async + public void info(final CommandArgument e) { final String pluginname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); @@ -247,8 +258,10 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "install", aliases = { "i" }, minimumArguments = 1, description = "安装插件", possibleArguments = "<插件名称>", sort = 12) - public void install(final InvokeCommandEvent e) { + @Cmd(aliases = "i", minimumArguments = 1) + @Help(value = "安装插件", possibleArguments = "<插件名称>") + @Sort(12) + public void install(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); final String pluginname = args[0]; @@ -269,8 +282,11 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "list", aliases = { "l" }, description = "列出已安装插件列表", sort = 1) - public void list(final InvokeCommandEvent e) { + @Cmd(aliases = "l") + @Help(value = "列出已安装插件列表") + @Sort(1) + @Async + public void list(final CommandArgument e) { final CommandSender sender = e.getSender(); sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: "); for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { @@ -289,8 +305,10 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "load", minimumArguments = 1, description = "载入插件", possibleArguments = "<插件名称>", sort = 3) - public void load(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "载入插件", possibleArguments = "<插件名称>") + @Sort(3) + public void load(final CommandArgument e) { final CommandSender sender = e.getSender(); final String pluginname = e.getArgs()[0]; final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); @@ -308,8 +326,10 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "reload", aliases = { "re" }, description = "重载插件", possibleArguments = "<插件名称|all|*>", sort = 5) - public void reload(final InvokeCommandEvent e) { + @Cmd(aliases = "re") + @Help(value = "重载插件", possibleArguments = "<插件名称|all|*>") + @Sort(5) + public void reload(final CommandArgument e) { final CommandSender sender = e.getSender(); if (e.getArgs().length == 0) { ConfigManager.i().reload(); @@ -329,97 +349,95 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "repo", aliases = { "r" }, minimumArguments = 1, description = "插件源命令", possibleArguments = " <仓库名称>", sort = 16) - public void repo(final InvokeCommandEvent e) { + @Cmd(aliases = "r", minimumArguments = 1) + @Help(value = "插件源命令", possibleArguments = " <仓库名称>") + @Sort(16) + @Async + public void repo(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); - main.getServer().getScheduler().runTaskAsynchronously(main, new Runnable() { - @Override - public void run() { - final String cmd = args[0]; - switch (cmd) { - case "add": - if (args.length == 2) { - if (YumAPI.getRepo().addRepositories(sender, args[1])) { - final String reponame = YumAPI.getRepo().getRepoCache(args[1]).name; - sender.sendMessage("§6仓库: §a源仓库 §e" + reponame + " §a的插件信息已缓存!"); - } else { - sender.sendMessage("§6仓库: §c源地址未找到仓库信息或当前地址已缓存!"); - } - } else { - sender.sendMessage("§6仓库: §c请输入需要添加的源地址!"); - } - break; - case "del": - if (args.length == 2) { - final Repositories delrepo = YumAPI.getRepo().getRepoCache(args[1]); - if (delrepo != null) { - YumAPI.getRepo().delRepositories(sender, args[1]); - sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!"); - } else { - sender.sendMessage("§6仓库: §c源地址未找到!"); - } - } else { - sender.sendMessage("§6仓库: §c请输入需要删除的源地址!"); - } - break; - case "delall": - YumAPI.getRepo().getRepoCache().getRepos().clear(); - sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!"); - break; - case "list": - sender.sendMessage("§6仓库: §b缓存的插件信息如下 "); - StrKit.sendStringArray(sender, YumAPI.getRepo().getAllPluginsInfo()); - break; - case "all": - sender.sendMessage("§6仓库: §b缓存的仓库信息如下 "); - StrKit.sendStringArray(sender, YumAPI.getRepo().getRepoCache().getAllRepoInfo()); - break; - case "clean": - YumAPI.getRepo().clean(); - sender.sendMessage("§6仓库: §a缓存的插件信息已清理!"); - break; - case "update": - YumAPI.getRepo().updateRepositories(sender); - sender.sendMessage("§6仓库: §a仓库缓存数据已更新!"); - break; + final String cmd = args[0]; + switch (cmd) { + case "add": + if (args.length == 2) { + if (YumAPI.getRepo().addRepositories(sender, args[1])) { + final String reponame = YumAPI.getRepo().getRepoCache(args[1]).name; + sender.sendMessage("§6仓库: §a源仓库 §e" + reponame + " §a的插件信息已缓存!"); + } else { + sender.sendMessage("§6仓库: §c源地址未找到仓库信息或当前地址已缓存!"); } + } else { + sender.sendMessage("§6仓库: §c请输入需要添加的源地址!"); } - }); + break; + case "del": + if (args.length == 2) { + final Repositories delrepo = YumAPI.getRepo().getRepoCache(args[1]); + if (delrepo != null) { + YumAPI.getRepo().delRepositories(sender, args[1]); + sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!"); + } else { + sender.sendMessage("§6仓库: §c源地址未找到!"); + } + } else { + sender.sendMessage("§6仓库: §c请输入需要删除的源地址!"); + } + break; + case "delall": + YumAPI.getRepo().getRepoCache().getRepos().clear(); + sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!"); + break; + case "list": + sender.sendMessage("§6仓库: §b缓存的插件信息如下 "); + StrKit.sendStringArray(sender, YumAPI.getRepo().getAllPluginsInfo()); + break; + case "all": + sender.sendMessage("§6仓库: §b缓存的仓库信息如下 "); + StrKit.sendStringArray(sender, YumAPI.getRepo().getRepoCache().getAllRepoInfo()); + break; + case "clean": + YumAPI.getRepo().clean(); + sender.sendMessage("§6仓库: §a缓存的插件信息已清理!"); + break; + case "update": + YumAPI.getRepo().updateRepositories(sender); + sender.sendMessage("§6仓库: §a仓库缓存数据已更新!"); + break; + } } - @HandlerCommand(name = "search", aliases = "s", minimumArguments = 1, description = "从BukkitDev搜索插件", possibleArguments = "插件名称", sort = 11) - public void search(final InvokeCommandEvent e) { - PluginKit.runTaskAsync(new Runnable() { - @Override - public void run() { - final String pname = e.getArgs()[0]; - final CommandSender sender = e.getSender(); - if (pname.length() < 3) { - sender.sendMessage(searchlimit); - return; - } - sender.sendMessage(String.format(searching, pname)); - final List list = Projects.parseList(IOUtil.getData(String.format(BukkitDev.SEARCH, pname.toLowerCase()))); - if (list.isEmpty()) { - sender.sendMessage(String.format(not_found_from_bukkit, pname)); - return; - } - sender.sendMessage(String.format(result, pname)); - sender.sendMessage(bukkitlistprefix); - for (final Projects p : list) { - final FancyMessage fm = FancyMessage.newFM(); - fm.text(String.format(bukkitlist, p.id, p.name, p.stage)); - fm.then(" "); - fm.then(look).command("/yum br look " + p.id); - fm.send(sender); - } - } - }); + @Cmd(aliases = "s", minimumArguments = 1) + @Help(value = "从BukkitDev搜索插件", possibleArguments = "插件名称") + @Sort(11) + @Async + public void search(final CommandArgument e) { + final String pname = e.getArgs()[0]; + final CommandSender sender = e.getSender(); + if (pname.length() < 3) { + sender.sendMessage(searchlimit); + return; + } + sender.sendMessage(String.format(searching, pname)); + final List list = Projects.parseList(IOUtil.getData(String.format(BukkitDev.SEARCH, pname.toLowerCase()))); + if (list.isEmpty()) { + sender.sendMessage(String.format(not_found_from_bukkit, pname)); + return; + } + sender.sendMessage(String.format(result, pname)); + sender.sendMessage(bukkitlistprefix); + for (final Projects p : list) { + final FancyMessage fm = FancyMessage.newFM(); + fm.text(String.format(bukkitlist, p.id, p.name, p.stage)); + fm.then(" "); + fm.then(look).command("/yum br look " + p.id); + fm.send(sender); + } } - @HandlerCommand(name = "unload", minimumArguments = 1, description = "卸载插件", possibleArguments = "<插件名称>", sort = 4) - public void unload(final InvokeCommandEvent e) { + @Cmd(minimumArguments = 1) + @Help(value = "卸载插件", possibleArguments = "<插件名称>") + @Sort(4) + public void unload(final CommandArgument e) { final String pluginname = e.getArgs()[0]; final CommandSender sender = e.getSender(); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); @@ -430,8 +448,11 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "update", aliases = { "u" }, description = "更新插件或缓存", possibleArguments = "[插件名称] [插件版本]", sort = 13) - public void update(final InvokeCommandEvent e) { + @Cmd(aliases = "u") + @Help(value = "更新插件或缓存", possibleArguments = "[插件名称] [插件版本]") + @Sort(13) + @Async + public void update(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); switch (args.length) { @@ -445,16 +466,11 @@ public class YumCommand implements HandlerCommands, Listener { final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); sender.sendMessage("§a开始更新插件: " + pluginname); if (plugin != null) { - Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() { - @Override - public void run() { - if (args.length < 2) { - YumAPI.updateFromYum(sender, plugin); - } else { - YumAPI.updateFromYum(sender, plugin, args[1]); - } - } - }); + if (args.length < 2) { + YumAPI.updateFromYum(sender, plugin); + } else { + YumAPI.updateFromYum(sender, plugin, args[1]); + } } else { sender.sendMessage("§c插件" + pluginname + "未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!"); } @@ -464,37 +480,31 @@ public class YumCommand implements HandlerCommands, Listener { } } - @HandlerCommand(name = "updateall", aliases = { "ua" }, description = "更新所有可更新插件", sort = 14) - public void updateall(final InvokeCommandEvent e) { - Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() { - @Override - public void run() { - YumAPI.updateAll(e.getSender()); - } - }); + @Cmd(aliases = "ua") + @Help("更新所有可更新插件") + @Sort(14) + public void updateall(final CommandArgument e) { + YumAPI.updateAll(e.getSender()); } - @HandlerCommand(name = "upgrade", aliases = { "ug" }, description = "升级或载入插件", possibleArguments = "[插件名称]", sort = 15) - public void upgrade(final InvokeCommandEvent e) { + @Cmd(aliases = "ug") + @Help(value = "升级或安装插件", possibleArguments = "[插件名称]") + @Sort(15) + public void upgrade(final CommandArgument e) { final String[] args = e.getArgs(); final CommandSender sender = e.getSender(); - Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() { - @Override - public void run() { - if (args.length == 0) { - YumAPI.getPlugman().upgrade(sender); - } else { - final String pluginname = args[0]; - final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); - sender.sendMessage("§a开始升级插件: §b" + pluginname); - if (plugin != null) { - YumAPI.upgrade(sender, plugin); - } else { - sender.sendMessage("§c错误: §b插件 " + pluginname + " §c未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!"); - } - } + if (args.length == 0) { + YumAPI.getPlugman().upgrade(sender); + } else { + final String pluginname = args[0]; + final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); + sender.sendMessage("§a开始升级插件: §b" + pluginname); + if (plugin != null) { + YumAPI.upgrade(sender, plugin); + } else { + sender.sendMessage("§c错误: §b插件 " + pluginname + " §c未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!"); } - }); + } } private String pnf(final String pname) { diff --git a/src/main/java/pw/yumc/Yum/inject/CommandInjector.java b/src/main/java/pw/yumc/Yum/inject/CommandInjector.java index bb8bc42..aacc77d 100644 --- a/src/main/java/pw/yumc/Yum/inject/CommandInjector.java +++ b/src/main/java/pw/yumc/Yum/inject/CommandInjector.java @@ -23,6 +23,8 @@ import pw.yumc.Yum.managers.MonitorManager; public class CommandInjector implements TabExecutor { private final static String prefix = "§6[§bYum §a命令监控§6] "; + private final static String warn = "§c注意! §6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令 §c耗时 §4%sms!"; + private final static String err = prefix + "§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令时发生异常!"; private final static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!"; private final static String plugin_is_null = "插件不得为NULL!"; private final CommandExecutor originalExecutor; @@ -104,12 +106,11 @@ public class CommandInjector implements TabExecutor { public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) { try { final long start = System.nanoTime(); - // TODO 当操作大于10ms的时候添加一个Lag提示 final boolean result = originalExecutor.onCommand(sender, command, label, args); final long end = System.nanoTime(); final long lag = end - start; if (Bukkit.isPrimaryThread() && lag / 1000000 > MonitorManager.lagTime) { - MonitorManager.lagTip("§c注意! §6玩家 §a" + sender.getName() + " §6执行 §b" + plugin.getName() + " §6插件 §d" + label + " " + StrKit.join(args, " ") + " §6命令 §c耗时 §4" + lag / 1000000 + "ms!"); + MonitorManager.lagTip(String.format(warn, sender.getName(), plugin.getName(), label, StrKit.join(args, " "), lag / 1000000)); } totalTime += lag; count++; @@ -119,13 +120,9 @@ public class CommandInjector implements TabExecutor { while (e.getCause() != null) { e = e.getCause(); } - sender.sendMessage(prefix + "§c命令执行异常 请反馈下列信息给腐竹!"); - sender.sendMessage("§6插件名称: §b" + plugin.getName()); - sender.sendMessage("§6异常名称: §c" + e.getClass().getName()); - sender.sendMessage("§6异常说明: §3" + e.getMessage()); MonitorCommand.lastError = e; - MonitorManager.log(prefix + "§6玩家 §a" + sender.getName() + " §6执行 §b" + plugin.getName() + " §6插件 §d" + label + " " + StrKit.join(args, " ") + " §6命令时发生异常!"); - MonitorManager.printThrowable(e); + MonitorManager.sendError(sender, plugin, e); + MonitorManager.printThrowable(String.format(err, sender.getName(), plugin.getName(), label, StrKit.join(args, " ")), e); } return false; } @@ -136,10 +133,8 @@ public class CommandInjector implements TabExecutor { return Collections.emptyList(); } final long start = System.nanoTime(); - // TODO add a more aggressive 10 ms cpu sample final List result = originalCompleter.onTabComplete(sender, command, alias, args); final long end = System.nanoTime(); - totalTime += end - start; count++; return result; diff --git a/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java b/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java index 4469277..053a713 100644 --- a/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java +++ b/src/main/java/pw/yumc/Yum/inject/ListenerInjector.java @@ -1,9 +1,9 @@ package pw.yumc.Yum.inject; import java.lang.reflect.Field; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang.Validate; import org.bukkit.event.Event; @@ -22,20 +22,20 @@ import pw.yumc.Yum.managers.MonitorManager; public class ListenerInjector implements EventExecutor { private final static String prefix = "§6[§bYum §a事件监控§6] "; + private final static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6事件 §c耗时 §4%sms!"; + private final static String err = prefix + "§6插件 §b%s §6处理 §d%s §6事件时发生异常!"; private final static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败 §6注入类: §3%s!"; private final static String plugin_is_null = "插件不得为NULL!"; private final EventExecutor originalExecutor; private final Plugin plugin; - public Map eventTotalTime; - public Map eventCount; + public Map eventTotalTime = new ConcurrentHashMap<>(); + public Map eventCount = new ConcurrentHashMap<>(); public ListenerInjector(final EventExecutor originalExecutor, final Plugin plugin) { this.originalExecutor = originalExecutor; this.plugin = plugin; - eventTotalTime = new HashMap<>(); - eventCount = new HashMap<>(); } public static void inject(final Plugin plugin) { @@ -46,8 +46,9 @@ public class ListenerInjector implements EventExecutor { if (listener instanceof TimedRegisteredListener) { return; } + // 兼容PerWorldPlugin if (listener.getClass().getName().contains("PWPRegisteredListener")) { - final Field f = Reflect.on(listener).getDeclaredField(RegisteredListener.class, "executor"); + final Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor"); f.setAccessible(true); final EventExecutor originalExecutor = (EventExecutor) f.get(listener); if (originalExecutor instanceof ListenerInjector) { @@ -92,13 +93,12 @@ public class ListenerInjector implements EventExecutor { try { if (!event.isAsynchronous()) { final long start = System.nanoTime(); - // TODO 当操作大于10ms的时候添加一个Lag提示 originalExecutor.execute(listener, event); final long end = System.nanoTime(); final String en = event.getEventName(); final long lag = end - start; if (lag / 1000000 > MonitorManager.lagTime && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) { - MonitorManager.lagTip("§c注意! §6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件 §c耗时 §4" + lag / 1000000 + "ms!"); + MonitorManager.lagTip(String.format(warn, plugin.getName(), event.getEventName(), lag / 1000000)); } if (eventTotalTime.containsKey(en)) { eventTotalTime.put(en, eventTotalTime.get(en) + lag); @@ -116,8 +116,7 @@ public class ListenerInjector implements EventExecutor { e = e.getCause(); } MonitorCommand.lastError = e; - MonitorManager.log(prefix + "§6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时发生异常!"); - MonitorManager.printThrowable(e); + MonitorManager.printThrowable(String.format(err, plugin.getName(), event.getEventName()), e); } } diff --git a/src/main/java/pw/yumc/Yum/inject/TaskInjector.java b/src/main/java/pw/yumc/Yum/inject/TaskInjector.java index 4fc7730..fe89a9b 100644 --- a/src/main/java/pw/yumc/Yum/inject/TaskInjector.java +++ b/src/main/java/pw/yumc/Yum/inject/TaskInjector.java @@ -15,6 +15,8 @@ import pw.yumc.Yum.managers.MonitorManager; public class TaskInjector implements Runnable { private final static String prefix = "§6[§bYum §a任务监控§6] "; + private final static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6任务 §c耗时 §4%sms!"; + private final static String err = prefix + "§6插件 §b%s §6处理 §d%s §6任务时发生异常!"; private final static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!"; private final static String plugin_is_null = "插件不得为NULL!"; private final Runnable originalTask; @@ -81,12 +83,11 @@ public class TaskInjector implements Runnable { public void run() { try { final long start = System.nanoTime(); - // TODO 当操作大于10ms的时候添加一个Lag提示 originalTask.run(); final long end = System.nanoTime(); final long lag = end - start; if (Bukkit.isPrimaryThread() && lag / 1000000 > MonitorManager.lagTime) { - MonitorManager.lagTip("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6执行 §d" + taskName + " §6任务 §c耗时 §4" + lag / 1000000 + "ms!"); + MonitorManager.lagTip(String.format(warn, plugin.getName(), taskName, lag / 1000000)); } totalTime += lag; count++; @@ -96,9 +97,7 @@ public class TaskInjector implements Runnable { e = e.getCause(); } MonitorCommand.lastError = e; - MonitorManager.log(prefix + "§6插件 §b" + plugin.getName() + " §6执行 §d" + taskName + " §6任务时发生异常!"); - MonitorManager.printThrowable(e); + MonitorManager.printThrowable(String.format(err, plugin.getName(), taskName), e); } - } } diff --git a/src/main/java/pw/yumc/Yum/managers/MonitorManager.java b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java index 345241b..c71adea 100644 --- a/src/main/java/pw/yumc/Yum/managers/MonitorManager.java +++ b/src/main/java/pw/yumc/Yum/managers/MonitorManager.java @@ -3,12 +3,16 @@ 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; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; import cn.citycraft.PluginHelper.kit.LogKit; import cn.citycraft.PluginHelper.kit.PluginKit; @@ -19,31 +23,47 @@ import cn.citycraft.PluginHelper.kit.PluginKit; * @author 喵♂呜 */ public class MonitorManager { - public static String prefix = "§6[§bYum §a能耗监控§6] "; - public static int lagTime = 20; - public static boolean debug = ConfigManager.i().isMonitorDebug(); - public static boolean log_to_file = ConfigManager.i().isLogToFile(); + public final static String prefix = "§6[§bYum §a能耗监控§6] "; + private final static String errMsg = prefix + "§c命令执行异常 请反馈下列信息给腐竹!"; + private final static String errP = "§6插件名称: §b%s"; + private final static String errN = "§6异常名称: §c%s"; + private final static String errM = "§6异常说明: §3%s"; + private final static String errInfo = "§6简易错误信息如下:"; + private final static String errStackTrace = " §e位于 §c%s.%s(§4%s:%s§c)"; + private final static String devInfo = "§c开发人员调试信息如下:"; - private static Map monitor = new HashMap<>(); - private static Map task = new HashMap<>(); - private static Map event = new HashMap<>(); - private static Map cmd = new HashMap<>(); + public final static int lagTime = 20; + public final static boolean debug = ConfigManager.i().isMonitorDebug(); + public final static boolean log_to_file = ConfigManager.i().isLogToFile(); + + private final static Map monitor = new ConcurrentHashMap<>(); + private final static Map task = new ConcurrentHashMap<>(); + private final static Map event = new ConcurrentHashMap<>(); + private final static Map cmd = new ConcurrentHashMap<>(); private final static double um = 1000000.00; + private final static LogKit mlog = new LogKit("monitor.log"); + private final static LogKit elog = new LogKit("error.log"); + public static void addCmd(final String pname, final long time) { - monitor.put(pname, monitor.get(pname) + time); - cmd.put(pname, cmd.get(pname) + time); + add(pname, time, monitor, cmd); } public static void addEvent(final String pname, final long time) { - monitor.put(pname, monitor.get(pname) + time); - event.put(pname, event.get(pname) + time); + add(pname, time, monitor, event); } public static void addTask(final String pname, final long time) { - monitor.put(pname, monitor.get(pname) + time); - task.put(pname, task.get(pname) + time); + add(pname, time, monitor, task); + } + + public static void elog(final String message) { + if (log_to_file) { + elog.logSender(message); + } else { + PluginKit.sc(message); + } } public static Map getMonitor() { @@ -54,29 +74,36 @@ public class MonitorManager { return new MonitorInfo(monitor.get(pname) / um, cmd.get(pname) / um, event.get(pname) / um, task.get(pname) / um); } + public static void init() { + for (final Plugin p : Bukkit.getPluginManager().getPlugins()) { + reset(p.getName()); + } + } + public static void lagTip(final String message) { log(prefix + message); } public static void log(final String message) { if (log_to_file) { - LogKit.DEFAULT.logSender(message); + mlog.logSender(message); } else { PluginKit.sc(message); } } - public static void printThrowable(final Throwable e) { - log("§6异常名称: §c" + e.getClass().getName()); - log("§6异常说明: §3" + e.getMessage()); - log("§6简易错误信息如下:"); + public static void printThrowable(final String title, final Throwable e) { + elog(title); + elog(String.format(errN, e.getClass().getName())); + elog(String.format(errM, e.getMessage())); + elog(errInfo); final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length; for (int i = 0; i < l; i++) { final StackTraceElement ste = e.getStackTrace()[i]; - log(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)"); + elog(String.format(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName(), ste.getLineNumber())); } if (debug) { - PluginKit.sc("§c开发人员调试信息如下:"); + PluginKit.sc(devInfo); e.printStackTrace(); } } @@ -88,6 +115,17 @@ public class MonitorManager { cmd.put(pname, 0L); } + public static void sendError(final CommandSender sender, final Plugin plugin, final Throwable e) { + sender.sendMessage(errMsg); + sender.sendMessage(String.format(errP, plugin.getName())); + sender.sendMessage(String.format(errN, e.getClass().getName())); + sender.sendMessage(String.format(errM, e.getMessage())); + } + + public static void sendObject(final CommandSender sender) { + sender.sendMessage(String.format("monitor@%s cmd@%s event@%s task@%s", monitor.hashCode(), cmd.hashCode(), event.hashCode(), task.hashCode())); + } + /** * 使用 Map按value进行排序 * @@ -110,6 +148,13 @@ public class MonitorManager { return sortedMap; } + @SafeVarargs + private static void add(final String pname, final long time, final Map... maps) { + for (final Map map : maps) { + map.put(pname, map.get(pname) + time); + } + } + public static class MonitorInfo { public double monitor; public double cmd; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f5cfef4..0dfdc1a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,14 +3,14 @@ ############################ #配置版本号 请勿修改!!! -Version: 2.3 +Version: 2.4 #是否只允许控制台执行插件仓库命令 -onlyCommandConsole: false +onlyCommandConsole: '' #是否只允许控制台执行插件网络管理命令 -onlyNetCommandConsole: false +onlyNetCommandConsole: '' #是否只允许控制台执行插件文件管理命令 -onlyFileCommandConsole: false +onlyFileCommandConsole: '' #禁止rm -rf的文件夹列表 blacklist: - 'plugins'