feat: 新增屏蔽指定插件报错功能

Signed-off-by: MiaoWoo <admin@yumc.pw>
master
MiaoWoo 2021-10-28 09:51:27 +00:00
parent 129f854382
commit 18dc99e78e
7 changed files with 708 additions and 714 deletions

18
pom.xml
View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>Yum</artifactId> <artifactId>Yum</artifactId>
<version>2.9.1</version> <version>2.9.5</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>Minecraft 服务器插件管理系统</description> <description>Minecraft 服务器插件管理系统</description>
@ -16,16 +16,18 @@
</parent> </parent>
<properties> <properties>
<update.description>§a补丁包 2.9.1 版本</update.description> <update.description>§a补丁包 2.9.5 版本</update.description>
<update.changes> <update.changes>
§620-03-25 §cfix: paper HikariPool error; §621-10-28 §afeat: 新增屏蔽插件报错功能;
§619-09-30 §cfix: tabComplete error; §620-03-25 §afeat: 优化 当前插件获取逻辑;
§619-08-28 §cfix: knownCommands not compatible; §620-03-25 §c修复: Paper HikariPool 不兼容问题;
       §cfix: async event on primary thread; §619-09-30 §c修复: 自动补全报错的问题;
§619-08-26 §cfix: 修复不兼容 1.14.4 的问题; §619-08-28 §c修复: knownCommands 不兼容;
§619-02-23 §cfix: 修复不兼容 1.13 的问题;       §c修复: async event on primary thread;
</update.changes> </update.changes>
<update.changelog> <update.changelog>
§619-08-26 §c修复: 修复不兼容 1.14.4 的问题;
§619-02-23 §c修复: 修复不兼容 1.13 的问题;
§617-07-29 §cfix: 修复不兼容 1.12 的问题; §617-07-29 §cfix: 修复不兼容 1.12 的问题;
§6- §cfix: §7修复仓库数据读取错误的问题; §6- §cfix: §7修复仓库数据读取错误的问题;
§6- §cfix: §7修复一个tab补全产生的错误 §6- §cfix: §7修复一个tab补全产生的错误

View File

