feat: 添加能耗监控系统

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-07-06 20:51:25 +08:00
parent 4e1304d912
commit 7985ff3433
13 changed files with 497 additions and 54 deletions

View File

@ -8,6 +8,7 @@ import java.util.TimerTask;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import cn.citycraft.CommonData.UpdatePlugin; import cn.citycraft.CommonData.UpdatePlugin;
@ -15,6 +16,7 @@ import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.utils.VersionChecker; import cn.citycraft.PluginHelper.utils.VersionChecker;
import pw.yumc.Yum.api.YumAPI; import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.commands.FileCommand; import pw.yumc.Yum.commands.FileCommand;
import pw.yumc.Yum.commands.MonitorCommand;
import pw.yumc.Yum.commands.NetCommand; import pw.yumc.Yum.commands.NetCommand;
import pw.yumc.Yum.commands.YumCommand; import pw.yumc.Yum.commands.YumCommand;
import pw.yumc.Yum.listeners.PluginNetworkListener; import pw.yumc.Yum.listeners.PluginNetworkListener;
@ -43,6 +45,9 @@ public class Yum extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
NetworkManager.unregister(); NetworkManager.unregister();
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
YumAPI.uninject(plugin);
}
} }
@Override @Override
@ -54,6 +59,7 @@ public class Yum extends JavaPlugin {
initCommands(); initCommands();
initListeners(); initListeners();
initRunnable(); initRunnable();
initInject();
new VersionChecker(this); new VersionChecker(this);
YumAPI.updaterepo(Bukkit.getConsoleSender()); YumAPI.updaterepo(Bukkit.getConsoleSender());
YumAPI.updatecheck(Bukkit.getConsoleSender()); YumAPI.updatecheck(Bukkit.getConsoleSender());
@ -76,6 +82,14 @@ public class Yum extends JavaPlugin {
new YumCommand(this); new YumCommand(this);
new NetCommand(this); new NetCommand(this);
new FileCommand(this); new FileCommand(this);
new MonitorCommand(this);
}
private void initInject() {
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
YumAPI.inject(plugin);
}
PluginKit.scp("§a性能监控系统已启用...");
} }
/** /**

View File

@ -12,6 +12,7 @@ import org.bukkit.plugin.Plugin;
import cn.citycraft.CommonData.UpdatePlugin; import cn.citycraft.CommonData.UpdatePlugin;
import cn.citycraft.PluginHelper.kit.PKit; import cn.citycraft.PluginHelper.kit.PKit;
import pw.yumc.Yum.inject.CommandInjector;
import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.Yum.managers.DownloadManager; import pw.yumc.Yum.managers.DownloadManager;
import pw.yumc.Yum.managers.PluginsManager; import pw.yumc.Yum.managers.PluginsManager;
@ -31,6 +32,20 @@ public class YumAPI {
private static RepositoryManager repo; private static RepositoryManager repo;
private static boolean runlock = false; private static boolean runlock = false;
/**
* 初始化Yum管理中心
*
* @param plugin
* 插件实体
*/
public YumAPI() {
YumAPI.main = PKit.instance;
plugman = new PluginsManager(main);
download = new DownloadManager(main);
repo = new RepositoryManager(main);
plugman.addIgnore(ConfigManager.i().getIgnoreList());
}
/** /**
* 删除插件 * 删除插件
* *
@ -81,6 +96,18 @@ public class YumAPI {
return ulist; return ulist;
} }
/**
* 注入性能监控器
*
* @param plugin
* 插件
*/
public static void inject(final Plugin plugin) {
CommandInjector.inject(plugin);
// ListenerInjector.inject(plugin);
// TaskInjector.inject(plugin);
}
/** /**
* 安装新插件 * 安装新插件
* *
@ -175,6 +202,18 @@ public class YumAPI {
plugman.reload(plugin); plugman.reload(plugin);
} }
/**
* 取消注入
*
* @param plugin
* 插件
*/
public static void uninject(final Plugin plugin) {
CommandInjector.uninject(plugin);
// ListenerInjector.uninject(plugin);
// TaskInjector.uninject(plugin);
}
/** /**
* 卸载插件 * 卸载插件
* *
@ -239,9 +278,10 @@ public class YumAPI {
sender.sendMessage("§d开始更新服务器可更新插件"); sender.sendMessage("§d开始更新服务器可更新插件");
for (final Plugin updateplugin : ulist) { for (final Plugin updateplugin : ulist) {
sender.sendMessage("§d一键更新: §a开始更新" + updateplugin.getName() + "!"); sender.sendMessage("§d一键更新: §a开始更新" + updateplugin.getName() + "!");
if (!updatefromyum(sender, updateplugin, null, true)) if (!updatefromyum(sender, updateplugin, null, true)) {
failed++; failed++;
} }
}
if (failed != 0) { if (failed != 0) {
sender.sendMessage("§d一键更新: §c升级过程中 §4" + failed + " §c个插件更新失败!"); sender.sendMessage("§d一键更新: §c升级过程中 §4" + failed + " §c个插件更新失败!");
} }
@ -354,18 +394,4 @@ public class YumAPI {
public static void upgrade(final CommandSender sender, final Plugin plugin) { public static void upgrade(final CommandSender sender, final Plugin plugin) {
plugman.upgrade(sender, plugin); plugman.upgrade(sender, plugin);
} }
/**
* 初始化Yum管理中心
*
* @param plugin
* 插件实体
*/
public YumAPI() {
YumAPI.main = PKit.instance;
plugman = new PluginsManager(main);
download = new DownloadManager(main);
repo = new RepositoryManager(main);
plugman.addIgnore(ConfigManager.i().getIgnoreList());
}
} }

