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