@ -1,139 +1,132 @@
package pw.yumc.Yum.inject; package pw.yumc.Yum.inject;
import java.util.Collections; import org.apache.commons.lang.Validate;
import java.util.List; import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin;
import org.bukkit.Bukkit; import org.bukkit.plugin.PluginManager;
import org.bukkit.command.Command; import pw.yumc.Yum.commands.MonitorCommand;
import org.bukkit.command.CommandExecutor; import pw.yumc.Yum.managers.MonitorManager;
import org.bukkit.command.CommandSender; import pw.yumc.YumCore.kit.StrKit;
import org.bukkit.command.PluginCommand; import pw.yumc.YumCore.reflect.Reflect;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.command.TabCompleter; import java.util.Collections;
import org.bukkit.command.TabExecutor; import java.util.List;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; public class CommandInjector implements TabExecutor {
private static String prefix = "§6[§bYum §a命令监控§6] ";
import pw.yumc.Yum.commands.MonitorCommand; private static String warn = "§c注意! §6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令 §c耗时 §4%sms §c平均耗时 §4%sms!";
import pw.yumc.Yum.managers.MonitorManager; private static String err = prefix + "§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令时发生异常!";
import pw.yumc.YumCore.kit.StrKit; private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!";
import pw.yumc.YumCore.reflect.Reflect; private static String plugin_is_null = "插件不得为NULL!";
private CommandExecutor originalExecutor;
public class CommandInjector implements TabExecutor { private TabCompleter originalCompleter;
private static String prefix = "§6[§bYum §a命令监控§6] ";
private static String warn = "§c注意! §6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令 §c耗时 §4%sms §c平均耗时 §4%sms!"; private Plugin plugin;
private static String err = prefix + "§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令时发生异常!";
private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!"; public long totalTime;
private static String plugin_is_null = "插件不得为NULL!"; public int count;
private CommandExecutor originalExecutor;
private TabCompleter originalCompleter; public CommandInjector(CommandExecutor originalCommandExecutor, TabCompleter originalTabCompleter, Plugin plugin) {
this.originalExecutor = originalCommandExecutor;
private Plugin plugin; this.originalCompleter = originalTabCompleter;
this.plugin = plugin;
public long totalTime; }
public int count;
public static void inject(Plugin plugin) {
public CommandInjector(CommandExecutor originalCommandExecutor, TabCompleter originalTabCompleter, Plugin plugin) { Validate.notNull(plugin, plugin_is_null);
this.originalExecutor = originalCommandExecutor; try {
this.originalCompleter = originalTabCompleter; PluginManager pluginManager = Bukkit.getPluginManager();
this.plugin = plugin; SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
} for (Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
public static void inject(Plugin plugin) { PluginCommand pluginCommand = (PluginCommand) command;
Validate.notNull(plugin, plugin_is_null); Plugin cp = pluginCommand.getPlugin();
try { if (cp.equals(plugin)) {
PluginManager pluginManager = Bukkit.getPluginManager(); CommandExecutor executor = Reflect.on(command).get("executor");
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap"); if (executor instanceof CommandInjector) { return; }
for (Command command : commandMap.getCommands()) { TabCompleter completer = Reflect.on(command).get("completer");
if (command instanceof PluginCommand) { CommandInjector commandInjector = new CommandInjector(executor, completer, plugin);
PluginCommand pluginCommand = (PluginCommand) command; Reflect.on(command).set("executor", commandInjector);
Plugin cp = pluginCommand.getPlugin(); Reflect.on(command).set("completer", commandInjector);
if (cp.equals(plugin)) { }
CommandExecutor executor = Reflect.on(command).get("executor"); }
if (executor instanceof CommandInjector) { return; } }
TabCompleter completer = Reflect.on(command).get("completer"); } catch (Throwable e) {
CommandInjector commandInjector = new CommandInjector(executor, completer, plugin); MonitorManager.log(String.format(inject_error, plugin.getName()));
Reflect.on(command).set("executor", commandInjector); }
Reflect.on(command).set("completer", commandInjector); }
}
} public static void uninject(Plugin plugin) {
} Validate.notNull(plugin, plugin_is_null);
} catch (Throwable e) { try {
MonitorManager.log(String.format(inject_error, plugin.getName())); PluginManager pluginManager = Bukkit.getPluginManager();
} SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
} for (Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
public static void uninject(Plugin plugin) { PluginCommand pluginCommand = (PluginCommand) command;
Validate.notNull(plugin, plugin_is_null); Plugin cp = pluginCommand.getPlugin();
try { if (cp.equals(plugin)) {
PluginManager pluginManager = Bukkit.getPluginManager(); CommandExecutor executor = Reflect.on(command).get("executor");
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap"); if (executor instanceof CommandInjector) {
for (Command command : commandMap.getCommands()) { CommandInjector injected = (CommandInjector) executor;
if (command instanceof PluginCommand) { Reflect.on(command).set("executor", injected.getOriginalExecutor());
PluginCommand pluginCommand = (PluginCommand) command; }
Plugin cp = pluginCommand.getPlugin(); TabCompleter completer = Reflect.on(command).get("completer");
if (cp.equals(plugin)) { if (completer instanceof CommandInjector) {
CommandExecutor executor = Reflect.on(command).get("executor"); CommandInjector injected = (CommandInjector) completer;
if (executor instanceof CommandInjector) { Reflect.on(command).set("completer", injected.getOriginalCompleter());
CommandInjector injected = (CommandInjector) executor; }
Reflect.on(command).set("executor", injected.getOriginalExecutor()); }
} }
TabCompleter completer = Reflect.on(command).get("completer"); }
if (completer instanceof CommandInjector) { } catch (Throwable ignored) {
CommandInjector injected = (CommandInjector) completer; }
Reflect.on(command).set("completer", injected.getOriginalCompleter()); }
}
} public TabCompleter getOriginalCompleter() {
} return originalCompleter;
} }
} catch (Throwable ignored) {
} public CommandExecutor getOriginalExecutor() {
} return originalExecutor;
}
public TabCompleter getOriginalCompleter() {
return originalCompleter; @Override
} public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
public CommandExecutor getOriginalExecutor() { long start = System.nanoTime();
return originalExecutor; boolean result = originalExecutor.onCommand(sender, command, label, args);
} long end = System.nanoTime();
long lag = end - start;
@Override totalTime += lag;
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { count++;
try { long lagms = lag / MonitorManager.um;
long start = System.nanoTime(); long avglagms = totalTime / count / MonitorManager.um;
boolean result = originalExecutor.onCommand(sender, command, label, args); if (Bukkit.isPrimaryThread() && lagms > MonitorManager.lagTime && avglagms > MonitorManager.lagTime) {
long end = System.nanoTime(); MonitorManager.lagTip(String.format(warn, sender.getName(), plugin.getName(), label, StrKit.join(args, " "), lagms, avglagms));
long lag = end - start; }
totalTime += lag; MonitorManager.addCmd(plugin.getName(), lag);
count++; return result;
long lagms = lag / MonitorManager.um; } catch (Throwable e) {
long avglagms = totalTime / count / MonitorManager.um; while (e.getCause() != null) {
if (Bukkit.isPrimaryThread() && lagms > MonitorManager.lagTime && avglagms > MonitorManager.lagTime) { e = e.getCause();
MonitorManager.lagTip(String.format(warn, sender.getName(), plugin.getName(), label, StrKit.join(args, " "), lagms, avglagms)); }
} MonitorCommand.lastError = e;
MonitorManager.addCmd(plugin.getName(), lag); MonitorManager.sendError(sender, plugin, e);
return result; MonitorManager.printThrowable(plugin, String.format(err, sender.getName(), plugin.getName(), label, StrKit.join(args, " ")), e);
} catch (Throwable e) { }
while (e.getCause() != null) { return false;
e = e.getCause(); }
}
MonitorCommand.lastError = e; @Override
MonitorManager.sendError(sender, plugin, e); public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
MonitorManager.printThrowable(String.format(err, sender.getName(), plugin.getName(), label, StrKit.join(args, " ")), e); if (originalCompleter == null) { return Collections.emptyList(); }
} long start = System.nanoTime();
return false; List<String> result = originalCompleter.onTabComplete(sender, command, alias, args);
} long end = System.nanoTime();
totalTime += end - start;
@Override count++;
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { return result;
if (originalCompleter == null) { return Collections.emptyList(); } }
long start = System.nanoTime(); }
List<String> result = originalCompleter.onTabComplete(sender, command, alias, args);
long end = System.nanoTime();
totalTime += end - start;
count++;
return result;
}
}