View File

@ -12,7 +12,6 @@ import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
import cn.citycraft.PluginHelper.utils.FileUtil; import cn.citycraft.PluginHelper.utils.FileUtil;
import pw.yumc.Yum.Yum; import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI; import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.managers.DownloadManager;
/** /**
* File命令基类 * File命令基类
@ -22,11 +21,9 @@ import pw.yumc.Yum.managers.DownloadManager;
*/ */
public class FileCommand implements HandlerCommands { public class FileCommand implements HandlerCommands {
Yum plugin; Yum plugin;
DownloadManager dl;
public FileCommand(final Yum yum) { public FileCommand(final Yum yum) {
plugin = yum; plugin = yum;
dl = YumAPI.getDownload();
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file"); final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true)); cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
cmdhandler.registerCommands(this); cmdhandler.registerCommands(this);
@ -64,9 +61,9 @@ public class FileCommand implements HandlerCommands {
if (args.length == 2) { if (args.length == 2) {
file = new File(args[1]); file = new File(args[1]);
} else { } else {
file = new File(Bukkit.getUpdateFolderFile(), dl.getFileName(urlstr)); file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(urlstr));
} }
dl.run(e.getSender(), urlstr, file); YumAPI.getDownload().run(e.getSender(), urlstr, file);
} }
@HandlerCommand(name = "ls", aliases = { "l" }, description = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>") @HandlerCommand(name = "ls", aliases = { "l" }, description = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>")

View File

@ -0,0 +1,129 @@
package pw.yumc.Yum.commands;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
import org.bukkit.command.TabCompleter;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitTask;
import cn.citycraft.PluginHelper.commands.HandlerCommand;
import cn.citycraft.PluginHelper.commands.HandlerCommands;
import cn.citycraft.PluginHelper.commands.HandlerTabComplete;
import cn.citycraft.PluginHelper.commands.InvokeCommandEvent;
import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.utils.StrKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.inject.CommandInjector;
import pw.yumc.Yum.inject.TaskInjector;
/**
*
* @since 2016年7月6日 下午5:13:32
* @author
*/
public class MonitorCommand implements HandlerCommands {
Yum main;
public MonitorCommand(final Yum yum) {
main = yum;
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
cmdhandler.registerCommands(this);
}
@HandlerCommand(name = "a")
public void a(final InvokeCommandEvent e) {
}
@HandlerCommand(name = "cmd", minimumArguments = 1, possibleArguments = "插件名称")
public void cmd(final InvokeCommandEvent e) {
final String pname = e.getArgs()[0];
final CommandSender sender = e.getSender();
if (Bukkit.getPluginManager().getPlugin(pname) == null) {
sender.sendMessage("§c插件不存在!");
return;
}
final PluginManager pluginManager = Bukkit.getPluginManager();
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
sender.sendMessage("§6插件 §b" + pname + " §6的命令能耗如下!");
final Map<String, Command> temp = new HashMap<>();
for (final Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
final PluginCommand pluginCommand = (PluginCommand) command;
final Plugin plugin = pluginCommand.getPlugin();
if (plugin.getName().equalsIgnoreCase(pname)) {
temp.put(command.getName(), command);
}
}
}
for (final Entry<String, Command> command : temp.entrySet()) {
final CommandExecutor executor = Reflect.on(command.getValue()).get("executor");
if (executor instanceof CommandInjector) {
final CommandInjector injected = (CommandInjector) executor;
final StringBuffer str = new StringBuffer();
str.append("§6- §e" + command.getValue().getName() + " ");
str.append(String.format("§6总耗时: §a%.2f秒 ", injected.totalTime / 1000000.0));
str.append("§6执行次数: §b" + injected.count + "");
if (injected.count != 0) {
str.append(String.format("§6平均耗时: §d%.2f秒!", injected.totalTime / 1000000.0 / injected.count));
}
e.getSender().sendMessage(str.toString());
} else {
final TabCompleter completer = Reflect.on(command).get("completer");
final CommandInjector commandInjector = new CommandInjector(executor, completer);
Reflect.on(command).set("executor", commandInjector);
Reflect.on(command).set("completer", commandInjector);
}
}
}
@HandlerTabComplete()
public List<String> listtab(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
return StrKit.copyPartialMatches(args[1], YumAPI.getPlugman().getPluginNames(false), new ArrayList<String>());
}
@HandlerCommand(name = "task")
public void task(final InvokeCommandEvent e) {
final String pname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
if (plugin == null) {
sender.sendMessage("§c插件不存在!");
return;
}
final List<BukkitTask> pendingTasks = Bukkit.getScheduler().getPendingTasks();
sender.sendMessage("§6插件 §b" + pname + " §6的任务能耗如下!");
for (final BukkitTask pendingTask : pendingTasks) {
final Runnable task = Reflect.on(pendingTask).get("task");
if (task instanceof TaskInjector) {
final TaskInjector executor = (TaskInjector) task;
final StringBuffer str = new StringBuffer();
str.append("§6- §e" + task.getClass().getSimpleName() + " ");
str.append(String.format("§6总耗时: §a%.2f秒 ", executor.totalTime / 1000000.0));
str.append("§6执行次数: §b" + executor.count + "");
if (executor.count != 0) {
str.append(String.format("§6平均耗时: §d%.2f秒!", executor.totalTime / 1000000.0 / executor.count));
}
e.getSender().sendMessage(str.toString());
} else {
final TaskInjector taskInjector = new TaskInjector(task);
Reflect.on(pendingTask).set("task", taskInjector);
}
}
}
}

View File

@ -27,8 +27,6 @@ import cn.citycraft.PluginHelper.utils.StrKit;
import pw.yumc.Yum.Yum; import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI; import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.Yum.managers.PluginsManager;
import pw.yumc.Yum.managers.RepositoryManager;
import pw.yumc.Yum.models.RepoSerialization.Repositories; import pw.yumc.Yum.models.RepoSerialization.Repositories;
/** /**
@ -39,13 +37,9 @@ import pw.yumc.Yum.models.RepoSerialization.Repositories;
*/ */
public class YumCommand implements HandlerCommands, Listener { public class YumCommand implements HandlerCommands, Listener {
Yum main; Yum main;
RepositoryManager repo;
PluginsManager plugman;
public YumCommand(final Yum yum) { public YumCommand(final Yum yum) {
main = yum; main = yum;
repo = YumAPI.getRepo();
plugman = YumAPI.getPlugman();
Bukkit.getPluginManager().registerEvents(this, yum); Bukkit.getPluginManager().registerEvents(this, yum);
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum"); final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum");
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false)); cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false));
@ -59,7 +53,7 @@ public class YumCommand implements HandlerCommands, Listener {
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) { if (plugin != null) {
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15); final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (plugman.deletePlugin(sender, plugin)) { if (YumAPI.getPlugman().deletePlugin(sender, plugin)) {
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!"); sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
} else { } else {
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!"); sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
@ -91,7 +85,7 @@ public class YumCommand implements HandlerCommands, Listener {
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) { if (plugin != null) {
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15); final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (plugman.fullDeletePlugin(sender, plugin)) { if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) {
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!"); sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
} else { } else {
sender.sendMessage("§c删除: §c插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!"); sender.sendMessage("§c删除: §c插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
@ -134,7 +128,7 @@ public class YumCommand implements HandlerCommands, Listener {
sender.sendMessage("§6 - §a" + perm.getName() + "§6 - §e" + (perm.getDescription().isEmpty() ? "无描述" : perm.getDescription())); sender.sendMessage("§6 - §a" + perm.getName() + "§6 - §e" + (perm.getDescription().isEmpty() ? "无描述" : perm.getDescription()));
} }
} }
sender.sendMessage("§6插件物理路径: §3" + plugman.getPluginFile(plugin).getAbsolutePath()); sender.sendMessage("§6插件物理路径: §3" + YumAPI.getPlugman().getPluginFile(plugin).getAbsolutePath());
} else { } else {
sender.sendMessage(pnf(pluginname)); sender.sendMessage(pnf(pluginname));
} }
@ -167,7 +161,7 @@ public class YumCommand implements HandlerCommands, Listener {
final CommandSender sender = e.getSender(); final CommandSender sender = e.getSender();
sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: "); sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: ");
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
sender.sendMessage("§6- " + plugman.getFormattedName(plugin, true)); sender.sendMessage("§6- " + YumAPI.getPlugman().getFormattedName(plugin, true));
} }
} }
@ -175,16 +169,16 @@ public class YumCommand implements HandlerCommands, Listener {
public List<String> listtab(final InvokeCommandEvent e) { public List<String> listtab(final InvokeCommandEvent e) {
final String[] args = e.getArgs(); final String[] args = e.getArgs();
if (args[0].equalsIgnoreCase("install") || args[0].equalsIgnoreCase("i")) { if (args[0].equalsIgnoreCase("install") || args[0].equalsIgnoreCase("i")) {
return StrKit.copyPartialMatches(args[1], repo.getAllPluginName(), new ArrayList<String>()); return StrKit.copyPartialMatches(args[1], YumAPI.getRepo().getAllPluginName(), new ArrayList<String>());
} else if (args[0].equalsIgnoreCase("repo")) { } else if (args[0].equalsIgnoreCase("repo")) {
if (args.length == 2) { if (args.length == 2) {
return StrKit.copyPartialMatches(args[1], Arrays.asList(new String[] { "add", "all", "list", "delall", "clean", "update", "del" }), new ArrayList<String>()); return StrKit.copyPartialMatches(args[1], Arrays.asList(new String[] { "add", "all", "list", "delall", "clean", "update", "del" }), new ArrayList<String>());
} }
if (args.length == 3 && (args[1] == "add" || args[1] == "del")) { if (args.length == 3 && (args[1] == "add" || args[1] == "del")) {
return StrKit.copyPartialMatches(args[2], repo.getRepos().keySet(), new ArrayList<String>()); return StrKit.copyPartialMatches(args[2], YumAPI.getRepo().getRepos().keySet(), new ArrayList<String>());
} }
} else { } else {
return StrKit.copyPartialMatches(args[1], plugman.getPluginNames(false), new ArrayList<String>()); return StrKit.copyPartialMatches(args[1], YumAPI.getPlugman().getPluginNames(false), new ArrayList<String>());
} }
return null; return null;
} }
@ -195,7 +189,7 @@ public class YumCommand implements HandlerCommands, Listener {
final String pluginname = e.getArgs()[0]; final String pluginname = e.getArgs()[0];
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin == null) { if (plugin == null) {
plugman.load(sender, pluginname); YumAPI.getPlugman().load(sender, pluginname);
} else { } else {
sender.sendMessage("§c错误: §a插件 §b" + pluginname + " §c已加载到服务器!"); sender.sendMessage("§c错误: §a插件 §b" + pluginname + " §c已加载到服务器!");
} }
@ -218,12 +212,12 @@ public class YumCommand implements HandlerCommands, Listener {
} }
final String pluginname = e.getArgs()[0]; final String pluginname = e.getArgs()[0];
if (pluginname.equalsIgnoreCase("all") || pluginname.equalsIgnoreCase("*")) { if (pluginname.equalsIgnoreCase("all") || pluginname.equalsIgnoreCase("*")) {
plugman.reloadAll(sender); YumAPI.getPlugman().reloadAll(sender);
return; return;
} }
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) { if (plugin != null) {
plugman.reload(sender, plugin); YumAPI.getPlugman().reload(sender, plugin);
} else { } else {
sender.sendMessage(pnf(pluginname)); sender.sendMessage(pnf(pluginname));
} }
@ -240,8 +234,8 @@ public class YumCommand implements HandlerCommands, Listener {
switch (cmd) { switch (cmd) {
case "add": case "add":
if (args.length == 2) { if (args.length == 2) {
if (repo.addRepositories(sender, args[1])) { if (YumAPI.getRepo().addRepositories(sender, args[1])) {
final String reponame = repo.getRepoCache(args[1]).name; final String reponame = YumAPI.getRepo().getRepoCache(args[1]).name;
sender.sendMessage("§6仓库: §a源仓库 §e" + reponame + " §a的插件信息已缓存!"); sender.sendMessage("§6仓库: §a源仓库 §e" + reponame + " §a的插件信息已缓存!");
} else { } else {
sender.sendMessage("§6仓库: §c源地址未找到仓库信息或当前地址已缓存!"); sender.sendMessage("§6仓库: §c源地址未找到仓库信息或当前地址已缓存!");
@ -252,9 +246,9 @@ public class YumCommand implements HandlerCommands, Listener {
break; break;
case "del": case "del":
if (args.length == 2) { if (args.length == 2) {
final Repositories delrepo = repo.getRepoCache(args[1]); final Repositories delrepo = YumAPI.getRepo().getRepoCache(args[1]);
if (delrepo != null) { if (delrepo != null) {
repo.delRepositories(sender, args[1]); YumAPI.getRepo().delRepositories(sender, args[1]);
sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!"); sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!");
} else { } else {
sender.sendMessage("§6仓库: §c源地址未找到!"); sender.sendMessage("§6仓库: §c源地址未找到!");
@ -264,23 +258,23 @@ public class YumCommand implements HandlerCommands, Listener {
} }
break; break;
case "delall": case "delall":
repo.getRepoCache().getRepos().clear(); YumAPI.getRepo().getRepoCache().getRepos().clear();
sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!"); sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!");
break; break;
case "list": case "list":
sender.sendMessage("§6仓库: §b缓存的插件信息如下 "); sender.sendMessage("§6仓库: §b缓存的插件信息如下 ");
StrKit.sendStringArray(sender, repo.getAllPluginsInfo()); StrKit.sendStringArray(sender, YumAPI.getRepo().getAllPluginsInfo());
break; break;
case "all": case "all":
sender.sendMessage("§6仓库: §b缓存的仓库信息如下 "); sender.sendMessage("§6仓库: §b缓存的仓库信息如下 ");
StrKit.sendStringArray(sender, repo.getRepoCache().getAllRepoInfo()); StrKit.sendStringArray(sender, YumAPI.getRepo().getRepoCache().getAllRepoInfo());
break; break;
case "clean": case "clean":
repo.clean(); YumAPI.getRepo().clean();
sender.sendMessage("§6仓库: §a缓存的插件信息已清理!"); sender.sendMessage("§6仓库: §a缓存的插件信息已清理!");
break; break;
case "update": case "update":
repo.updateRepositories(sender); YumAPI.getRepo().updateRepositories(sender);
sender.sendMessage("§6仓库: §a仓库缓存数据已更新!"); sender.sendMessage("§6仓库: §a仓库缓存数据已更新!");
break; break;
} }
@ -335,7 +329,7 @@ public class YumCommand implements HandlerCommands, Listener {
final CommandSender sender = e.getSender(); final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) { if (plugin != null) {
plugman.unload(sender, plugin); YumAPI.getPlugman().unload(sender, plugin);
} else { } else {
sender.sendMessage(pnf(pluginname)); sender.sendMessage(pnf(pluginname));
} }
@ -347,7 +341,7 @@ public class YumCommand implements HandlerCommands, Listener {
final CommandSender sender = e.getSender(); final CommandSender sender = e.getSender();
switch (args.length) { switch (args.length) {
case 0: case 0:
repo.updateRepositories(sender); YumAPI.getRepo().updateRepositories(sender);
sender.sendMessage("§6仓库: §a仓库缓存数据已更新!"); sender.sendMessage("§6仓库: §a仓库缓存数据已更新!");
break; break;
case 1: case 1:
@ -393,7 +387,7 @@ public class YumCommand implements HandlerCommands, Listener {
@Override @Override
public void run() { public void run() {
if (args.length == 0) { if (args.length == 0) {
plugman.upgrade(sender); YumAPI.getPlugman().upgrade(sender);
} else { } else {
final String pluginname = args[0]; final String pluginname = args[0];
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname); final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);

View File

@ -0,0 +1,108 @@
package pw.yumc.Yum.inject;
import java.util.List;
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;
import org.bukkit.command.TabCompleter;
import org.bukkit.command.TabExecutor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.kit.PluginKit;
public class CommandInjector implements TabExecutor {
private final CommandExecutor originalExecutor;
private final TabCompleter originalCompleter;
public long totalTime;
public long count;
public CommandInjector(final CommandExecutor originalCommandExecutor, final TabCompleter originalTabCompleter) {
this.originalExecutor = originalCommandExecutor;
this.originalCompleter = originalTabCompleter;
}
public static void inject(final Plugin toInjectPlugin) {
final PluginManager pluginManager = Bukkit.getPluginManager();
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
for (final Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
final PluginCommand pluginCommand = (PluginCommand) command;
final Plugin plugin = pluginCommand.getPlugin();
if (plugin.equals(toInjectPlugin)) {
final CommandExecutor executor = Reflect.on(command).get("executor");
if (executor instanceof CommandInjector) {
return;
}
final TabCompleter completer = Reflect.on(command).get("completer");
final CommandInjector commandInjector = new CommandInjector(executor, completer);
Reflect.on(command).set("executor", commandInjector);
Reflect.on(command).set("completer", commandInjector);
}
}
}
PluginKit.scp("§a注入命令性能监控到 " + toInjectPlugin.getName());
}
public static void uninject(final Plugin toUninject) {
final PluginManager pluginManager = Bukkit.getPluginManager();
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
for (final Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
final PluginCommand pluginCommand = (PluginCommand) command;
final Plugin plugin = pluginCommand.getPlugin();
if (plugin.equals(toUninject)) {
final CommandExecutor executor = Reflect.on(command).get("executor");
if (executor instanceof CommandInjector) {
final CommandInjector injected = (CommandInjector) executor;
Reflect.on(command).set("executor", injected.getOriginalExecutor());
}
final TabCompleter completer = Reflect.on(command).get("completer");
if (completer instanceof CommandInjector) {
final CommandInjector injected = (CommandInjector) completer;
Reflect.on(command).set("completer", injected.getOriginalCompleter());
}
}
}
}
}
public TabCompleter getOriginalCompleter() {
return originalCompleter;
}
public CommandExecutor getOriginalExecutor() {
return originalExecutor;
}
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
final long start = System.nanoTime();
// todo add a more aggressive 10 ms cpu sample
final boolean result = originalExecutor.onCommand(sender, command, label, args);
final long end = System.nanoTime();
totalTime += end - start;
count++;
return result;
}
@Override
public List<String> onTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
final long start = System.nanoTime();
// todo add a more aggressive 10 ms cpu sample
final List<String> result = originalCompleter.onTabComplete(sender, command, alias, args);
final long end = System.nanoTime();
totalTime += end - start;
count++;
return result;
}
}

View File

@ -0,0 +1,61 @@
package pw.yumc.Yum.inject;
import java.util.List;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
public class ListenerInjector implements EventExecutor {
private final EventExecutor originalExecutor;
public long totalTime;
public long count;
public ListenerInjector(final EventExecutor originalExecutor) {
this.originalExecutor = originalExecutor;
}
public static void inject(final Plugin plugin) {
final List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (final RegisteredListener listener : listeners) {
final EventExecutor originalExecutor = Reflect.on(listener).get("executor");
final ListenerInjector listenerInjector = new ListenerInjector(originalExecutor);
Reflect.on(listener).set("executor", listenerInjector);
}
}
public static void uninject(final Plugin plugin) {
final List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (final RegisteredListener listener : listeners) {
final ListenerInjector executor = Reflect.on(listener).get("executor");
Reflect.on(listener).set("executor", executor.getOriginalExecutor());
}
}
@Override
public void execute(final Listener listener, final Event event) throws EventException {
if (!event.isAsynchronous()) {
final long start = System.nanoTime();
// todo add a more aggressive 10 ms cpu sample
originalExecutor.execute(listener, event);
final long end = System.nanoTime();
totalTime += end - start;
count++;
} else {
originalExecutor.execute(listener, event);
}
}
public EventExecutor getOriginalExecutor() {
return originalExecutor;
}
}

View File

@ -0,0 +1,64 @@
package pw.yumc.Yum.inject;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
public class TaskInjector implements Runnable {
private final Runnable originalTask;
public long totalTime;
public long count;
public TaskInjector(final Runnable originalTask) {
this.originalTask = originalTask;
}
// sadly it works only with interval tasks
// for single runs we would have to register a dynamic proxy
public static void inject(final Plugin plugin) {
final BukkitScheduler scheduler = Bukkit.getScheduler();
final List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
for (final BukkitTask pendingTask : pendingTasks) {
// we could ignore async tasks for now
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
final Runnable originalTask = Reflect.on(pendingTask).get("task");
final TaskInjector taskInjector = new TaskInjector(originalTask);
Reflect.on(pendingTask).set("task", taskInjector);
}
}
}
public static void uninject(final Plugin plugin) {
final BukkitScheduler scheduler = Bukkit.getScheduler();
final List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
for (final BukkitTask pendingTask : pendingTasks) {
// we could ignore async tasks for now
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
final TaskInjector originalTask = Reflect.on(pendingTask).get("task");
Reflect.on(pendingTask).set("task", originalTask.getOriginalTask());
}
}
}
public Runnable getOriginalTask() {
return originalTask;
}
@Override
public void run() {
final long start = System.nanoTime();
// todo add a more aggressive 10 ms cpu sample
originalTask.run();
final long end = System.nanoTime();
totalTime += end - start;
count++;
}
}

View File

@ -0,0 +1,32 @@
package pw.yumc.Yum.listeners;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import cn.citycraft.PluginHelper.kit.PKit;
import pw.yumc.Yum.api.YumAPI;
/**
*
* @since 2016年7月6日 下午6:44:16
* @author
*/
public class PluginListener implements Listener {
public PluginListener() {
Bukkit.getPluginManager().registerEvents(this, PKit.i());
}
@EventHandler
public void onPluginDisable(final PluginDisableEvent e) {
YumAPI.uninject(e.getPlugin());
}
@EventHandler
public void onPluginEnable(final PluginEnableEvent e) {
YumAPI.inject(e.getPlugin());
}
}

View File

@ -15,7 +15,9 @@ import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.Plugin;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.Yum; import pw.yumc.Yum.Yum;
/** /**
@ -87,7 +89,10 @@ public class ThreadSafetyListener implements Listener {
private void checkSafety(final Event eventType) { private void checkSafety(final Event eventType) {
if (Yum.mainThread != null && Thread.currentThread() != Yum.mainThread && !eventType.isAsynchronous()) { if (Yum.mainThread != null && Thread.currentThread() != Yum.mainThread && !eventType.isAsynchronous()) {
final String eventName = eventType.getEventName(); final String eventName = eventType.getEventName();
throw new IllegalAccessError("[Yum 线程安全]: 请勿异步调用一个同步事件 " + eventName); final Plugin plugin = PluginKit.getOperatePlugin();
if (plugin != null) {
throw new IllegalAccessError("[Yum 线程安全]: 请勿异步调用一个同步事件 " + eventName + " 操作插件: " + plugin.getName());
}
} }
} }
} }

View File

@ -6,13 +6,23 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import cn.citycraft.PluginHelper.PluginHelperLogger; import cn.citycraft.PluginHelper.PluginHelperLogger;
import cn.citycraft.PluginHelper.kit.PKit;
import cn.citycraft.PluginHelper.utils.IOUtil; import cn.citycraft.PluginHelper.utils.IOUtil;
import pw.yumc.Yum.models.RepoSerialization.Plugin; import pw.yumc.Yum.models.RepoSerialization.Plugin;
import pw.yumc.Yum.models.RepoSerialization.TagInfo; import pw.yumc.Yum.models.RepoSerialization.TagInfo;
import pw.yumc.Yum.models.RepoSerialization.URLType; import pw.yumc.Yum.models.RepoSerialization.URLType;
public class PluginInfo implements Serializable { public class PluginInfo implements Serializable {
public static final String NMSVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; public static String NMSVersion;
static {
try {
NMSVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} catch (final Exception e) {
PKit.i().getLogger().warning("服务器NMS解析失败: " + Bukkit.getServer().getClass().getPackage().getName());
NMSVersion = "NONMS";
}
}
public String branch; public String branch;
public String name; public String name;
@ -78,10 +88,7 @@ public class PluginInfo implements Serializable {
* @return 更新地址 * @return 更新地址
*/ */
public String getMavenUrl(final String ver) { public String getMavenUrl(final String ver) {
return String.format(url + (url.endsWith("/") ? "" : "/") + "%1$s/%2$s/%3$s/%2$s-%3$s.jar", return String.format(url + (url.endsWith("/") ? "" : "/") + "%1$s/%2$s/%3$s/%2$s-%3$s.jar", plugin.groupId.replace(".", "/"), plugin.artifactId, (ver == null || ver.isEmpty()) ? plugin.version : ver);
plugin.groupId.replace(".", "/"),
plugin.artifactId,
(ver == null || ver.isEmpty()) ? plugin.version : ver);
} }
public String getUrl(final CommandSender sender, final String version) { public String getUrl(final CommandSender sender, final String version) {

View File

View File

@ -30,6 +30,12 @@ commands:
usage: §6使用§a/security help§6查看帮助! usage: §6使用§a/security help§6查看帮助!
permission: security.use permission: security.use
permission-message: §c你没有 <permission> 的权限来执行此命令! permission-message: §c你没有 <permission> 的权限来执行此命令!
monitor:
description: MC系统监控命令
aliases: [m]
usage: §6使用§a/monitor help§6查看帮助!
permission: monitor.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
permissions: permissions:
yum.use: yum.use:
description: 插件管理系统使用权限! description: 插件管理系统使用权限!