View File

@ -1,120 +1,119 @@
package pw.yumc.Yum.inject; package pw.yumc.Yum.inject;
import java.lang.reflect.Field; import org.apache.commons.lang.Validate;
import java.util.List; import org.bukkit.event.Event;
import java.util.Map; import org.bukkit.event.EventException;
import java.util.concurrent.ConcurrentHashMap; import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.apache.commons.lang.Validate; import org.bukkit.plugin.EventExecutor;
import org.bukkit.event.Event; import org.bukkit.plugin.Plugin;
import org.bukkit.event.EventException; import org.bukkit.plugin.RegisteredListener;
import org.bukkit.event.HandlerList; import org.bukkit.plugin.TimedRegisteredListener;
import org.bukkit.event.Listener; import pw.yumc.Yum.commands.MonitorCommand;
import org.bukkit.plugin.EventExecutor; import pw.yumc.Yum.managers.ConfigManager;
import org.bukkit.plugin.Plugin; import pw.yumc.Yum.managers.MonitorManager;
import org.bukkit.plugin.RegisteredListener; import pw.yumc.YumCore.reflect.Reflect;
import org.bukkit.plugin.TimedRegisteredListener;
import java.lang.reflect.Field;
import pw.yumc.Yum.commands.MonitorCommand; import java.util.List;
import pw.yumc.Yum.managers.ConfigManager; import java.util.Map;
import pw.yumc.Yum.managers.MonitorManager; import java.util.concurrent.ConcurrentHashMap;
import pw.yumc.YumCore.reflect.Reflect;
public class ListenerInjector implements EventExecutor {
public class ListenerInjector implements EventExecutor { private static String prefix = "§6[§bYum §a事件监控§6] ";
private static String prefix = "§6[§bYum §a事件监控§6] "; private static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6事件 §c耗时 §4%sms §c平均耗时 §4%sms!";
private static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6事件 §c耗时 §4%sms §c平均耗时 §4%sms!"; private static String err = prefix + "§6插件 §b%s §6处理 §d%s §6事件时发生异常!";
private static String err = prefix + "§6插件 §b%s §6处理 §d%s §6事件时发生异常!"; private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败 §6注入类: §3%s!";
private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败 §6注入类: §3%s!"; private static String plugin_is_null = "插件不得为NULL!";
private static String plugin_is_null = "插件不得为NULL!"; private EventExecutor originalExecutor;
private EventExecutor originalExecutor;
private Plugin plugin;
private Plugin plugin;
public Map<String, Long> eventTotalTime = new ConcurrentHashMap<>();
public Map<String, Long> eventTotalTime = new ConcurrentHashMap<>(); public Map<String, Integer> eventCount = new ConcurrentHashMap<>();
public Map<String, Integer> eventCount = new ConcurrentHashMap<>();
public ListenerInjector(EventExecutor originalExecutor, Plugin plugin) {
public ListenerInjector(EventExecutor originalExecutor, Plugin plugin) { this.originalExecutor = originalExecutor;
this.originalExecutor = originalExecutor; this.plugin = plugin;
this.plugin = plugin; }
}
public static void inject(Plugin plugin) {
public static void inject(Plugin plugin) { Validate.notNull(plugin, plugin_is_null);
Validate.notNull(plugin, plugin_is_null); List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin); for (RegisteredListener listener : listeners) {
for (RegisteredListener listener : listeners) { try {
try { if (listener instanceof TimedRegisteredListener) { return; }
if (listener instanceof TimedRegisteredListener) { return; } // 兼容PerWorldPlugin
// 兼容PerWorldPlugin if (listener.getClass().getName().contains("PWPRegisteredListener")) {
if (listener.getClass().getName().contains("PWPRegisteredListener")) { Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor");
Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor"); f.setAccessible(true);
f.setAccessible(true); EventExecutor originalExecutor = (EventExecutor) f.get(listener);
EventExecutor originalExecutor = (EventExecutor) f.get(listener); if (originalExecutor instanceof ListenerInjector) { return; }
if (originalExecutor instanceof ListenerInjector) { return; } ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin); f.set(listener, listenerInjector);
f.set(listener, listenerInjector); } else {
} else { EventExecutor originalExecutor = Reflect.on(listener).get("executor");
EventExecutor originalExecutor = Reflect.on(listener).get("executor"); if (originalExecutor instanceof ListenerInjector) { return; }
if (originalExecutor instanceof ListenerInjector) { return; } ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin); Reflect.on(listener).set("executor", listenerInjector);
Reflect.on(listener).set("executor", listenerInjector); }
} } catch (Throwable e) {
} catch (Throwable e) { MonitorManager.log(String.format(inject_error, plugin.getName(), listener.getClass().getName()));
MonitorManager.log(String.format(inject_error, plugin.getName(), listener.getClass().getName())); e.printStackTrace();
e.printStackTrace(); }
} }
} }
}
public static void uninject(Plugin plugin) {
public static void uninject(Plugin plugin) { Validate.notNull(plugin, plugin_is_null);
Validate.notNull(plugin, plugin_is_null); try {
try { List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin); for (RegisteredListener listener : listeners) {
for (RegisteredListener listener : listeners) { if (listener instanceof TimedRegisteredListener) { return; }
if (listener instanceof TimedRegisteredListener) { return; } EventExecutor executor = Reflect.on(listener).get("executor");
EventExecutor executor = Reflect.on(listener).get("executor"); if (executor instanceof ListenerInjector) {
if (executor instanceof ListenerInjector) { Reflect.on(listener).set("executor", ((ListenerInjector) executor).getOriginalExecutor());
Reflect.on(listener).set("executor", ((ListenerInjector) executor).getOriginalExecutor()); }
} }
} } catch (Throwable ignored) {
} catch (Throwable ignored) { }
} }
}
@Override
@Override public void execute(Listener listener, Event event) throws EventException {
public void execute(Listener listener, Event event) throws EventException { try {
try { if (!event.isAsynchronous()) {
if (!event.isAsynchronous()) { long start = System.nanoTime();
long start = System.nanoTime(); originalExecutor.execute(listener, event);
originalExecutor.execute(listener, event); long end = System.nanoTime();
long end = System.nanoTime(); String en = event.getEventName();
String en = event.getEventName(); long lag = end - start;
long lag = end - start; if (eventTotalTime.containsKey(en)) {
if (eventTotalTime.containsKey(en)) { eventTotalTime.put(en, eventTotalTime.get(en) + lag);
eventTotalTime.put(en, eventTotalTime.get(en) + lag); eventCount.put(en, eventCount.get(en) + 1);
eventCount.put(en, eventCount.get(en) + 1); } else {
} else { eventTotalTime.put(en, end - start);
eventTotalTime.put(en, end - start); eventCount.put(en, 1);
eventCount.put(en, 1); }
} long lagms = lag / MonitorManager.um;
long lagms = lag / MonitorManager.um; long avglagms = eventTotalTime.get(en) / eventCount.get(en) / MonitorManager.um;
long avglagms = eventTotalTime.get(en) / eventCount.get(en) / MonitorManager.um; if (avglagms > MonitorManager.lagTime && lagms > MonitorManager.lagTime && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
if (avglagms > MonitorManager.lagTime && lagms > MonitorManager.lagTime && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) { MonitorManager.lagTip(String.format(warn, plugin.getName(), event.getEventName(), lagms, avglagms));
MonitorManager.lagTip(String.format(warn, plugin.getName(), event.getEventName(), lagms, avglagms)); }
} MonitorManager.addEvent(plugin.getName(), lag);
MonitorManager.addEvent(plugin.getName(), lag); } else {
} else { originalExecutor.execute(listener, event);
originalExecutor.execute(listener, event); }
} } catch (Throwable e) {
} catch (Throwable e) { while (e.getCause() != null) {
while (e.getCause() != null) { e = e.getCause();
e = e.getCause(); }
} MonitorCommand.lastError = e;
MonitorCommand.lastError = e; MonitorManager.printThrowable(plugin, String.format(err, plugin.getName(), event.getEventName()), e);
MonitorManager.printThrowable(String.format(err, plugin.getName(), event.getEventName()), e); }
} }
}
public EventExecutor getOriginalExecutor() {
public EventExecutor getOriginalExecutor() { return originalExecutor;
return originalExecutor; }
} }
}

View File

@ -1,120 +1,119 @@
package pw.yumc.Yum.inject; package pw.yumc.Yum.inject;
import java.util.List; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin;
import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitScheduler; import pw.yumc.Yum.commands.MonitorCommand;
import org.bukkit.scheduler.BukkitTask; import pw.yumc.Yum.managers.MonitorManager;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.Yum.commands.MonitorCommand; import pw.yumc.YumCore.kit.StrKit;
import pw.yumc.Yum.managers.MonitorManager; import pw.yumc.YumCore.reflect.Reflect;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.kit.StrKit; import java.util.List;
import pw.yumc.YumCore.reflect.Reflect;
public class TaskInjector implements Runnable {
public class TaskInjector implements Runnable { private static String prefix = "§6[§bYum §a任务监控§6] ";
private static String prefix = "§6[§bYum §a任务监控§6] "; private static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6任务 §c耗时 §4%sms §c平均耗时 §4%sms!";
private static String warn = "§c注意! §6插件 §b%s §6处理 §d%s §6任务 §c耗时 §4%sms §c平均耗时 §4%sms!"; private static String err = prefix + "§6插件 §b%s §6处理 §d%s §6任务时发生异常!";
private static String err = prefix + "§6插件 §b%s §6处理 §d%s §6任务时发生异常!"; private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!";
private static String inject_error = prefix + "§6插件 §b%s §c注入能耗监控失败!"; private static String plugin_is_null = "插件不得为NULL!";
private static String plugin_is_null = "插件不得为NULL!"; private static String taskFieldName = "task";
private static String taskFieldName = "task";
static {
static { BukkitTask task = Bukkit.getServer().getScheduler().runTask(P.instance, new Runnable() {
BukkitTask task = Bukkit.getServer().getScheduler().runTask(P.instance, new Runnable(){ @Override
@Override public void run() {}
public void run() {} });
}); try {
try { Reflect.on(task).get("rTask");
Reflect.on(task).get("rTask"); taskFieldName = "rTask";
taskFieldName = "rTask"; } catch (Throwable ex) {
}catch (Throwable ex) { }
} }
}
private Runnable originalTask;
private Runnable originalTask; private Plugin plugin;
private Plugin plugin;
private String taskName;
private String taskName;
public long totalTime;
public long totalTime; public int count;
public int count;
public TaskInjector(Runnable originalTask, Plugin plugin) {
public TaskInjector(Runnable originalTask, Plugin plugin) { this.originalTask = originalTask;
this.originalTask = originalTask; this.plugin = plugin;
this.plugin = plugin; Class<? extends Runnable> taskClass = getOriginalTask().getClass();
Class<? extends Runnable> taskClass = getOriginalTask().getClass(); taskName = StrKit.isBlank(taskClass.getSimpleName()) ? taskClass.getName() : taskClass.getSimpleName();
taskName = StrKit.isBlank(taskClass.getSimpleName()) ? taskClass.getName() : taskClass.getSimpleName(); }
}
// 当前注入只能对TimerTask有效
// 当前注入只能对TimerTask有效 // 对于单次执行的任务 我们需要注册一个动态的代理
// 对于单次执行的任务 我们需要注册一个动态的代理 public static void inject(Plugin plugin) {
public static void inject(Plugin plugin) { Validate.notNull(plugin, plugin_is_null);
Validate.notNull(plugin, plugin_is_null); try {
try { BukkitScheduler scheduler = Bukkit.getScheduler();
BukkitScheduler scheduler = Bukkit.getScheduler(); List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
List<BukkitTask> pendingTasks = scheduler.getPendingTasks(); for (BukkitTask pendingTask : pendingTasks) {
for (BukkitTask pendingTask : pendingTasks) { // 忽略异步任务
// 忽略异步任务 if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) { Runnable originalTask = Reflect.on(pendingTask).get(taskFieldName);
Runnable originalTask = Reflect.on(pendingTask).get(taskFieldName); if (originalTask instanceof TaskInjector) {
if (originalTask instanceof TaskInjector) { return;
return; }
} TaskInjector taskInjector = new TaskInjector(originalTask, plugin);
TaskInjector taskInjector = new TaskInjector(originalTask, plugin); Reflect.on(pendingTask).set(taskFieldName, taskInjector);
Reflect.on(pendingTask).set(taskFieldName, taskInjector); }
} }
} } catch (Throwable e) {
} catch (Throwable e) { MonitorManager.log(String.format(inject_error, plugin.getName()));
MonitorManager.log(String.format(inject_error, plugin.getName())); }
} }
}
public static void uninject(Plugin plugin) {
public static void uninject(Plugin plugin) { Validate.notNull(plugin, plugin_is_null);
Validate.notNull(plugin, plugin_is_null); try {
try { BukkitScheduler scheduler = Bukkit.getScheduler();
BukkitScheduler scheduler = Bukkit.getScheduler(); List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
List<BukkitTask> pendingTasks = scheduler.getPendingTasks(); for (BukkitTask pendingTask : pendingTasks) {
for (BukkitTask pendingTask : pendingTasks) { // 忽略异步任务
// 忽略异步任务 if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) { Runnable originalTask = Reflect.on(pendingTask).get("task");
Runnable originalTask = Reflect.on(pendingTask).get("task"); if (originalTask instanceof TaskInjector) {
if (originalTask instanceof TaskInjector) { Reflect.on(pendingTask).set("task", ((TaskInjector) originalTask).getOriginalTask());
Reflect.on(pendingTask).set("task", ((TaskInjector) originalTask).getOriginalTask()); }
} }
} }
} } catch (Throwable ignored) {
} catch (Throwable ignored) { }
} }
}
public Runnable getOriginalTask() {
public Runnable getOriginalTask() { return originalTask;
return originalTask; }
}
@Override
@Override public void run() {
public void run() { try {
try { long start = System.nanoTime();
long start = System.nanoTime(); originalTask.run();
originalTask.run(); long end = System.nanoTime();
long end = System.nanoTime(); long lag = end - start;
long lag = end - start; totalTime += lag;
totalTime += lag; count++;
count++; long lagms = lag / MonitorManager.um;
long lagms = lag / MonitorManager.um; long avglagms = totalTime / count / MonitorManager.um;
long avglagms = totalTime / count / MonitorManager.um; if (Bukkit.isPrimaryThread() && lagms > MonitorManager.lagTime && avglagms > MonitorManager.lagTime) {
if (Bukkit.isPrimaryThread() && lagms > MonitorManager.lagTime && avglagms > MonitorManager.lagTime) { MonitorManager.lagTip(String.format(warn, plugin.getName(), taskName, lagms, avglagms));
MonitorManager.lagTip(String.format(warn, plugin.getName(), taskName, lagms, avglagms)); }
} MonitorManager.addTask(plugin.getName(), lag);
MonitorManager.addTask(plugin.getName(), lag); } catch (Throwable e) {
} catch (Throwable e) { while (e.getCause() != null) {
while (e.getCause() != null) { e = e.getCause();
e = e.getCause(); }
} MonitorCommand.lastError = e;
MonitorCommand.lastError = e; MonitorManager.printThrowable(plugin, String.format(err, plugin.getName(), taskName), e);
MonitorManager.printThrowable(String.format(err, plugin.getName(), taskName), e); }
} }
} }
}

View File

@ -1,126 +1,129 @@
package pw.yumc.Yum.managers; package pw.yumc.Yum.managers;
import java.util.List; import org.bukkit.plugin.java.JavaPlugin;
import pw.yumc.YumCore.bukkit.P;
import org.bukkit.plugin.java.JavaPlugin; import pw.yumc.YumCore.config.FileConfig;
import pw.yumc.YumCore.sql.DataBase;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.config.FileConfig; import java.util.List;
import pw.yumc.YumCore.sql.DataBase;
public class ConfigManager {
public class ConfigManager { public static String ENABLE = "Enable";
public static String ENABLE = "Enable"; public static String BLACK = "Black";
public static String BLACK = "Black"; public static String IGNORE = "Ignore";
public static String IGNORE = "Ignore";
private static ConfigManager i = new ConfigManager(P.instance);
private static ConfigManager i = new ConfigManager(P.instance);
public FileConfig config;
public FileConfig config; public FileConfig setop;
public FileConfig setop; public FileConfig network;
public FileConfig network; public FileConfig thread;
public FileConfig thread; public FileConfig monitor;
public FileConfig monitor;
public ConfigManager(JavaPlugin plugin) {
public ConfigManager(JavaPlugin plugin) { config = new FileConfig();
config = new FileConfig(); setop = new FileConfig("setop.yml");
setop = new FileConfig("setop.yml"); network = new FileConfig("network.yml");
network = new FileConfig("network.yml"); thread = new FileConfig("thread.yml");
thread = new FileConfig("thread.yml"); monitor = new FileConfig("monitor.yml");
monitor = new FileConfig("monitor.yml"); }
}
public static ConfigManager i() {
public static ConfigManager i() { return i;
return i; }
}
public List<String> getBlackList() {
public List<String> getBlackList() { return config.getStringList("blacklist");
return config.getStringList("blacklist"); }
}
public DataBase getDataBase() {
public DataBase getDataBase() { return DataBase.create(P.instance, config.getConfigurationSection(""));
return DataBase.create(P.instance, config.getConfigurationSection("")); }
}
public List<String> getIgnoreList() {
public List<String> getIgnoreList() { return config.getStringList("ignorelist");
return config.getStringList("ignorelist"); }
}
public List<String> getMonitorIgnoreList() {
public List<String> getMonitorIgnoreList() { return monitor.getStringList(IGNORE);
return monitor.getStringList(IGNORE); }
}
public List<String> getMonitorIgnoreErrorList() {
public List<String> getNetworkBlackList() { return monitor.getStringList("IgnoreError");
return network.getStringList(BLACK); }
}
public List<String> getNetworkBlackList() {
public List<String> getNetworkIgnoreList() { return network.getStringList(BLACK);
return network.getStringList(IGNORE); }
}
public List<String> getNetworkIgnoreList() {
public List<String> getNetworkWhiteURL() { return network.getStringList(IGNORE);
return network.getStringList("WhiteURL"); }
}
public List<String> getNetworkWhiteURL() {
public List<String> getSetOpBlackList() { return network.getStringList("WhiteURL");
return setop.getStringList(BLACK); }
}
public List<String> getSetOpBlackList() {
public List<String> getSetOpIgnoreList() { return setop.getStringList(BLACK);
return setop.getStringList(IGNORE); }
}
public List<String> getSetOpIgnoreList() {
public boolean isAllowPrimaryThread() { return setop.getStringList(IGNORE);
return network.getBoolean("AllowPrimaryThread", false); }
}
public boolean isAllowPrimaryThread() {
public boolean isLogToFile() { return network.getBoolean("AllowPrimaryThread", false);
return monitor.getBoolean("LogToFile"); }
}
public boolean isLogToFile() {
public boolean isMainThreadCheck() { return monitor.getBoolean("LogToFile");
return thread.getBoolean("MainThreadCheck", true); }
}
public boolean isMainThreadCheck() {
public boolean isMainThreadDebug() { return thread.getBoolean("MainThreadCheck", true);
return thread.getBoolean("Debug"); }
}
public boolean isMainThreadDebug() {
public boolean isMonitorDebug() { return thread.getBoolean("Debug");
return monitor.getBoolean("Debug"); }
}
public boolean isMonitorDebug() {
public boolean isMonitorEnable() { return monitor.getBoolean("Debug");
return monitor.getBoolean(ENABLE, true); }
}
public boolean isMonitorEnable() {
public boolean isNetworkDebug() { return monitor.getBoolean(ENABLE, true);
return network.getBoolean("NetworkDebug", false); }
}
public boolean isNetworkDebug() {
public boolean isNetworkEnable() { return network.getBoolean("NetworkDebug", false);
return network.getBoolean(ENABLE, true); }
}
public boolean isNetworkEnable() {
public boolean isNetworkShowInfo() { return network.getBoolean(ENABLE, true);
return network.getBoolean("ShowInfo", true); }
}
public boolean isNetworkShowInfo() {
public boolean isSetOpEnable() { return network.getBoolean("ShowInfo", true);
return setop.getBoolean(ENABLE, true); }
}
public boolean isSetOpEnable() {
public boolean isThreadSafe() { return setop.getBoolean(ENABLE, true);
return thread.getBoolean("ThreadSafe", true); }
}
public boolean isThreadSafe() {
public List<String> getNetWorkDebug() { return thread.getBoolean("ThreadSafe", true);
return network.getStringList("Debug"); }
}
public List<String> getNetWorkDebug() {
public void reload() { return network.getStringList("Debug");
setop.reload(); }
network.reload();
thread.reload(); public void reload() {
monitor.reload(); setop.reload();
} network.reload();
} thread.reload();
monitor.reload();
}
}

View File

@ -1,185 +1,180 @@
package pw.yumc.Yum.managers; package pw.yumc.Yum.managers;
import java.util.ArrayList; import org.bukkit.Bukkit;
import java.util.Collection; import org.bukkit.command.CommandSender;
import java.util.Collections; import org.bukkit.plugin.Plugin;
import java.util.Comparator; import pw.yumc.YumCore.bukkit.Log;
import java.util.Iterator; import pw.yumc.YumCore.kit.LogKit;
import java.util.LinkedHashMap;
import java.util.List; import java.util.*;
import java.util.Map; import java.util.Map.Entry;
import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
import org.bukkit.Bukkit; *
import org.bukkit.command.CommandSender; *
import org.bukkit.plugin.Plugin; * @author
* @since 2016719 3:55:54
import pw.yumc.YumCore.bukkit.Log; */
import pw.yumc.YumCore.kit.LogKit; public class MonitorManager {
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";
* @since 2016719 3:55:54 private static String errM = "§6异常说明: §3%s";
* @author private static String errInfo = "§6简易错误信息如下:";
*/ private static String errStackTrace = " §e位于 §c%s.%s(§4%s:%s§c)";
public class MonitorManager { private static String devInfo = "§c开发人员调试信息如下:";
public static String prefix = "§6[§bYum §a能耗监控§6] ";
private static String errMsg = prefix + "§c命令执行异常 请反馈下列信息给腐竹!"; public static int lagTime = 20;
private static String errP = "§6插件名称: §b%s"; public static int um = 1000000;
private static String errN = "§6异常名称: §c%s"; public static boolean debug = ConfigManager.i().isMonitorDebug();
private static String errM = "§6异常说明: §3%s"; public static boolean log_to_file = ConfigManager.i().isLogToFile();
private static String errInfo = "§6简易错误信息如下:";
private static String errStackTrace = " §e位于 §c%s.%s(§4%s:%s§c)"; private static double totalTime = 0;
private static String devInfo = "§c开发人员调试信息如下:";
private static Map<String, Long> monitor = new ConcurrentHashMap<>();
public static int lagTime = 20; private static Map<String, Long> task = new ConcurrentHashMap<>();
public static int um = 1000000; private static Map<String, Long> event = new ConcurrentHashMap<>();
public static boolean debug = ConfigManager.i().isMonitorDebug(); private static Map<String, Long> cmd = new ConcurrentHashMap<>();
public static boolean log_to_file = ConfigManager.i().isLogToFile();
private static LogKit mlog = new LogKit("monitor.log");
private static double totalTime = 0; private static LogKit elog = new LogKit("error.log");
private static Map<String, Long> monitor = new ConcurrentHashMap<>(); public static void addCmd(String pname, long time) {
private static Map<String, Long> task = new ConcurrentHashMap<>(); add(pname, time, monitor, cmd);
private static Map<String, Long> event = new ConcurrentHashMap<>(); }
private static Map<String, Long> cmd = new ConcurrentHashMap<>();
public static void addEvent(String pname, long time) {
private static LogKit mlog = new LogKit("monitor.log"); add(pname, time, monitor, event);
private static LogKit elog = new LogKit("error.log"); }
public static void addCmd(String pname, long time) { public static void addTask(String pname, long time) {
add(pname, time, monitor, cmd); add(pname, time, monitor, task);
} }
public static void addEvent(String pname, long time) { public static void elog(String message) {
add(pname, time, monitor, event); if (log_to_file) {
} elog.console(message);
} else {
public static void addTask(String pname, long time) { Log.console(message);
add(pname, time, monitor, task); }
} }
public static void elog(String message) { public static Map<String, Long> getMonitor() {
if (log_to_file) { return sortMapByValue(monitor);
elog.console(message); }
} else {
Log.console(message); public static MonitorInfo getMonitorInfo(String pname) {
} double per = 100.00;
} return new MonitorInfo(monitor.get(pname) / totalTime * per, cmd.get(pname) / totalTime * per, event.get(pname) / totalTime * per, task.get(pname) / totalTime * per);
}
public static Map<String, Long> getMonitor() {
return sortMapByValue(monitor); public static void init() {
} for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
reset(p.getName());
public static MonitorInfo getMonitorInfo(String pname) { }
double per = 100.00; }
return new MonitorInfo(monitor.get(pname) / totalTime * per, cmd.get(pname) / totalTime * per, event.get(pname) / totalTime * per, task.get(pname) / totalTime * per);
} public static void lagTip(String message) {
log(prefix + message);
public static void init() { }
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
reset(p.getName()); public static void log(String message) {
} if (log_to_file) {
} mlog.console(message);
} else {
public static void lagTip(String message) { Log.console(message);
log(prefix + message); }
} }
public static void log(String message) { public static void printThrowable(Plugin plugin, String title, Throwable e) {
if (log_to_file) { if (ConfigManager.i().getMonitorIgnoreErrorList().contains(plugin.getName())) {
mlog.console(message); return;
} else { }
Log.console(message); elog(title);
} elog(String.format(errN, e.getClass().getName()));
} elog(String.format(errM, e.getMessage()));
elog(errInfo);
public static void printThrowable(String title, Throwable e) { int l = Math.min(e.getStackTrace().length, 5);
elog(title); for (int i = 0; i < l; i++) {
elog(String.format(errN, e.getClass().getName())); StackTraceElement ste = e.getStackTrace()[i];
elog(String.format(errM, e.getMessage())); elog(String.format(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName() == null ? "未知" : ste.getFileName(), ste.getLineNumber()));
elog(errInfo); }
int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length; if (debug) {
for (int i = 0; i < l; i++) { Log.console(devInfo);
StackTraceElement ste = e.getStackTrace()[i]; e.printStackTrace();
elog(String.format(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName() == null ? "未知" : ste.getFileName(), ste.getLineNumber())); }
} }
if (debug) {
Log.console(devInfo); public static void reset(String pname) {
e.printStackTrace(); monitor.put(pname, 0L);
} task.put(pname, 0L);
} event.put(pname, 0L);
cmd.put(pname, 0L);
public static void reset(String pname) { }
monitor.put(pname, 0L);
task.put(pname, 0L); public static void sendError(CommandSender sender, Plugin plugin, Throwable e) {
event.put(pname, 0L); sender.sendMessage(errMsg);
cmd.put(pname, 0L); 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 sendError(CommandSender sender, Plugin plugin, Throwable e) { }
sender.sendMessage(errMsg);
sender.sendMessage(String.format(errP, plugin.getName())); /**
sender.sendMessage(String.format(errN, e.getClass().getName())); * 使 Mapvalue
sender.sendMessage(String.format(errM, e.getMessage())); *
} * @param oriMap
* @return
/** */
* 使 Mapvalue public static Map<String, Long> sortMapByValue(Map<String, Long> oriMap) {
* if (oriMap == null || oriMap.isEmpty()) { return oriMap; }
* @param oriMap Map<String, Long> sortedMap = new LinkedHashMap<>();
* @return List<Map.Entry<String, Long>> entryList = new ArrayList<>(oriMap.entrySet());
*/ entryList.sort(new MonitorComparator());
public static Map<String, Long> sortMapByValue(Map<String, Long> oriMap) { Iterator<Map.Entry<String, Long>> iter = entryList.iterator();
if (oriMap == null || oriMap.isEmpty()) { return oriMap; } Entry<String, Long> tmpEntry;
Map<String, Long> sortedMap = new LinkedHashMap<>(); while (iter.hasNext()) {
List<Map.Entry<String, Long>> entryList = new ArrayList<>(oriMap.entrySet()); tmpEntry = iter.next();
Collections.sort(entryList, new MonitorComparator()); sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
Iterator<Map.Entry<String, Long>> iter = entryList.iterator(); }
Entry<String, Long> tmpEntry; return sortedMap;
while (iter.hasNext()) { }
tmpEntry = iter.next();
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue()); @SafeVarargs
} private static void add(String pname, long time, Map<String, Long>... maps) {
return sortedMap; totalTime += time;
} for (Map<String, Long> map : maps) {
map.put(pname, map.get(pname) + time);
@SafeVarargs }
private static void add(String pname, long time, Map<String, Long>... maps) { }
totalTime += time;
for (Map<String, Long> map : maps) { private static long sum(Collection<? extends Long> numbers) {
map.put(pname, map.get(pname) + time); int result = 0;
} for (Long num : numbers) {
} result += num;
}
private static long sum(Collection<? extends Long> numbers) { return result;
int result = 0; }
for (Long num : numbers) {
result += num; public static class MonitorInfo {
} public double monitor;
return result; public double cmd;
} public double event;
public double task;
public static class MonitorInfo {
public double monitor; public MonitorInfo(double monitor, double cmd, double event, double task) {
public double cmd; this.monitor = monitor;
public double event; this.cmd = cmd;
public double task; this.event = event;
this.task = task;
public MonitorInfo(double monitor, double cmd, double event, double task) { }
this.monitor = monitor; }
this.cmd = cmd;
this.event = event; static class MonitorComparator implements Comparator<Map.Entry<String, Long>> {
this.task = task; @Override
} public int compare(Entry<String, Long> o1, Entry<String, Long> o2) {
} return o2.getValue().compareTo(o1.getValue());
}
static class MonitorComparator implements Comparator<Map.Entry<String, Long>> { }
@Override }
public int compare(Entry<String, Long> o1, Entry<String, Long> o2) {
return o2.getValue().compareTo(o1.getValue());
}
}
}

View File

@ -1,16 +1,19 @@
############################ ############################
### 能耗监控系统配置文件 ### 能耗监控系统配置文件
############################ ############################
#配置版本号 请勿修改!!! #配置版本号 请勿修改!!!
Version: 1.3 Version: 1.4
#是否开启 #是否开启
Enable: true Enable: true
#是否显示开发人员信息 #是否显示开发人员信息
Debug: false Debug: false
#是否保存Lag日志到文件 #是否保存Lag日志到文件
LogToFile: true LogToFile: true
#忽略检测列表 #忽略检测列表
Ignore: Ignore:
- PluginHelper - PluginHelper
#忽略报错的插件列表
IgnoreError:
- PluginHelper