Compare commits

..

No commits in common. "master" and "2.6" have entirely different histories.
master ... 2.6

39 changed files with 2332 additions and 3214 deletions

31
.classpath Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

3
.gitignore vendored
View File

@ -1,7 +1,4 @@
# Eclipse stuff
/.project
/.classpath
/.factorypath
/.settings
# netbeans

23
.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Yum</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

178
pom.xml
View File

@ -1,71 +1,107 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>Yum</artifactId>
<version>2.9.5</version>
<packaging>jar</packaging>
<description>Minecraft 服务器插件管理系统</description>
<parent>
<groupId>pw.yumc</groupId>
<artifactId>minecraft-plugin-parent</artifactId>
<version>1.0</version>
<relativePath/>
</parent>
<properties>
<update.description>§a补丁包 2.9.5 版本</update.description>
<update.changes>
§621-10-28 §afeat: 新增屏蔽插件报错功能;
§620-03-25 §afeat: 优化 当前插件获取逻辑;
§620-03-25 §c修复: Paper HikariPool 不兼容问题;
§619-09-30 §c修复: 自动补全报错的问题;
§619-08-28 §c修复: knownCommands 不兼容;
      §c修复: async event on primary thread;
</update.changes>
<update.changelog>
§619-08-26 §c修复: 修复不兼容 1.14.4 的问题;
§619-02-23 §c修复: 修复不兼容 1.13 的问题;
§617-07-29 §cfix: 修复不兼容 1.12 的问题;
§6- §cfix: §7修复仓库数据读取错误的问题;
§6- §cfix: §7修复一个tab补全产生的错误
§6- §btip: §a本插件最后一次更新 2.7.8 版本;
§6- §afeat: §7线程中断只显示一次调试信息;
§6- §afeat: §7更新线程检查 添加调试;
§6- §afeat: §7修改显示前缀;
§6- §afeat: §7更新类库版本 完善网络调试;
§6- §drefactor: §7使用新类库;
§6- §afeat: §7使用新版本API;
§6- §afeat: §7去除加载器注入 异步获取主线程;
§6- §afeat: §7添加网络状态详细错误;
§6- §afeat: §7新增307跳转支持;
§6- §cfix: §7修复lasterror命令显示问题;
§6- §afeat: §7使用SimpleJson解析仓库数据;
§6- §afeat: §7使用新的类库处理Tellraw;
§6- §cfix: §7当仓库未找到插件时没有提示的BUG;
</update.changelog>
<env.GIT_COMMIT>DEV</env.GIT_COMMIT>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>pw.yumc</groupId>
<artifactId>BukkitInjectedTools</artifactId>
<type>jar</type>
<version>[1.1,)</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pw.yumc</groupId>
<artifactId>Yum</artifactId>
<version>2.6</version>
<name>Yum</name>
<description>Minecraft 服务器插件管理系统</description>
<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>cn.citycraft:PluginHelper</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>cn.citycraft.PluginHelper</pattern>
<shadedPattern>${project.groupId}.${project.artifactId}</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<ciManagement>
<system>Jenkins</system>
<url>http://ci.yumc.pw/job/${project.artifactId}/</url>
</ciManagement>
<properties>
<update.description>&amp;a全新 2.X 版本 更多守护与优化</update.description>
<update.changes>
&amp;b2.6 &amp;6- &amp;a添加能耗监控系统 事件错误监控...;
&amp;b2.5 &amp;6- &amp;d修复主线程守护系统错误...;
&amp;b2.4 &amp;6- &amp;c修复重载插件导致线程安全错误的问题...;
</update.changes>
<env.GIT_COMMIT>DEBUG</env.GIT_COMMIT>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>yumc-repo</id>
<url>http://repo.yumc.pw/content/groups/public/</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>jtb</id>
<name>YUMC</name>
<url>http://repo.yumc.pw/content/repositories/yumcenter/</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<type>jar</type>
<version>1.10.2-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.citycraft</groupId>
<artifactId>PluginHelper</artifactId>
<type>jar</type>
<version>1.0</version>
</dependency>
<dependency>
<groupId>pw.yumc</groupId>
<artifactId>BukkitInjectedTools</artifactId>
<type>jar</type>
<version>1.0</version>
</dependency>
</dependencies>
</project>

View File

@ -10,6 +10,9 @@ import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import cn.citycraft.CommonData.UpdatePlugin;
import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.utils.VersionChecker;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.commands.FileCommand;
import pw.yumc.Yum.commands.MonitorCommand;
@ -20,13 +23,8 @@ 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;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.reflect.Reflect;
import pw.yumc.YumCore.statistic.Statistics;
import pw.yumc.YumCore.update.SubscribeTask;
/**
* MC
@ -47,41 +45,32 @@ public class Yum extends JavaPlugin {
@Override
public void onDisable() {
NetworkManager.unregister();
}
@Override
public void onEnable() {
if (Bukkit.isPrimaryThread()) {
mainThread = Thread.currentThread();
} else {
mainThread = getMainThread();
}
new YumAPI();
initCommands();
initListeners();
initRunnable();
MonitorManager.init();
new Statistics();
new SubscribeTask(true, SubscribeTask.UpdateType.MAVEN);
new VersionChecker(this);
YumAPI.updateInject();
YumAPI.updateRepo(Bukkit.getConsoleSender());
YumAPI.updateCheck(Bukkit.getConsoleSender());
}
@Override
public void onLoad() {
// 初始化配置
ConfigManager.i();
// 初始化更新列
UpdatePlugin.getUpdateList();
// 启用网络注入
if (ConfigManager.i().isNetworkEnable()) {
NetworkManager.register(this);
}
}
/**
* @return 线
*/
private Thread getMainThread() {
Object console = Reflect.on(Bukkit.getServer()).get("console");
return Reflect.on(console).get("primaryThread");
NetworkManager.register(this);
}
/**
@ -98,30 +87,28 @@ public class Yum extends JavaPlugin {
*
*/
private void initListeners() {
new PluginListener();
if (ConfigManager.i().isSetOpEnable()) {
try {
ClassLoader cl = Class.forName("pw.yumc.injected.event.SetOpEvent").getClassLoader();
final ClassLoader cl = Class.forName("pw.yumc.injected.event.SetOpEvent").getClassLoader();
try {
cl.getClass().getDeclaredField("plugin");
throw new ClassNotFoundException();
} catch (NoSuchFieldException | SecurityException e) {
} catch (final NoSuchFieldException | SecurityException e) {
new SecurityListener(this);
Log.console("§a安全管理系统已启用...");
PluginKit.scp("§a安全管理系统已启用...");
}
} catch (ClassNotFoundException e) {
Log.console("§c服务端未注入安全拦截器 关闭功能...");
} catch (final ClassNotFoundException e) {
PluginKit.scp("§c服务端未注入安全拦截器 关闭功能...");
}
}
if (ConfigManager.i().isNetworkEnable()) {
new PluginNetworkListener(this);
Log.console("§a网络管理系统已启用...");
PluginKit.scp("§a网络管理系统已启用...");
}
if (ConfigManager.i().isThreadSafe()) {
new ThreadSafetyListener(this);
Log.console("§a线程管理系统已启用...");
}
if (ConfigManager.i().isMonitorEnable()) {
new PluginListener();
PluginKit.scp("§a线程管理系统已启用...");
}
}
@ -131,11 +118,11 @@ public class Yum extends JavaPlugin {
private void initRunnable() {
// 需要在主线程注册任务
if (ConfigManager.i().isMainThreadCheck() && mainThread != null) {
Log.console("§aI O 管理系统已启用...");
PluginKit.scp("§aI O 管理系统已启用...");
if (tt != null) {
tt.cancel();
}
task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 500);
task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 5000);
}
}
}

View File

@ -2,11 +2,17 @@ package pw.yumc.Yum.api;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import cn.citycraft.CommonData.UpdatePlugin;
import cn.citycraft.PluginHelper.kit.PKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.inject.CommandInjector;
import pw.yumc.Yum.inject.ListenerInjector;
import pw.yumc.Yum.inject.TaskInjector;
@ -15,8 +21,6 @@ import pw.yumc.Yum.managers.DownloadManager;
import pw.yumc.Yum.managers.PluginsManager;
import pw.yumc.Yum.managers.RepositoryManager;
import pw.yumc.Yum.models.PluginInfo;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.kit.PKit;
/**
* Yum
@ -33,9 +37,12 @@ public class YumAPI {
/**
* Yum
*
* @param plugin
*
*/
public YumAPI() {
YumAPI.main = P.instance;
YumAPI.main = PKit.instance;
plugman = new PluginsManager(main);
download = new DownloadManager(main);
repo = new RepositoryManager(main);
@ -48,7 +55,7 @@ public class YumAPI {
* @param plugin
*
*/
public static void delete(Plugin plugin) {
public static void delete(final Plugin plugin) {
plugman.deletePlugin(plugin);
}
@ -79,14 +86,27 @@ public class YumAPI {
return repo;
}
public static List<Plugin> getUpdateList(final CommandSender sender) {
final List<Plugin> ulist = new ArrayList<>();
try {
for (final Entry<String, Plugin> updateplugin : UpdatePlugin.getUpdateList().entrySet()) {
ulist.add(updateplugin.getValue());
}
} catch (final Exception | Error e) {
sender.sendMessage("§4错误: §c无法检索全体更新列表!");
sender.sendMessage("§4异常: §c" + e.getMessage());
}
return ulist;
}
/**
*
*
* @param plugin
*
*/
public static void inject(Plugin plugin) {
if (plugin.isEnabled() && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
public static void inject(final Plugin plugin) {
if (plugin.isEnabled()) {
CommandInjector.inject(plugin);
ListenerInjector.inject(plugin);
TaskInjector.inject(plugin);
@ -100,11 +120,16 @@ public class YumAPI {
*
* @param pluginname
*
* @param version
*
* @return
*/
public static boolean install(CommandSender sender, String pluginname, String url) {
File pluginFile = new File(Bukkit.getUpdateFolderFile().getParentFile(), pluginname + ".jar");
return download.run(sender, url, pluginFile) && plugman.load(sender, pluginFile);
public static boolean install(final CommandSender sender, final String pluginname, final String url) {
final File pluginFile = new File(Bukkit.getUpdateFolderFile().getParentFile(), pluginname + ".jar");
if (download.run(sender, url, pluginFile)) {
return plugman.load(sender, pluginFile);
}
return false;
}
/**
@ -112,9 +137,11 @@ public class YumAPI {
*
* @param pluginname
*
* @param version
*
* @return
*/
public static boolean install(String pluginname, String url) {
public static boolean install(final String pluginname, final String url) {
return install(null, pluginname, url);
}
@ -127,7 +154,7 @@ public class YumAPI {
*
* @return
*/
public static boolean installFromYum(CommandSender sender, String pluginname) {
public static boolean installFromYum(final CommandSender sender, final String pluginname) {
return installFromYum(sender, pluginname, null);
}
@ -142,17 +169,21 @@ public class YumAPI {
*
* @return
*/
public static boolean installFromYum(CommandSender sender, String pluginname, String version) {
PluginInfo pi = repo.getPlugin(pluginname);
if (pi != null) { return install(sender, pi.name, pi.getUrl(sender, version)); }
sender.sendMessage("§4错误: §c仓库中未找到插件 §b" + pluginname + " §c安装失败!");
public static boolean installFromYum(final CommandSender sender, final String pluginname, final String version) {
final PluginInfo pi = repo.getPlugin(pluginname);
if (pi != null) {
return install(sender, pi.name, pi.getUrl(sender, version));
}
return false;
}
/**
*
*
* @param pluginname
*
*/
public static void load(File pluginFile) {
public static void load(final File pluginFile) {
plugman.load(pluginFile);
}
@ -162,7 +193,7 @@ public class YumAPI {
* @param pluginname
*
*/
public static void load(String pluginname) {
public static void load(final String pluginname) {
plugman.load(pluginname);
}
@ -172,15 +203,18 @@ public class YumAPI {
* @param plugin
*
*/
public static void reload(Plugin plugin) {
public static void reload(final Plugin plugin) {
plugman.reload(plugin);
}
/**
*
*
* @param plugin
*
*/
public static void uninject() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
YumAPI.uninject(plugin);
}
}
@ -191,9 +225,9 @@ public class YumAPI {
* @param plugin
*
*/
public static void uninject(Plugin plugin) {
public static void uninject(final Plugin plugin) {
CommandInjector.uninject(plugin);
ListenerInjector.uninject(plugin);
// ListenerInjector.uninject(plugin);
TaskInjector.uninject(plugin);
}
@ -203,7 +237,7 @@ public class YumAPI {
* @param plugin
*
*/
public static void unload(Plugin plugin) {
public static void unload(final Plugin plugin) {
plugman.unload(plugin);
}
@ -218,10 +252,8 @@ public class YumAPI {
*
* @return
*/
public static boolean update(CommandSender sender, Plugin plugin, URL url) {
if (download.run(sender,
url,
new File(Bukkit.getUpdateFolderFile(), plugman.getPluginFile(plugin).getName()))) {
public static boolean update(final CommandSender sender, final Plugin plugin, final URL url) {
if (download.run(sender, url, new File(Bukkit.getUpdateFolderFile(), plugman.getPluginFile(plugin).getName()))) {
sender.sendMessage("§6更新: §e已下载 " + plugin.getName() + " 插件到服务器更新文件夹");
sender.sendMessage("§6更新: §e插件将在重启后自动更新(或使用§b/yum upgrade§e直接升级)!");
return true;
@ -238,10 +270,67 @@ public class YumAPI {
*
* @return
*/
public static boolean update(Plugin plugin, URL url) {
public static boolean update(final Plugin plugin, final URL url) {
return update(null, plugin, url);
}
/**
* Yum
*
* @param sender
*
*/
public static void updateAll(final CommandSender sender) {
main.getServer().getScheduler().runTaskAsynchronously(main, new Runnable() {
@Override
public void run() {
if (runlock) {
sender.sendMessage("§d一键更新: §c一键更新运行中 请稍候重试...");
return;
}
runlock = true;
int failed = 0;
final List<Plugin> ulist = getUpdateList(sender);
if (ulist.size() > 0) {
sender.sendMessage("§d开始更新服务器可更新插件");
for (final Plugin updateplugin : ulist) {
sender.sendMessage("§d一键更新: §a开始更新" + updateplugin.getName() + "!");
if (!updateFromYum(sender, updateplugin, null, true)) {
failed++;
}
}
if (failed != 0) {
sender.sendMessage("§d一键更新: §c升级过程中 §4" + failed + " §c个插件更新失败!");
}
sender.sendMessage("§d一键更新: §e已下载所有需要升级的插件到 服务器更新 文件夹");
sender.sendMessage("§d一键更新: §e插件将在重启后自动更新(或使用§b/yum upgrade§e直接升级)!");
updateCheck(sender);
} else {
sender.sendMessage("§6更新: §e未找到需要更新且可以用Yum处理的插件!");
}
runlock = false;
}
});
}
/**
*
*
* @param sender
*
*/
public static void updateCheck(final CommandSender sender) {
PluginKit.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
final List<Plugin> ulist = getUpdateList(sender);
if (ulist.size() > 0) {
sender.sendMessage("§6[§bYum§6]§e自动更新: §a发现 §e" + ulist.size() + " §a个可更新插件 请使用 §b/yum ua §a更新所有插件!");
}
}
}, 60);
}
/**
*
*
@ -251,7 +340,7 @@ public class YumAPI {
*
* @return
*/
public static boolean updateFromYum(CommandSender sender, Plugin plugin) {
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin) {
return updateFromYum(sender, plugin, null);
}
@ -266,7 +355,7 @@ public class YumAPI {
* (null)
* @return
*/
public static boolean updateFromYum(CommandSender sender, Plugin plugin, String version) {
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin, final String version) {
return updateFromYum(sender, plugin, version, false);
}
@ -283,16 +372,16 @@ public class YumAPI {
*
* @return
*/
public static boolean updateFromYum(CommandSender sender, Plugin plugin, String version, boolean oneKeyUpdate) {
PluginInfo pi = repo.getPlugin(plugin.getName());
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin, final String version, final boolean oneKeyUpdate) {
final PluginInfo pi = repo.getPlugin(plugin.getName());
if (pi != null) {
File pFile = new File(Bukkit.getUpdateFolderFile(), plugman.getPluginFile(plugin).getName());
final File pFile = new File(Bukkit.getUpdateFolderFile(), plugman.getPluginFile(plugin).getName());
if (download.run(sender, pi.getUrl(sender, version), pFile)) {
if (!oneKeyUpdate) {
sender.sendMessage("§6更新: §e已下载 " + plugin.getName() + " 插件到服务器更新文件夹");
sender.sendMessage("§6更新: §e插件将在重启后自动更新(或使用§b/yum upgrade§e直接升级)!");
}
//UpdatePlugin.getUpdateList().remove(plugin.getName());
UpdatePlugin.getUpdateList().remove(plugin.getName());
return true;
}
} else {
@ -305,10 +394,10 @@ public class YumAPI {
*
*/
public static void updateInject() {
PKit.runTaskLater(new Runnable() {
PluginKit.runTaskLater(new Runnable() {
@Override
public void run() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
YumAPI.inject(plugin);
}
}
@ -319,7 +408,7 @@ public class YumAPI {
* Yum
*/
public static void updateRepo(final CommandSender sender) {
PKit.runTaskAsync(new Runnable() {
PluginKit.runTaskAsync(new Runnable() {
@Override
public void run() {
repo.updateRepositories(sender);
@ -328,24 +417,12 @@ public class YumAPI {
}
/**
*
*
* @param sender
*
*/
public static void upgrade(CommandSender sender) {
plugman.upgrade(sender);
}
/**
*
*
* @param sender
*
* @param plugin
*
*/
public static void upgrade(CommandSender sender, Plugin plugin) {
public static void upgrade(final CommandSender sender, final Plugin plugin) {
plugman.upgrade(sender, plugin);
}
}

View File

@ -1,25 +1,17 @@
package pw.yumc.Yum.commands;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
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.utils.FileUtil;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.YumCore.commands.CommandSub;
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.Option;
import pw.yumc.YumCore.commands.interfaces.Executor;
import pw.yumc.YumCore.kit.FileKit;
/**
* File
@ -27,97 +19,67 @@ import pw.yumc.YumCore.kit.FileKit;
* @since 201619 10:02:39
* @author
*/
public class FileCommand implements Executor {
private static String prefix = "§6[§bYum §a文件管理§6] ";
private static String file_not_found = prefix + "§b%s §c文件未找到!";
private static String file_is_dir = prefix + "§b%s §c文件是一个目录!";
private static String copySuccess = prefix + "§a文件 §b%s §a复制成功!";
private static String copyFailed = prefix + "§c文件 §b%s §c复制失败!";
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 = "§e %s §a成功添加开机自动启...";
private static String addStartupFailed = "§c添加开机自动启失败 %s %s!";
private static String STARTPATH = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp";
public class FileCommand implements HandlerCommands {
Yum plugin;
public FileCommand(Yum yum) {
public FileCommand(final Yum yum) {
plugin = yum;
new CommandSub("file", this, PluginTabComplete.INSTANCE);
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
cmdhandler.registerCommands(this);
}
@Cmd(aliases = "cp", minimumArguments = 2)
@Help(value = "复制文件", possibleArguments = "<源文件> <目标目录>")
@Async
public void copy(CommandSender sender, @Option(value = "check") File src, File des) throws IOException {
if (src.isDirectory()) {
sender.sendMessage(String.format(file_is_dir, src.getPath()));
return;
}
if (Files.copy(new FileInputStream(src), des.toPath(), StandardCopyOption.REPLACE_EXISTING) != 0) {
sender.sendMessage(String.format(copySuccess, src.getPath()));
} else {
sender.sendMessage(String.format(copyFailed, src.getPath()));
}
}
@Cmd(aliases = "del", minimumArguments = 1)
@Help(value = "删除文件(服务器JAR为根目录)", possibleArguments = "<文件相对目录>")
@Async
public void delete(CommandSender sender, String fpath) {
File file = new File(fpath);
fpath = file.getAbsolutePath();
@HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除文件(服务器JAR为根目录)", possibleArguments = "<文件相对目录>")
public void delete(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final String fpath = args[0];
final File file = new File(fpath);
final CommandSender sender = e.getSender();
if (!file.exists()) {
sender.sendMessage(String.format(file_not_found, fpath));
sender.sendMessage("§c文件 " + file.getAbsolutePath() + " 不存在!");
} else {
if (file.isDirectory()) {
sender.sendMessage(String.format(file_is_dir, fpath));
sender.sendMessage("§e" + file.getAbsolutePath() + " §c是一个目录 请使用file rm!");
return;
}
try {
sender.sendMessage("§d文件 §e" + fpath + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!"));
} catch (Exception ex) {
sender.sendMessage("§d文件 §e" + fpath + " 删除失败: " + ex.getMessage());
sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!"));
} catch (final Exception ex) {
sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " 删除失败: " + ex.getMessage());
}
}
}
@Cmd(aliases = "d", minimumArguments = 1)
@Help(value = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]")
@Async
public void download(CommandSender sender, String urlstr, String path) {
@HandlerCommand(name = "download", aliases = { "d" }, minimumArguments = 1, description = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]")
public void download(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
String urlstr = args[0];
if (!urlstr.startsWith("http")) {
urlstr = "http://" + urlstr;
}
File file = null;
if (path != null) {
file = new File(path);
if (args.length == 2) {
file = new File(args[1]);
} else {
file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(urlstr));
}
YumAPI.getDownload().run(sender, urlstr, file);
YumAPI.getDownload().run(e.getSender(), urlstr, file);
}
@Cmd(aliases = "ls")
@Help(value = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>")
@Async
public void ls(CommandSender sender, String filename) {
@HandlerCommand(name = "ls", aliases = { "l" }, description = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>")
public void ls(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
File dir = new File(".");
if (filename != null) {
dir = new File(filename);
if (args.length == 1) {
dir = new File(args[0]);
}
if (!dir.isDirectory()) {
sender.sendMessage("§6路径: §e " + dir.getAbsolutePath() + " §c不是一个目录!");
return;
}
StringBuffer sb = new StringBuffer();
for (File file : dir.listFiles()) {
final StringBuffer sb = new StringBuffer();
for (final File file : dir.listFiles()) {
if (file.isDirectory()) {
sb.append("§b");
} else {
@ -125,7 +87,7 @@ public class FileCommand implements Executor {
}
sb.append(file.getName() + " ");
}
String filelist = sb.toString();
final String filelist = sb.toString();
if (filelist.isEmpty()) {
sender.sendMessage("§6目录: §e" + dir.getAbsolutePath() + " §c下没有文件或文件夹!");
} else {
@ -134,29 +96,31 @@ public class FileCommand implements Executor {
}
}
@Cmd(aliases = "rn", minimumArguments = 2)
@Help(value = "重命名文件(服务器JAR为根目录)", possibleArguments = "<文件相对路径> <文件名称>")
@Async
public void rename(CommandSender sender, String fpath, String des) {
File file = new File(fpath);
@HandlerCommand(name = "rename", aliases = { "rn" }, minimumArguments = 2, description = "重命名文件(服务器JAR为根目录)", possibleArguments = "<文件相对路径> <文件名称>")
public void rename(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
final String fpath = args[0];
final File file = new File(fpath);
if (!file.exists()) {
sender.sendMessage("§c文件 " + file.getAbsolutePath() + " 不存在!");
} else {
try {
File newFile = new File(file.getParentFile(), des);
final File newFile = new File(file.getParentFile(), args[1]);
file.renameTo(newFile);
sender.sendMessage("§a文件 §e" + file.getAbsolutePath() + " §a重命名为 §d" + newFile.getAbsolutePath());
} catch (Exception ex) {
} catch (final Exception ex) {
sender.sendMessage("§c文件 §e" + file.getAbsolutePath() + " §c重命名失败: " + ex.getMessage());
}
}
}
@Cmd(minimumArguments = 1)
@Help(value = "删除文件夹(服务器JAR为根目录)", possibleArguments = "<相对目录>")
@Async
public void rm(CommandSender sender, String fpath, String option) {
File file = new File(fpath);
@HandlerCommand(name = "rm", minimumArguments = 1, description = "删除文件夹(服务器JAR为根目录)", possibleArguments = "<相对目录>")
public void rm(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
final String fpath = args[0];
final File file = new File(fpath);
if (!file.exists()) {
sender.sendMessage("§c目录 " + file.getAbsolutePath() + " 不存在!");
} else {
@ -164,66 +128,19 @@ public class FileCommand implements Executor {
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!");
return;
}
for (String name : plugin.getConfig().getStringList("blacklist")) {
for (final String name : plugin.getConfig().getStringList("blacklist")) {
if (file.getAbsolutePath().toLowerCase().endsWith(name)) {
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c不允许被删除!");
return;
}
}
if (file.listFiles().length != 0 && !(option != null && option.equalsIgnoreCase("-rf"))) {
if (file.listFiles().length != 0 && !(args.length > 1 && args[1].equalsIgnoreCase("-rf"))) {
sender.sendMessage("§d目录 §e" + file.getAbsolutePath() + " §c不为空!");
sender.sendMessage("§c请使用 §a/file rm " + fpath + " -rf §c强行删除!");
return;
}
sender.sendMessage("§d目录 §e" + file.getAbsolutePath() + " "
+ (FileKit.deleteDir(sender, file) ? "§a删除成功!" : "§c删除失败!"));
sender.sendMessage("§d目录 §e" + file.getAbsolutePath() + " " + (FileUtil.deleteDir(sender, file) ? "§a删除成功!" : "§c删除失败!"));
}
}
@Cmd(aliases = "r", minimumArguments = 1)
@Help(value = "运行一个命令或文件", possibleArguments = "<命令或文件绝对路径>")
@Async
public void run(CommandSender sender, String args) {
try {
Process process = Runtime.getRuntime().exec(args);
sender.sendMessage(waitCommand);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
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 (Exception e2) {
sender.sendMessage(String.format(runError, e2.getClass().getSimpleName(), e2.getMessage()));
}
}
@Cmd(minimumArguments = 1)
@Help(value = "添加开机自启动", possibleArguments = "<文件绝对路径>")
@Async
public void startup(CommandSender sender, String filepath) {
File src = new File(filepath);
File des = new File(STARTPATH, src.getName());
if (!src.exists()) {
sender.sendMessage(String.format(file_not_found, filepath));
return;
}
if (src.isDirectory()) {
sender.sendMessage(String.format(file_is_dir, filepath));
return;
}
try {
Files.copy(new FileInputStream(src), des.toPath(), StandardCopyOption.REPLACE_EXISTING);
sender.sendMessage(String.format(addStartupSuccess, filepath));
} catch (Exception e2) {
sender.sendMessage(String.format(addStartupFailed, e2.getClass().getName(), e2.getMessage()));
}
}
}

View File

@ -1,6 +1,5 @@
package pw.yumc.Yum.commands;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -8,6 +7,7 @@ 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;
@ -19,129 +19,98 @@ 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.StrKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.inject.CommandInjector;
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.CommandSub;
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.Option;
import pw.yumc.YumCore.commands.interfaces.Executor;
import pw.yumc.YumCore.kit.PKit;
import pw.yumc.YumCore.kit.StrKit;
import pw.yumc.YumCore.reflect.Reflect;
/**
*
* @since 201676 5:13:32
* @author
*/
public class MonitorCommand implements Executor {
public static Throwable lastError = null;
public class MonitorCommand implements HandlerCommands {
private final String prefix = "§6[§bYum §a能耗监控§6] ";
private final String total = "§6总耗时: §a%.2f毫秒 ";
private final String count = "§6执行次数: §b%s次 ";
private final String avg = "§6平均耗时: §d%.5f毫秒!";
private final String p_n_f = prefix + "§c插件 §b%s §c不存在!";
private String prefix = "§6[§bYum §a能耗监控§6] ";
private final double um = 1000000.0;
private String no_mi = prefix + "§6%s §a自服务器启动以来尚未执行任何操作";
private String micprefix = " §6命令名称 §a总耗时 §b执行次数 §d平均耗时";
private String mieprefix = " §6事件名称 §a总耗时 §b执行次数 §d平均耗时";
private String mitprefix = " §6任务名称 §a总耗时 §b执行次数 §d平均耗时";
private String milist = "§6- §e%-20s §a%-9.2f §b%-9s §d%-9.5f";
private String miwlist = "§6- §c%-20s §a%-9.2f §b%-9s §c%-9.5f";
private String reinject = prefix + "§a能耗监控器重载完毕!";
private String injected = prefix + "§a插件 §b%s §a成功注入能耗监控器!";
private String uninjected = prefix + "§a插件 §b%s §a成功撤销能耗监控器!";
private String notEnable = prefix + "§c插件 §b%s §c未成功加载 无法执行注入!";
private String lag = prefix + "§a当前服务器插件能耗如下§6(单位: %)";
private String lagprefix = " §6插件名称 §c主线程 §a命令 §b事件 §d任务";
private String laglist = "§6%-2s §b%-18s §c%-25s §a%-5.2f §b%-5.2f §d%-5.2f";
private String no_error = prefix + "§a自服务器启动以来尚未发现报错!";
private String last_error = prefix + "§c最后一次错误异常由 §b%s §c造成 详细如下:";
private String p_n_f = prefix + "§c插件 §b%s §c不存在!";
private double um = 1000000.00;
public MonitorCommand(Yum yum) {
new CommandSub("monitor", this, PluginTabComplete.INSTANCE);
public MonitorCommand(final Yum yum) {
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
cmdhandler.registerCommands(this);
cmdhandler.registerCommands(PluginTabComplete.instence);
}
@Cmd(aliases = "c", minimumArguments = 1)
@Help(value = "查看插件命令能耗", possibleArguments = "[插件名称]")
@Async
public void cmd(CommandSender sender, String pname) {
@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(String.format(p_n_f, pname));
return;
}
PluginManager pluginManager = Bukkit.getPluginManager();
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
final PluginManager pluginManager = Bukkit.getPluginManager();
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的命令能耗如下!");
Map<String, Command> temp = new HashMap<>();
for (Command command : commandMap.getCommands()) {
final Map<String, Command> temp = new HashMap<>();
for (final Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
PluginCommand pluginCommand = (PluginCommand) command;
Plugin plugin = pluginCommand.getPlugin();
final PluginCommand pluginCommand = (PluginCommand) command;
final Plugin plugin = pluginCommand.getPlugin();
if (plugin.getName().equalsIgnoreCase(pname)) {
temp.put(command.getName(), command);
}
}
}
if (temp.isEmpty()) {
sender.sendMessage(String.format(no_mi, pname));
return;
}
sender.sendMessage(micprefix);
for (Entry<String, Command> command : temp.entrySet()) {
org.bukkit.command.CommandExecutor executor = Reflect.on(command.getValue()).get("executor");
for (final Entry<String, Command> command : temp.entrySet()) {
final CommandExecutor executor = Reflect.on(command.getValue()).get("executor");
if (executor instanceof CommandInjector) {
CommandInjector injected = (CommandInjector) executor;
final CommandInjector injected = (CommandInjector) executor;
final StringBuffer str = new StringBuffer();
str.append("§6- §e" + command.getValue().getName() + " ");
str.append(String.format(total, injected.totalTime / um));
str.append(String.format(count, injected.count));
if (injected.count != 0) {
double avgTime = injected.totalTime / um / injected.count;
sender.sendMessage(String.format(avgTime < 10 ? milist : miwlist, command.getValue().getName(), injected.totalTime / um, injected.count, avgTime));
} else {
sender.sendMessage(String.format(milist, command.getValue().getName(), injected.totalTime / um, injected.count, 0D));
str.append(String.format(avg, injected.totalTime / um / injected.count));
}
e.getSender().sendMessage(str.toString());
}
}
}
@Cmd(aliases = "e", minimumArguments = 1)
@Help(value = "查看插件事件能耗", possibleArguments = "[插件名称]")
@Async
public void event(CommandSender sender, String pname) throws IllegalAccessException, NoSuchFieldException {
Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
@HandlerCommand(name = "event", minimumArguments = 1, possibleArguments = "插件名称")
public void event(final InvokeCommandEvent e) throws InstantiationException, IllegalAccessException {
final String pname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
if (plugin == null) {
sender.sendMessage(String.format(p_n_f, pname));
return;
}
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的事件能耗如下!");
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
Map<String, Long> eventTotalTime = new HashMap<>();
Map<String, Integer> eventCount = new HashMap<>();
for (RegisteredListener listener : listeners) {
final List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
final Map<String, Long> eventTotalTime = new HashMap<>();
final Map<String, Integer> eventCount = new HashMap<>();
for (final RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) {
TimedRegisteredListener trl = (TimedRegisteredListener) listener;
final TimedRegisteredListener trl = (TimedRegisteredListener) listener;
eventTotalTime.put(trl.getEventClass().getSimpleName(), trl.getTotalTime());
eventCount.put(trl.getEventClass().getSimpleName(), trl.getCount());
continue;
}
EventExecutor executor = Reflect.on(listener).get("executor");
if (listener.getClass().getName().contains("PWPRegisteredListener")) {
Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor");
f.setAccessible(true);
executor = (EventExecutor) f.get(listener);
}
final EventExecutor executor = Reflect.on(listener).get("executor");
if (executor instanceof ListenerInjector) {
ListenerInjector injected = (ListenerInjector) executor;
for (String entry : injected.eventTotalTime.keySet()) {
final ListenerInjector injected = (ListenerInjector) executor;
for (final String entry : injected.eventTotalTime.keySet()) {
if (eventTotalTime.containsKey(entry)) {
eventTotalTime.put(entry, eventTotalTime.get(entry) + injected.eventTotalTime.get(entry));
eventCount.put(entry, eventCount.get(entry) + injected.eventCount.get(entry));
@ -152,150 +121,45 @@ public class MonitorCommand implements Executor {
}
}
}
if (eventTotalTime.isEmpty()) {
sender.sendMessage(String.format(no_mi, pname));
return;
}
sender.sendMessage(mieprefix);
for (String event : MonitorManager.sortMapByValue(eventTotalTime).keySet()) {
double avgTime = eventTotalTime.get(event) / um / eventCount.get(event);
sender.sendMessage(String.format(avgTime < 10 ? milist : miwlist, event, eventTotalTime.get(event) / um, eventCount.get(event), avgTime));
for (final String event : eventTotalTime.keySet()) {
final StringBuffer str = new StringBuffer();
str.append("§6- §e" + event + " ");
str.append(String.format(total, eventTotalTime.get(event) / um));
str.append(String.format(count, eventCount.get(event)));
if (eventCount.get(event) != 0) {
str.append(String.format(avg, eventTotalTime.get(event) / um / eventCount.get(event)));
}
e.getSender().sendMessage(str.toString());
}
}
@Cmd(aliases = "i", minimumArguments = 1)
@Help(value = "注入能耗监控器", possibleArguments = "[插件名称]")
public void inject(CommandSender sender, String pname) {
Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
@HandlerCommand(name = "task", minimumArguments = 1, possibleArguments = "插件名称")
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(String.format(p_n_f, pname));
return;
}
if (plugin.isEnabled()) {
YumAPI.inject(plugin);
sender.sendMessage(String.format(injected, pname));
} else {
sender.sendMessage(String.format(notEnable, pname));
}
}
@Cmd(aliases = "l")
@Help("查看插件总耗时")
@Async
public void lag(CommandSender sender, @Option("def:8") int size) {
Map<String, Long> mm = MonitorManager.getMonitor();
sender.sendMessage(lag);
sender.sendMessage(lagprefix);
int index = 0;
for (Entry<String, Long> entry : mm.entrySet()) {
if (++index > size) {
break;
}
MonitorInfo mi = MonitorManager.getMonitorInfo(entry.getKey());
if (mi.monitor != 0) {
sender.sendMessage(String.format(laglist, index, StrKit.substring(entry.getKey(), 0, 18), getPer(sender, mi.monitor), mi.cmd, mi.event, mi.task));
}
}
}
@Cmd(aliases = "la")
@Help("查看最后一次报错")
@Async
public void lasterror(CommandSender sender) {
if (lastError == null) {
sender.sendMessage(no_error);
return;
}
Plugin plugin = PKit.getOperatePlugin(lastError.getStackTrace());
sender.sendMessage(String.format(last_error, plugin != null ? plugin.getName() : "未知"));
lastError.printStackTrace();
}
@Cmd(aliases = "ri")
@Help("重载能耗监控器")
public void reinject(CommandSender sender) {
YumAPI.updateInject();
sender.sendMessage(reinject);
}
@Cmd
@Help("重置能耗监控器")
@Async
public void reset(CommandSender sender) {
MonitorManager.init();
}
@Cmd(aliases = "t", minimumArguments = 1)
@Help(value = "查看插件任务能耗", possibleArguments = "[插件名称]")
@Async
public void task(CommandSender sender, String pname) {
Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
if (plugin == null) {
sender.sendMessage(String.format(p_n_f, pname));
return;
}
List<BukkitTask> pendingTasks = Bukkit.getScheduler().getPendingTasks();
if (pendingTasks.isEmpty()) {
sender.sendMessage(String.format(no_mi, pname));
return;
}
final List<BukkitTask> pendingTasks = Bukkit.getScheduler().getPendingTasks();
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的任务能耗如下!");
sender.sendMessage(mitprefix);
for (BukkitTask pendingTask : pendingTasks) {
for (final BukkitTask pendingTask : pendingTasks) {
if (pendingTask.getOwner().getName().equalsIgnoreCase(pname)) {
Runnable task = Reflect.on(pendingTask).get("task");
final Runnable task = Reflect.on(pendingTask).get("task");
if (task instanceof TaskInjector) {
TaskInjector executor = (TaskInjector) task;
final TaskInjector executor = (TaskInjector) task;
final StringBuffer str = new StringBuffer();
final Class<? extends Runnable> taskName = executor.getOriginalTask().getClass();
str.append("§6- §e" + (StrKit.isBlank(taskName.getSimpleName()) ? taskName.getName() : taskName.getSimpleName()) + " ");
str.append(String.format(total, executor.totalTime / um));
str.append(String.format(count, executor.count));
if (executor.count != 0) {
double avgTime = executor.totalTime / um / executor.count;
sender.sendMessage(String.format(avgTime < 10 ? milist : miwlist, getClassName(executor.getOriginalTask().getClass()), executor.totalTime / um, executor.count, avgTime));
} else {
sender.sendMessage(String.format(milist, getClassName(executor.getOriginalTask().getClass()), executor.totalTime / um, executor.count, 0D));
str.append(String.format(avg, executor.totalTime / um / executor.count));
}
e.getSender().sendMessage(str.toString());
}
}
}
}
@Cmd(aliases = "ui", minimumArguments = 1)
@Help(value = "撤销能耗监控器", possibleArguments = "[插件名称]")
public void uninject(CommandSender sender, String pname) {
Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
if (plugin == null) {
sender.sendMessage(String.format(p_n_f, pname));
return;
}
if (plugin.isEnabled()) {
YumAPI.uninject(plugin);
sender.sendMessage(String.format(uninjected, pname));
}
}
private String getClassName(Class<?> clazz) {
return StrKit.isBlank(clazz.getSimpleName()) ? clazz.getName().substring(clazz.getName().lastIndexOf(".") + 1) : clazz.getSimpleName();
}
private String getPer(CommandSender sender, double per) {
String ps = "≡";
double p = per / 5;
StringBuilder sb = new StringBuilder();
if (p < 3) {
sb.append("§a");
} else if (p < 6) {
sb.append("§d");
} else if (p < 9) {
sb.append("§c");
} else {
sb.append("§4");
}
for (int i = 0; i < 11; i++) {
if (p > i) {
sb.append(ps);
}
}
if (per > 0) {
sb.append(String.format("% 3.2f", per));
}
return sb.toString();
}
}

View File

@ -1,78 +1,31 @@
package pw.yumc.Yum.commands;
import java.util.HashMap;
import java.util.Map.Entry;
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.CommandSub;
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.interfaces.Executor;
public class NetCommand implements Executor {
public static HashMap<String, Integer> netlist = new HashMap<>();
public class NetCommand implements HandlerCommands {
private String prefix = "§6[§bYum §a网络管理§6] ";
private String showlist = prefix + "§a自服务器启动以来尝试联网的插件列表如下:";
private String listprefix = " §6插件名称 §d联网次数";
private String list = "§6- §b%-20s §d%s";
private String no_net = prefix + "§a尚未检测到尝试联网的插件!";
private String add = prefix + "§a已添加插件 §b%s §a到网络 %s §a列表!";
private String p_n_f = prefix + "§c插件 §b%s §c不存在!";
public NetCommand(Yum yum) {
new CommandSub("net", this, PluginTabComplete.INSTANCE);
public NetCommand(final Yum yum) {
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net");
cmdhandler.registerCommands(this);
cmdhandler.registerCommands(PluginTabComplete.instence);
}
public static void addNetCount(String pname) {
if (netlist.containsKey(pname)) {
netlist.put(pname, netlist.get(pname) + 1);
} else {
netlist.put(pname, 1);
}
@HandlerCommand(name = "list", aliases = "l", permission = "", description = "列出联网的插件")
public void list(final InvokeCommandEvent e) {
}
@Cmd(aliases = "l")
@Help("列出联网的插件详情")
@Async
public void list(CommandSender sender) {
if (netlist.isEmpty()) {
sender.sendMessage(no_net);
return;
}
sender.sendMessage(showlist);
sender.sendMessage(listprefix);
for (Entry<String, Integer> entry : netlist.entrySet()) {
sender.sendMessage(String.format(list, entry.getKey(), entry.getValue()));
}
@HandlerCommand(name = "off", description = "禁止插件联网", possibleArguments = "[插件名称]")
public void off(final InvokeCommandEvent e) {
}
@Cmd(minimumArguments = 1)
@Help(value = "禁止插件联网", possibleArguments = "[插件名称]")
public void off(CommandSender sender, String pname) {
if (Bukkit.getPluginManager().getPlugin(pname) == null) {
sender.sendMessage(String.format(p_n_f, pname));
return;
}
ConfigManager.i().network.addToStringList(ConfigManager.BLACK, pname, false).save();
sender.sendMessage(String.format(add, pname, "§c黑名单"));
}
@HandlerCommand(name = "on", description = "允许插件联网", possibleArguments = "[插件名称]")
public void on(final InvokeCommandEvent e) {
@Cmd(minimumArguments = 1)
@Help(value = "允许插件联网", possibleArguments = "[插件名称]")
public void on(CommandSender sender, String pname) {
if (Bukkit.getPluginManager().getPlugin(pname) == null) {
sender.sendMessage(String.format(p_n_f, pname));
return;
}
ConfigManager.i().network.addToStringList(ConfigManager.IGNORE, pname, false).save();
sender.sendMessage(String.format(add, pname, "§e白名单"));
}
}

View File

@ -4,41 +4,35 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
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.annotation.Tab;
import pw.yumc.YumCore.commands.interfaces.Executor;
/**
* @author
*
* @since 201677 8:36:47
* @author
*/
public class PluginTabComplete implements Executor {
public static PluginTabComplete INSTANCE = new PluginTabComplete();
public class PluginTabComplete implements HandlerCommands {
public static PluginTabComplete instence = new PluginTabComplete();
@Tab
public List<String> listTab(CommandSender sender, String label, String[] args) {
if (args.length > 0) {
switch (args[0]) {
case "install":
case "i":
return YumAPI.getRepo().getAllPluginName();
case "repo":
case "r":
if (args.length == 2) {
return Arrays.asList("add", "all", "list", "delall", "clean", "update", "del");
}
if (args.length == 3) {
return new ArrayList<>(YumAPI.getRepo().getRepos().keySet());
}
break;
case "bukkitrepo":
case "br":
return Arrays.asList("look", "install");
default:
@HandlerTabComplete()
public List<String> listtab(final InvokeCommandEvent 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<String>());
} else if (args[0].equalsIgnoreCase("repo")) {
if (args.length == 2) {
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")) {
return StrKit.copyPartialMatches(args[2], YumAPI.getRepo().getRepos().keySet(), new ArrayList<String>());
}
} else {
return StrKit.copyPartialMatches(args[1], YumAPI.getPlugman().getPluginNames(false), new ArrayList<String>());
}
return YumAPI.getPlugman().getPluginNames(false);
return null;
}
}

View File

@ -1,9 +1,6 @@
package pw.yumc.Yum.commands;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -11,225 +8,110 @@ import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
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.utils.StrKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.managers.ConfigManager;
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.callback.CallBack.One;
import pw.yumc.YumCore.commands.CommandSub;
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;
import pw.yumc.YumCore.commands.interfaces.Executor;
import pw.yumc.YumCore.kit.FileKit;
import pw.yumc.YumCore.kit.HttpKit;
import pw.yumc.YumCore.kit.ZipKit;
import pw.yumc.YumCore.tellraw.Tellraw;
/**
* Yum
*
* @author
* @since 201619 10:02:24
* @author
*/
public class YumCommand implements Executor {
private String prefix = "§6[§bYum §a插件管理§6] ";
private String searchLimit = prefix + "§c为保证搜索速度和准确性 关键词必须大于 3 个字符!";
private String searching = prefix + "§a正在从 §eBukkitDev §a获取 §b%s §a的相关数据...";
private String notFoundFromBukkit = prefix + "§c未在 §eBukkitDev §c搜索到 §b%s §c的相关插件!";
private String result = prefix + "§6关键词 §b%s §6的搜索结果如下:";
private String bukkitListPrefix = " §6插件ID §3插件名称 §d发布类型 §a操作";
private String bukkitList = "§6- §e%-6s §b%-25s §d%-10s";
private String fsearching = prefix + "§a正在从 §eBukkitDev §a获取ID §b%s §a的文件列表...";
private String notFoundIdFromBukkit = prefix + "§c未在 §eBukkitDev §c搜索到ID为 §b%s §c的相关插件!";
private String fileListPrefix = " §6插件名称 §3游戏版本 §d发布类型 §a操作";
private String fileList = "§6- §b%-20s §3%-15s §d%-10s";
private String del = "§c删除: §a插件 §b%s §a版本 §d%s §a已从服务器卸载并删除!";
private String delFailed = "§c删除: §a插件 §b%s §c卸载或删除时发生错误 删除失败!";
private String look = "§6查看";
private String install = "§a安装";
private String installTip = "§a点击安装";
private String update = "§a更新";
private String unload = "§d卸载";
private String reload = "§6重载";
private String delete = "§c删除";
private String unzip_error = prefix + "ZIP文件解压错误!";
public class YumCommand implements HandlerCommands, Listener {
Yum main;
public YumCommand(Yum yum) {
public YumCommand(final Yum yum) {
main = yum;
new CommandSub("yum", this, PluginTabComplete.INSTANCE);
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);
}
@Async
@Cmd(aliases = "br", minimumArguments = 2)
@Help(value = "从BukkitDev查看安装插件", possibleArguments = "<操作符> <项目ID|项目名称> [地址]")
public void bukkitrepo(final CommandSender sender, final String opt, final String id, String url) {
switch (opt) {
case "look": {
sender.sendMessage(String.format(fsearching, id));
List<Files> lf = Files.parseList(HttpKit.get(String.format(BukkitDev.PLUGIN, id)));
if (lf.isEmpty()) {
sender.sendMessage(String.format(notFoundIdFromBukkit, id));
return;
}
sender.sendMessage(fileListPrefix);
for (int i = 0; i < lf.size() || i < 8; i++) {
Files f = lf.get(i);
Tellraw tr = Tellraw.create();
tr.text(String.format(fileList, f.name, f.gameVersion, f.releaseType));
tr.then(" ");
tr.then(install).command(String.format("/yum br ai %s %s", f.name, f.downloadUrl));
tr.tip(installTip);
tr.send(sender);
}
break;
}
case "ai": {
if (url == null) { return; }
File file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(url));
YumAPI.getDownload().run(sender, url, file, new One<File>() {
@Override
public void run(File file) {
if (file.getName().endsWith(".zip")) {
try {
ZipKit.unzip(file, Bukkit.getUpdateFolderFile(), ".jar");
file.delete();
} catch (IOException e) {
sender.sendMessage(unzip_error);
}
}
YumAPI.upgrade(sender);
}
});
break;
}
case "i":
case "install": {
sender.sendMessage(String.format(fsearching, id));
List<Files> lf = Files.parseList(HttpKit.get(String.format(BukkitDev.PLUGIN, id)));
if (lf.isEmpty()) {
sender.sendMessage(String.format(notFoundIdFromBukkit, id));
return;
}
Files f = lf.get(0);
url = f.downloadUrl;
File file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(url));
YumAPI.getDownload().run(sender, url, file, new One<File>() {
@Override
public void run(File file) {
if (file.getName().endsWith(".zip")) {
try {
ZipKit.unzip(file, Bukkit.getUpdateFolderFile(), ".jar");
} catch (IOException e) {
sender.sendMessage(unzip_error);
}
}
YumAPI.upgrade(sender);
}
});
break;
}
default:
}
}
@Cmd(aliases = "del", minimumArguments = 1)
@Help(value = "删除插件", possibleArguments = "<插件名称>")
@Sort(6)
public void delete(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除插件", possibleArguments = "<插件名称>")
public void delete(final InvokeCommandEvent e) {
final String pluginname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (YumAPI.getPlugman().deletePlugin(sender, plugin)) {
sender.sendMessage(String.format(del, pluginname, version));
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
} else {
sender.sendMessage(String.format(delFailed, pluginname));
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
}
} else {
sender.sendMessage(pnf(pluginname));
}
}
@Cmd(aliases = "ddel", minimumArguments = 1)
@Help(value = "删除插件数据文件夹", possibleArguments = "<插件名称>")
@Sort(7)
public void dirdelete(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
FileKit.deleteDir(sender, plugin.getDataFolder());
} else {
sender.sendMessage(pnf(pluginname));
}
}
@Cmd(aliases = "f", minimumArguments = 1)
@Help(value = "通过类名查找插件", possibleArguments = "<插件类名>")
@Sort(10)
public void find(CommandSender sender, String classname) {
@HandlerCommand(name = "find", aliases = { "f" }, minimumArguments = 1, possibleArguments = "<插件类名>", description = "通过类名查找插件")
public void find(final InvokeCommandEvent e) {
final String classname = e.getArgs()[0];
final CommandSender sender = e.getSender();
try {
Class<?> clazz = Class.forName(classname);
Field field = clazz.getClassLoader().getClass().getDeclaredField("plugin");
final Class<?> clazz = Class.forName(classname);
final Field field = clazz.getClassLoader().getClass().getDeclaredField("plugin");
field.setAccessible(true);
Plugin plugin = (JavaPlugin) field.get(clazz.getClassLoader());
final Plugin plugin = (JavaPlugin) field.get(clazz.getClassLoader());
Bukkit.dispatchCommand(sender, "yum info " + plugin.getName());
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
} catch (final ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
sender.sendMessage("§4错误: 无法找到类 " + classname + " 所对应的插件信息 异常:" + e2.getClass().getSimpleName() + " " + e2.getMessage() + "!");
}
}
@Cmd(aliases = "fdel", minimumArguments = 1)
@Help(value = "删除插件以及数据文件夹", possibleArguments = "<插件名称>")
@Sort(7)
public void fulldelete(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "fulldelete", aliases = { "fdel" }, minimumArguments = 1, description = "删除插件以及数据文件夹", possibleArguments = "<插件名称>")
public void fulldelete(final InvokeCommandEvent e) {
final String pluginname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) {
sender.sendMessage(String.format(del, pluginname, version));
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
} else {
sender.sendMessage(String.format(delFailed, pluginname));
sender.sendMessage("§c删除: §c插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
}
} else {
sender.sendMessage(pnf(pluginname));
}
}
@Cmd(minimumArguments = 1)
@Help(value = "查看插件详情", possibleArguments = "<插件名称>")
@Sort(2)
@Async
public void info(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "info", minimumArguments = 1, description = "查看插件详情", possibleArguments = "<插件名称>")
public void info(final InvokeCommandEvent e) {
final String pluginname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
PluginDescriptionFile desc = plugin.getDescription();
final PluginDescriptionFile desc = plugin.getDescription();
sender.sendMessage("§6插件名称: §3" + plugin.getName());
sender.sendMessage("§6插件版本: §3" + StringUtils.substring(plugin.getDescription().getVersion(), 0, 15));
sender.sendMessage("§6插件作者: §3" + StringUtils.join(desc.getAuthors(), " "));
sender.sendMessage("§6插件描述: §3" + (desc.getDescription() == null ? "无" : desc.getDescription()));
sender.sendMessage("§6插件依赖: §3" + (desc.getDepend().isEmpty() ? "无" : ""));
sendStringArray(sender, desc.getDepend(), "§6 - §a");
StrKit.sendStringArray(sender, desc.getDepend(), "§6 - §a");
sender.sendMessage("§6插件软依赖: §3" + (desc.getSoftDepend().isEmpty() ? "无" : ""));
sendStringArray(sender, desc.getSoftDepend(), "§6 - §a");
Map<String, Map<String, Object>> clist = desc.getCommands();
StrKit.sendStringArray(sender, desc.getSoftDepend(), "§6 - §a");
final Map<String, Map<String, Object>> clist = desc.getCommands();
if (clist != null) {
sender.sendMessage("§6插件注册命令: §3" + (clist.isEmpty() ? "无" : ""));
for (Entry<String, Map<String, Object>> entry : clist.entrySet()) {
for (final Entry<String, Map<String, Object>> entry : clist.entrySet()) {
sender.sendMessage("§6 - §a" + entry.getKey());
sendEntryList(sender, "§6 别名: §a", entry.getValue(), "aliases");
sendEntry(sender, "§6 描述: §a", entry.getValue(), "description");
@ -237,10 +119,10 @@ public class YumCommand implements Executor {
sendEntry(sender, "§6 用法: §a", entry.getValue(), "usage");
}
}
List<Permission> plist = desc.getPermissions();
final List<Permission> plist = desc.getPermissions();
if (plist != null) {
sender.sendMessage("§6插件注册权限: " + (plist.isEmpty() ? "无" : ""));
for (Permission perm : plist) {
for (final Permission perm : plist) {
sender.sendMessage("§6 - §a" + perm.getName() + "§6 - §e" + (perm.getDescription().isEmpty() ? "无描述" : perm.getDescription()));
}
}
@ -250,19 +132,20 @@ public class YumCommand implements Executor {
}
}
@Cmd(aliases = "i", minimumArguments = 1)
@Help(value = "安装插件", possibleArguments = "<插件名称>")
@Sort(12)
public void install(final CommandSender sender, final String pluginname, final String pluginversion) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "install", aliases = { "i" }, minimumArguments = 1, description = "安装插件", possibleArguments = "<插件名称>")
public void install(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
final String pluginname = args[0];
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin == null) {
Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() {
@Override
public void run() {
if (pluginversion == null) {
if (args.length < 2) {
YumAPI.installFromYum(sender, pluginname);
} else {
YumAPI.installFromYum(sender, pluginname, pluginversion);
YumAPI.installFromYum(sender, pluginname, args[1]);
}
}
});
@ -271,33 +154,20 @@ public class YumCommand implements Executor {
}
}
@Cmd(aliases = "l")
@Help(value = "列出已安装插件列表")
@Sort(1)
@Async
public void list(CommandSender sender) {
@HandlerCommand(name = "list", aliases = { "l" }, description = "列出已安装插件列表")
public void list(final InvokeCommandEvent e) {
final CommandSender sender = e.getSender();
sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: ");
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
String pname = plugin.getName();
Tellraw fm = Tellraw.create();
fm.text(String.format("§6- %-32s", YumAPI.getPlugman().getFormattedName(plugin, true)));
fm.then(" ");
fm.then(update).cmd_tip("/yum u " + pname, update);
fm.then(" ");
fm.then(unload).cmd_tip("/yum unload " + pname, unload);
fm.then(" ");
fm.then(reload).cmd_tip("/yum re " + pname, reload);
fm.then(" ");
fm.then(delete).cmd_tip("/yum del " + pname, delete);
fm.send(sender);
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
sender.sendMessage("§6- " + YumAPI.getPlugman().getFormattedName(plugin, true));
}
}
@Cmd(minimumArguments = 1)
@Help(value = "载入插件", possibleArguments = "<插件名称>")
@Sort(3)
public void load(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "load", minimumArguments = 1, description = "载入插件", possibleArguments = "<插件名称>")
public void load(final InvokeCommandEvent e) {
final CommandSender sender = e.getSender();
final String pluginname = e.getArgs()[0];
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin == null) {
YumAPI.getPlugman().load(sender, pluginname);
} else {
@ -305,20 +175,27 @@ public class YumCommand implements Executor {
}
}
@Cmd(aliases = "re")
@Help(value = "重载插件", possibleArguments = "<插件名称|all|*>")
@Sort(5)
public void reload(CommandSender sender, String pluginname) {
if (pluginname == null) {
@EventHandler
public void onAdminJoin(final PlayerJoinEvent e) {
if (e.getPlayer().isOp()) {
YumAPI.updateCheck(e.getPlayer());
}
}
@HandlerCommand(name = "reload", aliases = { "re" }, description = "重载插件", possibleArguments = "<插件名称|all|*>")
public void reload(final InvokeCommandEvent e) {
final CommandSender sender = e.getSender();
if (e.getArgs().length == 0) {
ConfigManager.i().reload();
sender.sendMessage("§6重载: §a配置文件已重载!");
return;
}
final String pluginname = e.getArgs()[0];
if (pluginname.equalsIgnoreCase("all") || pluginname.equalsIgnoreCase("*")) {
YumAPI.getPlugman().reloadAll(sender);
return;
}
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
YumAPI.getPlugman().reload(sender, plugin);
} else {
@ -326,91 +203,111 @@ public class YumCommand implements Executor {
}
}
@Cmd(aliases = "r", minimumArguments = 1)
@Help(value = "插件源命令", possibleArguments = "<add|del|all|clean|list> <仓库名称>")
@Sort(16)
@Async
public void repo(CommandSender sender, String cmd, String arg1) {
switch (cmd) {
case "add":
if (arg1 != null) {
if (YumAPI.getRepo().addRepositories(sender, arg1)) {
String reponame = YumAPI.getRepo().getRepoCache(arg1).name;
sender.sendMessage("§6仓库: §a源仓库 §e" + reponame + " §a的插件信息已缓存!");
@HandlerCommand(name = "repo", aliases = { "r" }, minimumArguments = 1, description = "插件源命令", possibleArguments = "<add|del|all|clean|list> <仓库名称>")
public void repo(final InvokeCommandEvent 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源地址未找到仓库信息或当前地址已缓存!");
sender.sendMessage("§6仓库: §c请输入需要添加的源地址!");
}
} else {
sender.sendMessage("§6仓库: §c请输入需要添加的源地址!");
}
break;
case "del":
if (arg1 != null) {
Repositories delrepo = YumAPI.getRepo().getRepoCache(arg1);
if (delrepo != null) {
YumAPI.getRepo().delRepositories(sender, arg1);
sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!");
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源地址未找到!");
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;
}
break;
case "delall":
YumAPI.getRepo().getRepoCache().getRepos().clear();
sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!");
break;
case "list":
sender.sendMessage("§6仓库: §b缓存的插件信息如下 ");
sendStringArray(sender, YumAPI.getRepo().getAllPluginsInfo());
break;
case "all":
sender.sendMessage("§6仓库: §b缓存的仓库信息如下 ");
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;
}
});
}
/**
*
*
* @param sender
*
* @param prefix
*
* @param map
*
* @param key
* Key
*/
public void sendEntry(final CommandSender sender, final String prefix, final Map<String, Object> map, final String key) {
final Object value = map.get(key);
if (value != null) {
sender.sendMessage(prefix + (String) value);
}
}
@Cmd(aliases = "s", minimumArguments = 1)
@Help(value = "从BukkitDev搜索插件", possibleArguments = "插件名称")
@Sort(11)
@Async
public void search(CommandSender sender, String pname) {
if (pname.length() < 3) {
sender.sendMessage(searchLimit);
return;
}
sender.sendMessage(String.format(searching, pname));
List<Projects> list = Projects.parseList(HttpKit.get(String.format(BukkitDev.SEARCH, pname.toLowerCase())));
if (list.isEmpty()) {
sender.sendMessage(String.format(notFoundFromBukkit, pname));
return;
}
sender.sendMessage(String.format(result, pname));
sender.sendMessage(bukkitListPrefix);
for (Projects p : list) {
Tellraw fm = Tellraw.create();
fm.text(String.format(bukkitList, p.id, p.name, p.stage));
fm.then(" ");
fm.then(look).cmd_tip("/yum br look " + p.id, look);
fm.send(sender);
/**
*
*
* @param sender
*
* @param prefix
*
* @param map
*
* @param key
* Key
*/
@SuppressWarnings("unchecked")
public void sendEntryList(final CommandSender sender, final String prefix, final Map<String, Object> map, final String key) {
final List<String> values = (List<String>) map.get(key);
if (values != null) {
for (final String value : values) {
sender.sendMessage(prefix + value);
}
}
}
@Cmd(minimumArguments = 1)
@Help(value = "卸载插件", possibleArguments = "<插件名称>")
@Sort(4)
public void unload(CommandSender sender, String pluginname) {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
@HandlerCommand(name = "unload", minimumArguments = 1, description = "卸载插件", possibleArguments = "<插件名称>")
public void unload(final InvokeCommandEvent e) {
final String pluginname = e.getArgs()[0];
final CommandSender sender = e.getSender();
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
if (plugin != null) {
YumAPI.getPlugman().unload(sender, plugin);
} else {
@ -418,144 +315,75 @@ public class YumCommand implements Executor {
}
}
@Cmd(aliases = "u")
@Help(value = "更新插件或缓存", possibleArguments = "[插件名称] [插件版本]")
@Sort(13)
@Async
public void update(CommandSender sender, String argstring) {
if (argstring == null) {
@HandlerCommand(name = "update", aliases = { "u" }, description = "更新插件或缓存", possibleArguments = "[插件名称] [插件版本]")
public void update(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
switch (args.length) {
case 0:
YumAPI.getRepo().updateRepositories(sender);
sender.sendMessage("§6仓库: §a仓库缓存数据已更新!");
return;
}
String[] args = argstring.split(" ");
switch (args.length) {
case 1:
case 2:
String pluginname = args[0];
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
sender.sendMessage("§a开始更新插件: " + pluginname);
if (plugin != null) {
if (args.length < 2) {
YumAPI.updateFromYum(sender, plugin);
} else {
YumAPI.updateFromYum(sender, plugin, args[1]);
}
} else {
sender.sendMessage("§c插件" + pluginname + "未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!");
}
break;
default:
sender.sendMessage("§c命令参数错误!");
}
}
@Cmd(aliases = "ug")
@Help(value = "升级或安装插件", possibleArguments = "[插件名称]")
@Sort(15)
public void upgrade(CommandSender sender, String pluginname) {
if (pluginname == null) {
YumAPI.getPlugman().upgrade(sender);
} else {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
sender.sendMessage("§a开始升级插件: §b" + pluginname);
break;
case 1:
case 2:
final String pluginname = args[0];
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
sender.sendMessage("§a开始更新插件: " + pluginname);
if (plugin != null) {
YumAPI.upgrade(sender, plugin);
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]);
}
}
});
} else {
sender.sendMessage("§c错误: §b插件 " + pluginname + " §c未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!");
sender.sendMessage("§c插件" + pluginname + "未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!");
}
break;
default:
sender.sendMessage("§c命令参数错误!");
}
}
private String pnf(String pname) {
@HandlerCommand(name = "updateall", aliases = { "ua" }, description = "更新所有可更新插件")
public void updateall(final InvokeCommandEvent e) {
Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() {
@Override
public void run() {
YumAPI.updateAll(e.getSender());
}
});
}
@HandlerCommand(name = "upgrade", aliases = { "ug" }, description = "升级或载入插件", possibleArguments = "[插件名称]")
public void upgrade(final InvokeCommandEvent 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 + "!");
}
}
}
});
}
private String pnf(final String pname) {
return String.format("§4错误: §c插件 §b %s §c不存在或已卸载!", pname);
}
/**
*
*
* @param sender
*
* @param prefix
*
* @param map
*
* @param key
* Key
*/
private void sendEntry(CommandSender sender, String prefix, Map<String, Object> map, String key) {
Object value = map.get(key);
if (value != null) {
sender.sendMessage(prefix + value);
}
}
/**
*
*
* @param sender
*
* @param prefix
*
* @param map
*
* @param key
* Key
*/
private void sendEntryList(CommandSender sender, String prefix, Map<String, Object> map, String key) {
List<String> values = (List<String>) map.get(key);
if (values != null) {
for (String value : values) {
sender.sendMessage(prefix + value);
}
}
}
/**
*
*
* @param sender
*
* @param msg
*
*/
public static void sendStringArray(CommandSender sender, Collection<String> msg) {
for (String string : msg) {
sender.sendMessage(string);
}
}
/**
*
*
* @param sender
*
* @param msg
*
* @param prefix
*
*/
public static void sendStringArray(CommandSender sender, Collection<String> msg, String prefix) {
for (String string : msg) {
sender.sendMessage(prefix + string);
}
}
/**
*
*
* @param sender
*
* @param msg
*
* @param prefix
*
* @param suffix
*
*/
public static void sendStringArray(CommandSender sender, Collection<String> msg, String prefix, String suffix) {
for (String string : msg) {
sender.sendMessage(prefix + string + suffix);
}
}
}

View File

@ -1,84 +1,83 @@
package pw.yumc.Yum.events;
import java.net.URI;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.Plugin;
public class PluginNetworkEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private boolean isPrimaryThread;
private Plugin plugin;
private boolean cancel;
private URI url;
public static HandlerList getHandlerList() {
return handlers;
}
/**
*
*
* @param plugin
*
* @param url
*
* @param isPrimaryThread
* 线
*/
public PluginNetworkEvent(Plugin plugin, URI url, boolean isPrimaryThread) {
super(!isPrimaryThread);
this.plugin = plugin;
this.url = url;
this.isPrimaryThread = isPrimaryThread;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
/**
* @return
*/
public Plugin getPlugin() {
return plugin;
}
/**
* @return
*/
public URI getUrl() {
return url;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* @return 线
*/
public boolean isPrimaryThread() {
return isPrimaryThread;
}
@Override
public void setCancelled(boolean value) {
cancel = value;
}
/**
* @param url
* URL
*/
public void setUrl(URI url) {
this.url = url;
}
}
package pw.yumc.Yum.events;
import java.net.URI;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.Plugin;
public class PluginNetworkEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final boolean isPrimaryThread;
private final Plugin plugin;
private boolean cancel;
private URI url;
public static HandlerList getHandlerList() {
return handlers;
}
/**
*
*
* @param plugin
*
* @param url
*
* @param isMainThread
* 线
*/
public PluginNetworkEvent(final Plugin plugin, final URI url, final boolean isPrimaryThread) {
this.plugin = plugin;
this.url = url;
this.isPrimaryThread = isPrimaryThread;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
/**
* @return
*/
public Plugin getPlugin() {
return plugin;
}
/**
* @return
*/
public URI getUrl() {
return url;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* @return 线
*/
public boolean isPrimaryThread() {
return isPrimaryThread;
}
@Override
public void setCancelled(final boolean value) {
cancel = value;
}
/**
* @param url
* URL
*/
public void setUrl(final URI url) {
this.url = url;
}
}

View File

@ -1,5 +1,6 @@
/*
* Updater for Bukkit.
*
* This class provides the means to safely and easily update a plugin, or check to see if it is updated using dev.bukkit.org
*/
@ -45,20 +46,20 @@ import org.json.simple.JSONValue;
*/
public class BukkitUpdater extends Updater {
private static String TITLE_VALUE = "name"; // Gets remote file's title
private static String LINK_VALUE = "downloadUrl"; // Gets remote file's download link
private static String TYPE_VALUE = "releaseType"; // Gets remote file's release type
private static final String TITLE_VALUE = "name"; // Gets remote file's title
private static final String LINK_VALUE = "downloadUrl"; // Gets remote file's download link
private static final String TYPE_VALUE = "releaseType"; // Gets remote file's release type
private static String VERSION_VALUE = "gameVersion"; // Gets remote file's build version
private static Object FILE_NAME = "fileName"; // Gets remote file's name
private static String QUERY = "/servermods/files?projectIds="; // Path to GET
private static String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed
private static final String VERSION_VALUE = "gameVersion"; // Gets remote file's build version
private static final Object FILE_NAME = "fileName"; // Gets remote file's name
private static final String QUERY = "/servermods/files?projectIds="; // Path to GET
private static final String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed
private static int BYTE_SIZE = 1024; // Used for downloading files
private static final int BYTE_SIZE = 1024; // Used for downloading files
// Update information
// private static String BUKKIT_DEV_SLUG = "protocollib";
// private static int BUKKIT_DEV_ID = 45564;
// private static final String BUKKIT_DEV_SLUG = "protocollib";
// private static final int BUKKIT_DEV_ID = 45564;
private URL url; // Connecting to RSS
private File file; // The plugin's file
@ -87,18 +88,18 @@ public class BukkitUpdater extends Updater {
* @param announce
* True if the program should announce the progress of new updates in console
*/
public BukkitUpdater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
public BukkitUpdater(final Plugin plugin, final int id, final File file, final UpdateType type, final boolean announce) {
super(plugin, type, announce);
this.file = file;
this.id = id;
this.updateFolder = plugin.getServer().getUpdateFolder();
File dataFolder = plugin.getDataFolder();
final File dataFolder = plugin.getDataFolder();
if (dataFolder != null) {
File pluginFile = plugin.getDataFolder().getParentFile();
File updaterFile = new File(pluginFile, "Updater");
File updaterConfigFile = new File(updaterFile, "config.yml");
final File pluginFile = plugin.getDataFolder().getParentFile();
final File updaterFile = new File(pluginFile, "Updater");
final File updaterConfigFile = new File(updaterFile, "config.yml");
if (!updaterFile.exists()) {
updaterFile.mkdir();
@ -106,9 +107,8 @@ public class BukkitUpdater extends Updater {
if (!updaterConfigFile.exists()) {
try {
updaterConfigFile.createNewFile();
} catch (IOException e) {
plugin.getLogger().severe(
"The updater could not create a configuration in " + updaterFile.getAbsolutePath());
} catch (final IOException e) {
plugin.getLogger().severe("The updater could not create a configuration in " + updaterFile.getAbsolutePath());
e.printStackTrace();
}
}
@ -128,9 +128,8 @@ public class BukkitUpdater extends Updater {
this.config.options().copyDefaults(true);
try {
this.config.save(updaterConfigFile);
} catch (IOException e) {
plugin.getLogger().severe(
"The updater could not save the configuration in " + updaterFile.getAbsolutePath());
} catch (final IOException e) {
plugin.getLogger().severe("The updater could not save the configuration in " + updaterFile.getAbsolutePath());
e.printStackTrace();
}
}
@ -150,7 +149,7 @@ public class BukkitUpdater extends Updater {
try {
this.url = new URL(BukkitUpdater.HOST + BukkitUpdater.QUERY + id);
} catch (MalformedURLException e) {
} catch (final MalformedURLException e) {
plugin.getLogger().severe("The project ID provided for updating, " + id + " is invalid.");
this.result = UpdateResult.FAIL_BADID;
e.printStackTrace();
@ -167,7 +166,7 @@ public class BukkitUpdater extends Updater {
*/
/*
* private boolean hasTag(String version) {
* for (String string : BukkitUpdater.NO_UPDATE_TAG) {
* for (final String string : BukkitUpdater.NO_UPDATE_TAG) {
* if (version.contains(string)) {
* return true;
* }
@ -178,7 +177,7 @@ public class BukkitUpdater extends Updater {
public boolean read() {
try {
URLConnection conn = this.url.openConnection();
final URLConnection conn = this.url.openConnection();
conn.setConnectTimeout(5000);
if (this.apiKey != null) {
@ -187,10 +186,10 @@ public class BukkitUpdater extends Updater {
conn.addRequestProperty("User-Agent", "Updater (by Gravity)");
conn.setDoOutput(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String response = reader.readLine();
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
final String response = reader.readLine();
JSONArray array = (JSONArray) JSONValue.parse(response);
final JSONArray array = (JSONArray) JSONValue.parse(response);
if (array.size() == 0) {
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
@ -198,7 +197,7 @@ public class BukkitUpdater extends Updater {
return false;
}
JSONObject jsonObject = (JSONObject) array.get(array.size() - 1);
final JSONObject jsonObject = (JSONObject) array.get(array.size() - 1);
this.versionFileName = (String) jsonObject.get(BukkitUpdater.FILE_NAME);
this.versionName = (String) jsonObject.get(BukkitUpdater.TITLE_VALUE);
this.versionLink = (String) jsonObject.get(BukkitUpdater.LINK_VALUE);
@ -206,16 +205,14 @@ public class BukkitUpdater extends Updater {
this.versionGameVersion = (String) jsonObject.get(BukkitUpdater.VERSION_VALUE);
return true;
} catch (IOException e) {
} catch (final IOException e) {
if (e.getMessage().contains("HTTP response code: 403")) {
this.plugin.getLogger().warning(
"dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
this.plugin.getLogger().warning("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
this.plugin.getLogger().warning("Please double-check your configuration to ensure it is correct.");
this.result = UpdateResult.FAIL_APIKEY;
} else {
this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
this.plugin.getLogger().warning(
"If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
this.result = UpdateResult.FAIL_DBO;
}
e.printStackTrace();
@ -231,7 +228,7 @@ public class BukkitUpdater extends Updater {
* - the update type.
*/
@Override
public void start(UpdateType type) {
public void start(final UpdateType type) {
waitForThread();
this.type = type;
@ -242,9 +239,11 @@ public class BukkitUpdater extends Updater {
/**
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
*/
private boolean pluginFile(String name) {
for (File file : new File("plugins").listFiles()) {
if (file.getName().equals(name)) { return true; }
private boolean pluginFile(final String name) {
for (final File file : new File("plugins").listFiles()) {
if (file.getName().equals(name)) {
return true;
}
}
return false;
}
@ -252,7 +251,7 @@ public class BukkitUpdater extends Updater {
/**
* Save an update from dev.bukkit.org into the server's update folder.
*/
private void saveFile(File folder, String file, String u) {
private void saveFile(final File folder, final String file, final String u) {
if (!folder.exists()) {
folder.mkdir();
}
@ -260,12 +259,12 @@ public class BukkitUpdater extends Updater {
FileOutputStream fout = null;
try {
// Download the file
URL url = new URL(u);
int fileLength = url.openConnection().getContentLength();
final URL url = new URL(u);
final int fileLength = url.openConnection().getContentLength();
in = new BufferedInputStream(url.openStream());
fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
final byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
int count;
if (this.announce) {
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
@ -274,19 +273,19 @@ public class BukkitUpdater extends Updater {
while ((count = in.read(data, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
downloaded += count;
fout.write(data, 0, count);
int percent = (int) ((downloaded * 100) / fileLength);
final int percent = (int) ((downloaded * 100) / fileLength);
if (this.announce && ((percent % 10) == 0)) {
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
}
}
// Just a quick check to make sure we didn't leave any files from last time...
for (File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
for (final File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
if (xFile.getName().endsWith(".zip")) {
xFile.delete();
}
}
// Check to see if it's a zip file, if it is, unzip it.
File dFile = new File(folder.getAbsolutePath() + "/" + file);
final File dFile = new File(folder.getAbsolutePath() + "/" + file);
if (dFile.getName().endsWith(".zip")) {
// Unzip
this.unzip(dFile.getCanonicalPath());
@ -294,7 +293,7 @@ public class BukkitUpdater extends Updater {
if (this.announce) {
this.plugin.getLogger().info("Finished updating.");
}
} catch (Exception ex) {
} catch (final Exception ex) {
this.plugin.getLogger().warning("The auto-updater tried to download a new update, but was unsuccessful.");
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
} finally {
@ -305,7 +304,7 @@ public class BukkitUpdater extends Updater {
if (fout != null) {
fout.close();
}
} catch (Exception ex) {
} catch (final Exception ex) {
}
}
}
@ -313,10 +312,10 @@ public class BukkitUpdater extends Updater {
/**
* Part of Zip-File-Extractor, modified by Gravity for use with Bukkit
*/
private void unzip(String file) {
private void unzip(final String file) {
try {
File fSourceZip = new File(file);
String zipPath = file.substring(0, file.length() - 4);
final File fSourceZip = new File(file);
final String zipPath = file.substring(0, file.length() - 4);
ZipFile zipFile = new ZipFile(fSourceZip);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
@ -326,21 +325,20 @@ public class BukkitUpdater extends Updater {
if (entry.isDirectory()) {
continue;
}
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
int b;
byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
FileOutputStream fos = new FileOutputStream(destinationFilePath);
BufferedOutputStream bos = new BufferedOutputStream(fos, BukkitUpdater.BYTE_SIZE);
final byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
final BufferedOutputStream bos = new BufferedOutputStream(fos, BukkitUpdater.BYTE_SIZE);
while ((b = bis.read(buffer, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
bos.write(buffer, 0, b);
}
bos.flush();
bos.close();
bis.close();
String name = destinationFilePath.getName();
final String name = destinationFilePath.getName();
if (name.endsWith(".jar") && this.pluginFile(name)) {
destinationFilePath.renameTo(
new File(this.plugin.getDataFolder().getParent(), this.updateFolder + "/" + name));
destinationFilePath.renameTo(new File(this.plugin.getDataFolder().getParent(), this.updateFolder + "/" + name));
}
entry = null;
destinationFilePath = null;
@ -350,15 +348,15 @@ public class BukkitUpdater extends Updater {
zipFile = null;
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
for (File dFile : new File(zipPath).listFiles()) {
for (final File dFile : new File(zipPath).listFiles()) {
if (dFile.isDirectory()) {
if (this.pluginFile(dFile.getName())) {
File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); // Get current dir
File[] contents = oFile.listFiles(); // List of existing files in the current dir
for (File cFile : dFile.listFiles()) // Loop through all the files in the new dir
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); // Get current dir
final File[] contents = oFile.listFiles(); // List of existing files in the current dir
for (final File cFile : dFile.listFiles()) // Loop through all the files in the new dir
{
boolean found = false;
for (File xFile : contents) // Loop through contents to see if it exists
for (final File xFile : contents) // Loop through contents to see if it exists
{
if (xFile.getName().equals(cFile.getName())) {
found = true;
@ -379,7 +377,7 @@ public class BukkitUpdater extends Updater {
}
new File(zipPath).delete();
fSourceZip.delete();
} catch (IOException ex) {
} catch (final IOException ex) {
this.plugin.getLogger().warning("The auto-updater tried to unzip a new update file, but was unsuccessful.");
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
ex.printStackTrace();
@ -400,11 +398,11 @@ public class BukkitUpdater extends Updater {
}
}
}
} catch (Exception e) {
} catch (final Exception e) {
// Any generic error will be handled here
} finally {
// Invoke the listeners on the main thread
for (Runnable listener : listeners) {
for (final Runnable listener : listeners) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
}
}
@ -412,8 +410,8 @@ public class BukkitUpdater extends Updater {
private void performUpdate() {
if ((BukkitUpdater.this.versionLink != null) && (BukkitUpdater.this.type != UpdateType.NO_DOWNLOAD)) {
File pluginFolder = plugin.getDataFolder().getParentFile();
File destinationFolder = new File(pluginFolder, updateFolder);
final File pluginFolder = plugin.getDataFolder().getParentFile();
final File destinationFolder = new File(pluginFolder, updateFolder);
String name = BukkitUpdater.this.file.getName();
// If it's a zip file, it shouldn't be downloaded as the plugin's name

View File

@ -33,22 +33,21 @@ import com.google.common.io.Closer;
* @author dmulloy2
*/
public class SpigotUpdater extends Updater {
private static String PROTOCOL = "https://";
public final class SpigotUpdater extends Updater {
private static final String PROTOCOL = "https://";
private static String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
private static final String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
private static String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
private static final String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
private static String ACTION = "POST";
private static final String ACTION = "POST";
private static int ID = 1997;
private static final int ID = 1997;
private static byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource="
+ ID).getBytes(Charsets.UTF_8);
private static final byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=" + ID).getBytes(Charsets.UTF_8);
private String remoteVersion;
public SpigotUpdater(Plugin plugin, UpdateType type, boolean announce) {
public SpigotUpdater(final Plugin plugin, final UpdateType type, final boolean announce) {
super(plugin, type, announce);
}
@ -64,15 +63,15 @@ public class SpigotUpdater extends Updater {
}
public String getSpigotVersion() throws IOException {
Closer closer = Closer.create();
final Closer closer = Closer.create();
try {
HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
final HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
con.setDoOutput(true);
con.setRequestMethod(ACTION);
con.getOutputStream().write(API_KEY);
InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
BufferedReader br = closer.register(new BufferedReader(isr));
final InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
final BufferedReader br = closer.register(new BufferedReader(isr));
return br.readLine();
} finally {
closer.close();
@ -80,7 +79,7 @@ public class SpigotUpdater extends Updater {
}
@Override
public void start(UpdateType type) {
public void start(final UpdateType type) {
waitForThread();
this.type = type;
this.thread = new Thread(new SpigotUpdateRunnable());
@ -91,17 +90,17 @@ public class SpigotUpdater extends Updater {
@Override
public void run() {
try {
String version = getSpigotVersion();
final String version = getSpigotVersion();
remoteVersion = version;
if (versionCheck(version)) {
result = UpdateResult.SPIGOT_UPDATE_AVAILABLE;
} else {
result = UpdateResult.NO_UPDATE;
}
} catch (Throwable ex) {
} catch (final Throwable ex) {
} finally {
// Invoke the listeners on the main thread
for (Runnable listener : listeners) {
for (final Runnable listener : listeners) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
}
}

View File

@ -45,7 +45,7 @@ public abstract class Updater {
protected List<Runnable> listeners = new CopyOnWriteArrayList<Runnable>();
public static Updater create(Plugin protocolLib, int id, File file, UpdateType type, boolean announce) {
public static Updater create(final Plugin protocolLib, final int id, final File file, final UpdateType type, final boolean announce) {
// if (Util.isUsingSpigot()) {
return new SpigotUpdater(protocolLib, type, announce);
// } else {
@ -53,7 +53,7 @@ public abstract class Updater {
// }
}
protected Updater(Plugin plugin, UpdateType type, boolean announce) {
protected Updater(final Plugin plugin, final UpdateType type, final boolean announce) {
this.plugin = plugin;
this.type = type;
this.announce = announce;
@ -67,7 +67,7 @@ public abstract class Updater {
* @param listener
* - the listener to add.
*/
public void addListener(Runnable listener) {
public void addListener(final Runnable listener) {
listeners.add(Preconditions.checkNotNull(listener, "listener cannot be NULL"));
}
@ -129,7 +129,7 @@ public abstract class Updater {
* - the listener to remove.
* @return TRUE if the listener was removed, FALSE otherwise.
*/
public boolean removeListener(Runnable listener) {
public boolean removeListener(final Runnable listener) {
return listeners.remove(listener);
}
@ -146,7 +146,7 @@ public abstract class Updater {
public abstract void start(UpdateType type);
public boolean versionCheck(String title) {
public boolean versionCheck(final String title) {
if (this.type != UpdateType.NO_VERSION_CHECK) {
String version = this.plugin.getDescription().getVersion();
@ -156,7 +156,7 @@ public abstract class Updater {
version = version.substring(0, version.indexOf("-"));
}
String[] splitTitle = title.split(" ");
final String[] splitTitle = title.split(" ");
String remoteVersion;
if (splitTitle.length == 2) {
@ -165,13 +165,9 @@ public abstract class Updater {
remoteVersion = splitTitle[0];
} else {
// The file's name did not contain the string 'vVersion'
String authorInfo = this.plugin.getDescription().getAuthors().size() == 0 ? ""
: " (" + this.plugin.getDescription().getAuthors().get(0) + ")";
this.plugin.getLogger().warning(
"The author of this plugin " + authorInfo + " has misconfigured their Auto Update system");
this.plugin
.getLogger()
.warning("File versions should follow the format 'PluginName VERSION[-SNAPSHOT]'");
final String authorInfo = this.plugin.getDescription().getAuthors().size() == 0 ? "" : " (" + this.plugin.getDescription().getAuthors().get(0) + ")";
this.plugin.getLogger().warning("The author of this plugin " + authorInfo + " has misconfigured their Auto Update system");
this.plugin.getLogger().warning("File versions should follow the format 'PluginName VERSION[-SNAPSHOT]'");
this.plugin.getLogger().warning("Please notify the author of this error.");
this.result = BukkitUpdater.UpdateResult.FAIL_NOVERSION;
return false;
@ -182,7 +178,7 @@ public abstract class Updater {
remoteVersion = remoteVersion.substring(1);
}
String localVersion = plugin.getDescription().getVersion();
final String localVersion = plugin.getDescription().getVersion();
if (devBuild && remoteVersion.equals(localVersion)) {
// They're using a dev build and this version has been released
@ -200,7 +196,7 @@ public abstract class Updater {
if (thread != null && thread.isAlive()) {
try {
thread.join();
} catch (InterruptedException ex) {
} catch (final InterruptedException ex) {
ex.printStackTrace();
}
}
@ -259,9 +255,9 @@ public abstract class Updater {
*/
SPIGOT_UPDATE_AVAILABLE("The updater found an update: %s (Running %s). Download at %s");
private String description;
private final String description;
private UpdateResult(String description) {
private UpdateResult(final String description) {
this.description = description;
}

View File

@ -1,86 +1,75 @@
package pw.yumc.Yum.inject;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import pw.yumc.Yum.commands.MonitorCommand;
import pw.yumc.Yum.managers.MonitorManager;
import pw.yumc.YumCore.kit.StrKit;
import pw.yumc.YumCore.reflect.Reflect;
import java.util.Collections;
import java.util.List;
public class CommandInjector implements TabExecutor {
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 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注入能耗监控失败!";
private static String plugin_is_null = "插件不得为NULL!";
private CommandExecutor originalExecutor;
private TabCompleter originalCompleter;
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;
private Plugin plugin;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
public class CommandInjector implements TabExecutor {
private final CommandExecutor originalExecutor;
private final TabCompleter originalCompleter;
public long totalTime;
public int count;
public CommandInjector(CommandExecutor originalCommandExecutor, TabCompleter originalTabCompleter, Plugin plugin) {
public CommandInjector(final CommandExecutor originalCommandExecutor, final TabCompleter originalTabCompleter) {
this.originalExecutor = originalCommandExecutor;
this.originalCompleter = originalTabCompleter;
this.plugin = plugin;
}
public static void inject(Plugin plugin) {
Validate.notNull(plugin, plugin_is_null);
try {
PluginManager pluginManager = Bukkit.getPluginManager();
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
for (Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
PluginCommand pluginCommand = (PluginCommand) command;
Plugin cp = pluginCommand.getPlugin();
if (cp.equals(plugin)) {
CommandExecutor executor = Reflect.on(command).get("executor");
if (executor instanceof CommandInjector) { return; }
TabCompleter completer = Reflect.on(command).get("completer");
CommandInjector commandInjector = new CommandInjector(executor, completer, plugin);
Reflect.on(command).set("executor", commandInjector);
Reflect.on(command).set("completer", commandInjector);
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);
}
}
} catch (Throwable e) {
MonitorManager.log(String.format(inject_error, plugin.getName()));
}
}
public static void uninject(Plugin plugin) {
Validate.notNull(plugin, plugin_is_null);
try {
PluginManager pluginManager = Bukkit.getPluginManager();
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
for (Command command : commandMap.getCommands()) {
if (command instanceof PluginCommand) {
PluginCommand pluginCommand = (PluginCommand) command;
Plugin cp = pluginCommand.getPlugin();
if (cp.equals(plugin)) {
CommandExecutor executor = Reflect.on(command).get("executor");
if (executor instanceof CommandInjector) {
CommandInjector injected = (CommandInjector) executor;
Reflect.on(command).set("executor", injected.getOriginalExecutor());
}
TabCompleter completer = Reflect.on(command).get("completer");
if (completer instanceof CommandInjector) {
CommandInjector injected = (CommandInjector) completer;
Reflect.on(command).set("completer", injected.getOriginalCompleter());
}
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());
}
}
}
} catch (Throwable ignored) {
}
}
@ -93,38 +82,26 @@ public class CommandInjector implements TabExecutor {
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
long start = System.nanoTime();
boolean result = originalExecutor.onCommand(sender, command, label, args);
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, sender.getName(), plugin.getName(), label, StrKit.join(args, " "), lagms, avglagms));
}
MonitorManager.addCmd(plugin.getName(), lag);
return result;
} catch (Throwable e) {
while (e.getCause() != null) {
e = e.getCause();
}
MonitorCommand.lastError = e;
MonitorManager.sendError(sender, plugin, e);
MonitorManager.printThrowable(plugin, String.format(err, sender.getName(), plugin.getName(), label, StrKit.join(args, " ")), e);
}
return false;
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
final long start = System.nanoTime();
// TODO 当操作大于10ms的时候添加一个Lag提示
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(CommandSender sender, Command command, String alias, String[] args) {
if (originalCompleter == null) { return Collections.emptyList(); }
long start = System.nanoTime();
List<String> result = originalCompleter.onTabComplete(sender, command, alias, args);
long end = System.nanoTime();
public List<String> onTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
if (originalCompleter == null) {
return Collections.emptyList();
}
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

@ -1,6 +1,9 @@
package pw.yumc.Yum.inject;
import org.apache.commons.lang.Validate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.HandlerList;
@ -9,85 +12,67 @@ import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.TimedRegisteredListener;
import pw.yumc.Yum.commands.MonitorCommand;
import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.Yum.managers.MonitorManager;
import pw.yumc.YumCore.reflect.Reflect;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.citycraft.PluginHelper.ext.kit.Reflect;
import cn.citycraft.PluginHelper.kit.PluginKit;
public class ListenerInjector implements EventExecutor {
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注入能耗监控失败 §6注入类: §3%s!";
private static String plugin_is_null = "插件不得为NULL!";
private EventExecutor originalExecutor;
private final String prefix = "§6[§bYum §a事件监控§6] ";
private final EventExecutor originalExecutor;
private Plugin plugin;
private final Plugin plugin;
public Map<String, Long> eventTotalTime = new ConcurrentHashMap<>();
public Map<String, Integer> eventCount = new ConcurrentHashMap<>();
public Map<String, Long> eventTotalTime;
public Map<String, Integer> eventCount;
public ListenerInjector(EventExecutor originalExecutor, Plugin plugin) {
public ListenerInjector(final EventExecutor originalExecutor, final Plugin plugin) {
this.originalExecutor = originalExecutor;
this.plugin = plugin;
eventTotalTime = new HashMap<>();
eventCount = new HashMap<>();
}
public static void inject(Plugin plugin) {
Validate.notNull(plugin, plugin_is_null);
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (RegisteredListener listener : listeners) {
try {
if (listener instanceof TimedRegisteredListener) { return; }
// 兼容PerWorldPlugin
if (listener.getClass().getName().contains("PWPRegisteredListener")) {
Field f = Reflect.getDeclaredField(RegisteredListener.class, "executor");
f.setAccessible(true);
EventExecutor originalExecutor = (EventExecutor) f.get(listener);
if (originalExecutor instanceof ListenerInjector) { return; }
ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
f.set(listener, listenerInjector);
} else {
EventExecutor originalExecutor = Reflect.on(listener).get("executor");
if (originalExecutor instanceof ListenerInjector) { return; }
ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
Reflect.on(listener).set("executor", listenerInjector);
}
} catch (Throwable e) {
MonitorManager.log(String.format(inject_error, plugin.getName(), listener.getClass().getName()));
e.printStackTrace();
public static void inject(final Plugin plugin) {
final List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (final RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) {
return;
}
final EventExecutor originalExecutor = Reflect.on(listener).get("executor");
if (originalExecutor instanceof ListenerInjector) {
return;
}
final ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
Reflect.on(listener).set("executor", listenerInjector);
}
}
public static void uninject(Plugin plugin) {
Validate.notNull(plugin, plugin_is_null);
try {
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) { return; }
EventExecutor executor = Reflect.on(listener).get("executor");
if (executor instanceof ListenerInjector) {
Reflect.on(listener).set("executor", ((ListenerInjector) executor).getOriginalExecutor());
}
public static void uninject(final Plugin plugin) {
final List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
for (final RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) {
return;
}
final EventExecutor executor = Reflect.on(listener).get("executor");
if (executor instanceof ListenerInjector) {
Reflect.on(listener).set("executor", ((ListenerInjector) executor).getOriginalExecutor());
}
} catch (Throwable ignored) {
}
}
@Override
public void execute(Listener listener, Event event) throws EventException {
public void execute(final Listener listener, final Event event) throws EventException {
try {
if (!event.isAsynchronous()) {
long start = System.nanoTime();
final long start = System.nanoTime();
// TODO 当操作大于10ms的时候添加一个Lag提示
originalExecutor.execute(listener, event);
long end = System.nanoTime();
String en = event.getEventName();
long lag = end - start;
final long end = System.nanoTime();
final String en = event.getEventName();
final long lag = end - start;
if (lag / 1000000 > 10) {
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时§c耗时超过 §410ms!");
}
if (eventTotalTime.containsKey(en)) {
eventTotalTime.put(en, eventTotalTime.get(en) + lag);
eventCount.put(en, eventCount.get(en) + 1);
@ -95,12 +80,6 @@ public class ListenerInjector implements EventExecutor {
eventTotalTime.put(en, end - start);
eventCount.put(en, 1);
}
long lagms = lag / 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())) {
MonitorManager.lagTip(String.format(warn, plugin.getName(), event.getEventName(), lagms, avglagms));
}
MonitorManager.addEvent(plugin.getName(), lag);
} else {
originalExecutor.execute(listener, event);
}
@ -108,8 +87,13 @@ public class ListenerInjector implements EventExecutor {
while (e.getCause() != null) {
e = e.getCause();
}
MonitorCommand.lastError = e;
MonitorManager.printThrowable(plugin, String.format(err, plugin.getName(), event.getEventName()), e);
PluginKit.sc(prefix + "§6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时发生异常 §c" + e.getClass().getName() + ": " + e.getMessage());
PluginKit.sc("§c错误信息如下:");
final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length;
for (int i = 0; i < l; i++) {
final StackTraceElement ste = e.getStackTrace()[i];
PluginKit.sc(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)");
}
}
}

View File

@ -1,91 +1,54 @@
package pw.yumc.Yum.inject;
import org.apache.commons.lang.Validate;
import java.util.List;
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;
import java.util.List;
import cn.citycraft.PluginHelper.ext.kit.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;
private final Runnable originalTask;
public long totalTime;
public int count;
public TaskInjector(Runnable originalTask, Plugin plugin) {
public TaskInjector(final Runnable originalTask) {
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);
public static void inject(final Plugin plugin) {
final BukkitScheduler scheduler = Bukkit.getScheduler();
final List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
for (final BukkitTask pendingTask : pendingTasks) {
// 忽略异步任务
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
final Runnable originalTask = Reflect.on(pendingTask).get("task");
if (originalTask instanceof TaskInjector) {
return;
}
final TaskInjector taskInjector = new TaskInjector(originalTask);
Reflect.on(pendingTask).set("task", 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());
}
public static void uninject(final Plugin plugin) {
final BukkitScheduler scheduler = Bukkit.getScheduler();
final List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
for (final BukkitTask pendingTask : pendingTasks) {
// 忽略异步任务
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
final Runnable originalTask = Reflect.on(pendingTask).get("task");
if (originalTask instanceof TaskInjector) {
Reflect.on(pendingTask).set("task", ((TaskInjector) originalTask).getOriginalTask());
}
}
} catch (Throwable ignored) {
}
}
@ -95,25 +58,11 @@ public class TaskInjector implements Runnable {
@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(plugin, String.format(err, plugin.getName(), taskName), e);
}
final long start = System.nanoTime();
// TODO 当操作大于10ms的时候添加一个Lag提示
originalTask.run();
final long end = System.nanoTime();
totalTime += end - start;
count++;
}
}

View File

@ -6,12 +6,9 @@ import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import cn.citycraft.PluginHelper.kit.PKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.Yum.managers.MonitorManager;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.kit.PKit;
/**
*
@ -21,24 +18,17 @@ import pw.yumc.YumCore.kit.PKit;
public class PluginListener implements Listener {
public PluginListener() {
Bukkit.getPluginManager().registerEvents(this, P.instance);
Log.console("§a性能监控系统已启用...");
Bukkit.getPluginManager().registerEvents(this, PKit.i());
PluginKit.scp("§a性能监控系统已启用...");
}
@EventHandler
public void onPluginDisable(PluginDisableEvent e) {
public void onPluginDisable(final PluginDisableEvent e) {
YumAPI.uninject(e.getPlugin());
}
@EventHandler
public void onPluginEnable(final PluginEnableEvent e) {
if (ConfigManager.i().getMonitorIgnoreList().contains(e.getPlugin().getName())) { return; }
MonitorManager.reset(e.getPlugin().getName());
PKit.runTaskLater(new Runnable() {
@Override
public void run() {
YumAPI.inject(e.getPlugin());
}
}, 2);
YumAPI.inject(e.getPlugin());
}
}

View File

@ -5,11 +5,10 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.commands.NetCommand;
import pw.yumc.Yum.events.PluginNetworkEvent;
import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.YumCore.bukkit.Log;
public class PluginNetworkListener implements Listener {
public String prefix = "§6[§bYum §a网络管理§6] ";
@ -18,46 +17,49 @@ public class PluginNetworkListener implements Listener {
public String breaked = "§c已阻止插件 §b%s §c访问网络!";
public String url = "§6地址: §c%s";
public PluginNetworkListener(Yum yum) {
public PluginNetworkListener(final Yum yum) {
Bukkit.getPluginManager().registerEvents(this, yum);
}
public void breakNetwork(PluginNetworkEvent e) {
public void breakNetwork(final PluginNetworkEvent e) {
if (ConfigManager.i().isNetworkShowInfo()) {
Log.console(prefix + breaked, e.getPlugin().getName());
Log.console(prefix + url, e.getUrl().toString());
PluginKit.sc(String.format(prefix + breaked, e.getPlugin().getName()));
PluginKit.sc(String.format(prefix + url, e.getUrl().toString()));
}
e.setCancelled(true);
}
@EventHandler
public void onPluginNetworkConect(PluginNetworkEvent e) {
Plugin plugin = e.getPlugin();
String urlinfo = e.getUrl().toString();
if (ConfigManager.i().getNetworkWhiteURL().contains(e.getUrl().getHost())) { return; }
if (urlinfo.contains("yumc") || urlinfo.contains("cco") || urlinfo.contains("citycraft") || urlinfo.contains("502647092")) {
String = "反编译的大神们我知道你们又要说了这货有后门";
public void onPluginNetworkConect(final PluginNetworkEvent e) {
final Plugin plugin = e.getPlugin();
final String urlinfo = e.getUrl().toString();
if (urlinfo.startsWith("socket")) {
return;
}
if (ConfigManager.i().getNetworkWhiteURL().contains(e.getUrl().getHost())) {
return;
}
if (urlinfo.contains("yumc") || urlinfo.contains("502647092")) {
final String = "反编译的大神们我知道你们又要说了这货有后门";
.isEmpty();
return;
}
if (plugin != null) {
if (ConfigManager.i().isNetworkDebug() && ConfigManager.i().getNetWorkDebug().contains(plugin.getName())) {
new Exception().printStackTrace();
}
NetCommand.addNetCount(plugin.getName());
if (ConfigManager.i().getNetworkBlackList().contains(plugin.getName())) {
breakNetwork(e);
return;
}
if (ConfigManager.i().getNetworkIgnoreList().contains(plugin.getName())) { return; }
if (ConfigManager.i().getNetworkIgnoreList().contains(plugin.getName())) {
return;
}
if (e.isPrimaryThread()) {
Log.console(prefix + warnMain, plugin.getName());
PluginKit.sc(String.format(prefix + warnMain, plugin.getName()));
if (!ConfigManager.i().isAllowPrimaryThread()) {
breakNetwork(e);
}
} else {
Log.console(prefix + warn, plugin.getName());
Log.console(prefix + url, urlinfo);
PluginKit.sc(String.format(prefix + warn, plugin.getName()));
PluginKit.sc(String.format(prefix + url, urlinfo));
}
}
}

View File

@ -5,10 +5,9 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.kit.PKit;
import pw.yumc.injected.event.SetOpEvent;
/**
@ -17,24 +16,26 @@ import pw.yumc.injected.event.SetOpEvent;
* @author
*/
public class SecurityListener implements Listener {
private String prefix = "§6[§bYum §a安全系统§6] ";
private String warn = "§c插件 §e%s §c已设置玩家 §a%s §c为OP §4请注意服务器安全!";
private String prevent = "§c黑名单插件 §e%s §c尝试设置玩家 §a%s §c为OP §a安全系统已成功拦截!";
private final String prefix = "§6[§bYum §a安全系统§6] ";
private final String warn = "§c插件 §e%s §c已设置玩家 §a%s §c为OP §4请注意服务器安全!";
private final String prevent = "§c黑名单插件 §e%s §c尝试设置玩家 §a%s §c为OP §a安全系统已成功拦截!";
public SecurityListener(Yum yum) {
public SecurityListener(final Yum yum) {
Bukkit.getPluginManager().registerEvents(this, yum);
}
@EventHandler
public void setop(SetOpEvent e) {
Plugin plugin = PKit.getOperatePlugin();
public void setop(final SetOpEvent e) {
final Plugin plugin = PluginKit.getOperatePlugin();
if (plugin != null) {
if (ConfigManager.i().getSetOpBlackList().contains(plugin.getName())) {
Log.console(prefix + prevent, plugin, e.getOfflinePlayer().getName());
PluginKit.sc(String.format(prefix + prevent, plugin, e.getOfflinePlayer().getName()));
e.setCancelled(true);
return;
}
if (ConfigManager.i().getSetOpIgnoreList().contains(plugin.getName())) { return; }
if (ConfigManager.i().getSetOpIgnoreList().contains(plugin.getName())) {
return;
}
Bukkit.getConsoleSender().sendMessage(String.format(prefix + warn, plugin, e.getOfflinePlayer().getName()));
}
}

View File

@ -1,94 +1,98 @@
package pw.yumc.Yum.listeners;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.Plugin;
import pw.yumc.Yum.Yum;
import pw.yumc.YumCore.kit.PKit;
/**
* Fork From LagMonitor: https://github.com/games647/LagMonitor.git
* We can listen to events which are intended to run sync to the main thread.
* If those events are fired on a async task the operation was likely not thread-safe.
*/
public class ThreadSafetyListener implements Listener {
public ThreadSafetyListener(Yum yum) {
Bukkit.getPluginManager().registerEvents(this, yum);
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent chunkLoadEvent) {
checkSafety(chunkLoadEvent);
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent chunkUnloadEvent) {
checkSafety(chunkUnloadEvent);
}
@EventHandler
public void onCreatureSpawn(CreatureSpawnEvent creatureSpawnEvent) {
checkSafety(creatureSpawnEvent);
}
public void onInventoryOpen(InventoryOpenEvent inventoryOpenEvent) {
checkSafety(inventoryOpenEvent);
}
@EventHandler
public void onItemSpawn(ItemSpawnEvent itemSpawnEvent) {
checkSafety(itemSpawnEvent);
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent moveEvent) {
checkSafety(moveEvent);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent quitEvent) {
checkSafety(quitEvent);
}
public void onPlayerTeleport(PlayerTeleportEvent teleportEvent) {
checkSafety(teleportEvent);
}
@EventHandler
public void onWorldLoad(WorldLoadEvent worldLoadEvent) {
checkSafety(worldLoadEvent);
}
public void onWorldSave(WorldSaveEvent worldSaveEvent) {
checkSafety(worldSaveEvent);
}
@EventHandler
public void onWorldUnload(WorldUnloadEvent worldUnloadEvent) {
checkSafety(worldUnloadEvent);
}
private void checkSafety(Event eventType) {
if (Yum.mainThread != null && Thread.currentThread() != Yum.mainThread && !eventType.isAsynchronous()) {
String eventName = eventType.getEventName();
Plugin plugin = PKit.getOperatePlugin();
if (plugin != null) { throw new IllegalAccessError("[Yum 线程安全]: 请勿异步调用一个同步事件 " + eventName + " 操作插件: "
+ plugin.getName()); }
}
}
}
package pw.yumc.Yum.listeners;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.Plugin;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.Yum;
/**
* Fork From LagMonitor: https://github.com/games647/LagMonitor.git
* We can listen to events which are intended to run sync to the main thread.
* If those events are fired on a async task the operation was likely not thread-safe.
*/
public class ThreadSafetyListener implements Listener {
public ThreadSafetyListener(final Yum yum) {
Bukkit.getPluginManager().registerEvents(this, yum);
}
@EventHandler
public void onChunkLoad(final ChunkLoadEvent chunkLoadEvent) {
checkSafety(chunkLoadEvent);
}
@EventHandler
public void onChunkUnload(final ChunkUnloadEvent chunkUnloadEvent) {
checkSafety(chunkUnloadEvent);
}
@EventHandler
public void onCreatureSpawn(final CreatureSpawnEvent creatureSpawnEvent) {
checkSafety(creatureSpawnEvent);
}
@EventHandler
public void onInventoryOpen(final InventoryOpenEvent inventoryOpenEvent) {
checkSafety(inventoryOpenEvent);
}
@EventHandler
public void onItemSpawn(final ItemSpawnEvent itemSpawnEvent) {
checkSafety(itemSpawnEvent);
}
@EventHandler
public void onPlayerMove(final PlayerMoveEvent moveEvent) {
checkSafety(moveEvent);
}
@EventHandler
public void onPlayerQuit(final PlayerQuitEvent quitEvent) {
checkSafety(quitEvent);
}
@EventHandler
public void onPlayerTeleport(final PlayerTeleportEvent teleportEvent) {
checkSafety(teleportEvent);
}
@EventHandler
public void onWorldLoad(final WorldLoadEvent worldLoadEvent) {
checkSafety(worldLoadEvent);
}
@EventHandler
public void onWorldSave(final WorldSaveEvent worldSaveEvent) {
checkSafety(worldSaveEvent);
}
@EventHandler
public void onWorldUnload(final WorldUnloadEvent worldUnloadEvent) {
checkSafety(worldUnloadEvent);
}
private void checkSafety(final Event eventType) {
if (Yum.mainThread != null && Thread.currentThread() != Yum.mainThread && !eventType.isAsynchronous()) {
final String eventName = eventType.getEventName();
final Plugin plugin = PluginKit.getOperatePlugin();
if (plugin != null) {
throw new IllegalAccessError("[Yum 线程安全]: 请勿异步调用一个同步事件 " + eventName + " 操作插件: " + plugin.getName());
}
}
}
}

View File

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

View File

@ -1,30 +0,0 @@
package pw.yumc.Yum.managers;
import pw.yumc.YumCore.sql.DataBase;
import pw.yumc.YumCore.sql.core.KeyValue;
public class DataManager {
private static DataBase db = ConfigManager.i().getDataBase();
public static void init() {
db.createTables(TableName.cmd,
new KeyValue("plugin", "VARCHAR(30)").add("name", "VARCHAR(30)").add("total", "INT").add("count",
"INT"),
null);
db.createTables(TableName.event,
new KeyValue("plugin", "VARCHAR(30)").add("name", "VARCHAR(30)").add("total", "INT").add("count",
"INT"),
null);
db.createTables(TableName.task,
new KeyValue("plugin", "VARCHAR(30)").add("name", "VARCHAR(30)").add("total", "INT").add("count",
"INT"),
null);
}
static class TableName {
public static String prefix = "monitor_";
public static String cmd = prefix + "cmd";
public static String event = prefix + "event";
public static String task = prefix + "task";
}
}

View File

@ -3,10 +3,8 @@ package pw.yumc.Yum.managers;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
@ -14,8 +12,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import pw.yumc.YumCore.callback.CallBack.One;
/**
*
*
@ -25,7 +21,7 @@ import pw.yumc.YumCore.callback.CallBack.One;
public class DownloadManager {
Plugin plugin;
public DownloadManager(Plugin main) {
public DownloadManager(final Plugin main) {
this.plugin = main;
}
@ -36,8 +32,8 @@ public class DownloadManager {
* -
* @return
*/
public String getFileName(String url) {
int end = url.lastIndexOf('/');
public String getFileName(final String url) {
final int end = url.lastIndexOf('/');
return url.substring(end + 1);
}
@ -48,7 +44,7 @@ public class DownloadManager {
* -
* @return
*/
public String getFileName(URL url) {
public String getFileName(final URL url) {
return getFileName(url.getFile());
}
@ -61,8 +57,8 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(CommandSender sender, String urlstring) {
return run(sender, urlstring, new File("plugins", getFileName(urlstring)), null);
public boolean run(final CommandSender sender, final String urlstring) {
return run(sender, urlstring, new File("plugins", getFileName(urlstring)));
}
/**
@ -76,35 +72,11 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(CommandSender sender, String urlstring, File file) {
public boolean run(final CommandSender sender, final String urlstring, final File file) {
try {
URL url = new URL(urlstring);
final URL url = new URL(urlstring);
return run(sender, url, file);
} catch (MalformedURLException e) {
sender.sendMessage("§4错误: §c无法识别的URL地址...");
sender.sendMessage("§4地址: §c" + urlstring);
return false;
}
}
/**
*
*
* @param sender
* -
* @param urlstring
* -
* @param file
* -
* @param callback
* -
* @return
*/
public boolean run(CommandSender sender, String urlstring, File file, One<File> callback) {
try {
URL url = new URL(urlstring);
return run(sender, url, file, callback);
} catch (MalformedURLException e) {
} catch (final MalformedURLException e) {
sender.sendMessage("§4错误: §c无法识别的URL地址...");
sender.sendMessage("§4地址: §c" + urlstring);
return false;
@ -122,24 +94,7 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(CommandSender sender, URL url, File file) {
return run(sender, url, file, null);
}
/**
*
*
* @param sender
* -
* @param url
* -
* @param file
* -
* @param callback
* -
* @return
*/
public boolean run(CommandSender sender, URL url, File file, One<File> callback) {
public boolean run(CommandSender sender, final URL url, final File file) {
BufferedInputStream in = null;
FileOutputStream fout = null;
if (sender == null) {
@ -148,27 +103,14 @@ public class DownloadManager {
try {
sender.sendMessage("§6开始下载: §3" + getFileName(url));
sender.sendMessage("§6下载地址: §3" + url.toString());
URLConnection uc = reload(sender, url.openConnection());
int status = ((HttpURLConnection) uc).getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
switch (status) {
case HttpURLConnection.HTTP_NOT_FOUND:
throw new IllegalStateException(status + " 文件未找到!");
case HttpURLConnection.HTTP_FORBIDDEN:
throw new IllegalStateException(status + " 服务器拒绝了访问!");
case HttpURLConnection.HTTP_BAD_GATEWAY:
throw new IllegalStateException(status + " 无效的网关!");
}
}
int fileLength = uc.getContentLength();
boolean dyml = "chunked".equalsIgnoreCase(uc.getHeaderField("Transfer-Encoding"));
if (fileLength < 0 && !dyml) {
final int fileLength = url.openConnection().getContentLength();
if (fileLength < 0) {
sender.sendMessage("§6下载: §c文件 " + file.getName() + " 获取长度错误(可能是网络问题)!");
sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!");
return false;
}
sender.sendMessage("§6文件长度: §3" + (dyml ? "动态长度" : fileLength));
in = new BufferedInputStream(uc.getInputStream());
sender.sendMessage("§6文件长度: §3" + fileLength);
in = new BufferedInputStream(url.openStream());
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
sender.sendMessage("§6创建新目录: §d" + file.getParentFile().getAbsolutePath());
@ -179,38 +121,31 @@ public class DownloadManager {
file.createNewFile();
sender.sendMessage("§6创建新文件: §d" + file.getAbsolutePath());
fout = new FileOutputStream(file);
byte[] data = new byte[1024];
final byte[] data = new byte[1024];
long downloaded = 0L;
int count;
long time = System.currentTimeMillis();
while ((count = in.read(data)) != -1) {
downloaded += count;
fout.write(data, 0, count);
if (dyml) {
if (System.currentTimeMillis() - time > 1000) {
sender.sendMessage(String.format("§6已下载: §a%sk", downloaded / 1024));
final int percent = (int) (downloaded * 100L / fileLength);
if (percent % 10 == 0) {
if (System.currentTimeMillis() - time > 500) {
sender.sendMessage(String.format("§6已下载: §a" + getPer(percent / 10) + " %s%%", percent));
time = System.currentTimeMillis();
}
} else {
int percent = (int) (downloaded * 100L / fileLength);
if (percent % 10 == 0) {
if (System.currentTimeMillis() - time > 500) {
sender.sendMessage(String.format("§6已下载: §a" + getPer(percent / 10) + " %s%%", percent));
time = System.currentTimeMillis();
}
}
}
}
String pVer = null;
try {
PluginDescriptionFile desc = plugin.getPluginLoader().getPluginDescription(file);
final PluginDescriptionFile desc = plugin.getPluginLoader().getPluginDescription(file);
pVer = StringUtils.substring(desc.getVersion(), 0, 15);
} catch (Exception e) {
} catch (final Exception e) {
pVer = "";
}
sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName()
+ (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!");
} catch (Exception ex) {
sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName() + (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!");
return true;
} catch (final Exception ex) {
sender.sendMessage("§6异常: §c" + ex.getMessage());
sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!");
return false;
@ -222,13 +157,9 @@ public class DownloadManager {
if (fout != null) {
fout.close();
}
} catch (Exception ex) {
} catch (final Exception ex) {
}
}
if (callback != null) {
callback.run(file);
}
return true;
}
/**
@ -238,7 +169,7 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(String urlstring) {
public boolean run(final String urlstring) {
return run(null, urlstring);
}
@ -251,8 +182,8 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(String urlstring, File file) {
return run(null, urlstring, file, null);
public boolean run(final String urlstring, final File file) {
return run(null, urlstring, file);
}
/**
@ -264,12 +195,12 @@ public class DownloadManager {
* -
* @return
*/
public boolean run(URL url, File file) {
return run(null, url, file, null);
public boolean run(final URL url, final File file) {
return run(null, url, file);
}
private String getPer(int per) {
StringBuilder sb = new StringBuilder();
private String getPer(final int per) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
if (per > i) {
sb.append("==");
@ -282,23 +213,4 @@ public class DownloadManager {
return sb.toString();
}
/**
* 302 301
*
* @param
* @return
* @throws Exception
*/
private URLConnection reload(CommandSender sender, URLConnection uc) throws Exception {
HttpURLConnection huc = (HttpURLConnection) uc;
// 302, 301, 307
if (huc.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP
|| huc.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || huc.getResponseCode() == 307) {
String url = huc.getHeaderField("Location");
sender.sendMessage("§6跳转至地址: §3" + url);
return reload(sender, new URL(url).openConnection());
}
return uc;
}
}

View File

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

@ -9,11 +9,10 @@ import java.util.List;
import org.bukkit.Bukkit;
import cn.citycraft.PluginHelper.kit.ExceptionKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import pw.yumc.Yum.Yum;
import pw.yumc.Yum.events.PluginNetworkEvent;
import pw.yumc.YumCore.kit.ExKit;
import pw.yumc.YumCore.kit.PKit;
import pw.yumc.YumCore.bukkit.Log;
/**
*
@ -23,27 +22,27 @@ import pw.yumc.YumCore.bukkit.Log;
*/
public class NetworkManager {
public static void register(Yum plugin) {
Bukkit.getConsoleSender().sendMessage("§6[§a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
public static void register(final Yum plugin) {
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin));
}
public static void unregister() {
ProxySelector cur = ProxySelector.getDefault();
final ProxySelector cur = ProxySelector.getDefault();
if (cur instanceof YumProxySelector) {
ProxySelector.setDefault(((YumProxySelector) cur).getDefaultSelector());
}
}
static class YumProxySelector extends ProxySelector {
private ProxySelector defaultSelector;
private final ProxySelector defaultSelector;
public YumProxySelector(ProxySelector defaultSelector, Yum plugin) {
public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) {
this.defaultSelector = defaultSelector;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
public void connectFailed(final URI uri, final SocketAddress sa, final IOException ioe) {
defaultSelector.connectFailed(uri, sa, ioe);
}
@ -52,12 +51,11 @@ public class NetworkManager {
}
@Override
public List<Proxy> select(URI uri) {
if (uri.toString().startsWith("socket")) { return defaultSelector.select(uri); }
PluginNetworkEvent pne = new PluginNetworkEvent(PKit.getOperatePlugin(), uri, Bukkit.isPrimaryThread());
public List<Proxy> select(final URI uri) {
final PluginNetworkEvent pne = new PluginNetworkEvent(PluginKit.getOperatePlugin(), uri, Bukkit.isPrimaryThread());
Bukkit.getPluginManager().callEvent(pne);
if (pne.isCancelled()) {
ExKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 并被联网规则拦截!"));
ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 并被联网规则拦截!"));
}
return defaultSelector.select(uri);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,6 @@
/**
*
*/
package pw.yumc.Yum.managers;
import java.util.ArrayList;
@ -8,9 +11,11 @@ import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import cn.citycraft.PluginHelper.PluginHelperLogger;
import cn.citycraft.PluginHelper.jsonresult.JsonHandle;
import cn.citycraft.PluginHelper.kit.HttpKit;
import cn.citycraft.PluginHelper.kit.StrKit;
import pw.yumc.Yum.models.PluginInfo;
import pw.yumc.Yum.models.RepoCache;
import pw.yumc.Yum.models.RepoSerialization.PackageInfo;
@ -19,7 +24,6 @@ import pw.yumc.Yum.models.RepoSerialization.Repositories;
import pw.yumc.Yum.models.RepoSerialization.Repository;
import pw.yumc.Yum.models.RepoSerialization.TagInfo;
import pw.yumc.Yum.models.RepoSerialization.URLType;
import pw.yumc.YumCore.kit.HttpKit;
/**
*
@ -28,64 +32,72 @@ import pw.yumc.YumCore.kit.HttpKit;
* @since 201619 10:02:57
*/
public class RepositoryManager {
PluginHelperLogger logger = PluginHelperLogger.getLogger();
org.bukkit.plugin.Plugin main;
RepoCache repocache;
public RepositoryManager(org.bukkit.plugin.Plugin plugin) {
public RepositoryManager(final org.bukkit.plugin.Plugin plugin) {
this.main = plugin;
repocache = new RepoCache();
}
public boolean addPackage(CommandSender sender, String urlstring) {
String json = HttpKit.get(urlstring);
if (json.isEmpty()) { return false; }
PackageInfo pkg = jsonToPackage(json);
if (pkg == null) { return false; }
public boolean addPackage(final CommandSender sender, final String urlstring) {
final String json = HttpKit.get(urlstring);
if (json == null || json.isEmpty()) {
return false;
}
final PackageInfo pkg = jsonToPackage(json);
if (pkg == null) {
return false;
}
updatePackage(sender, pkg);
return true;
}
public boolean addRepositories(CommandSender sender, String urlstring) {
String url = handerRepoUrl(urlstring);
Repositories repo = repocache.addRepo(url);
return repo != null && updateRepositories(sender, repo);
public boolean addRepositories(final CommandSender sender, final String urlstring) {
final String url = handerRepoUrl(urlstring);
final Repositories repo = repocache.addRepo(url);
if (repo == null) {
return false;
}
return updateRepositories(sender, repo);
}
public void clean() {
repocache.getPlugins().clear();
}
public boolean delRepositories(CommandSender sender, String urlstring) {
public boolean delRepositories(final CommandSender sender, final String urlstring) {
return repocache.removeRepo(handerRepoUrl(urlstring));
}
public List<PluginInfo> getAllPlugin() {
List<PluginInfo> li = new ArrayList<>();
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
final List<PluginInfo> li = new ArrayList<PluginInfo>();
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
li.add(plugin.getValue());
}
return li;
}
public List<String> getAllPluginName() {
List<String> li = new ArrayList<>();
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
final List<String> li = new ArrayList<String>();
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
li.add(plugin.getValue().name);
}
return li;
}
public List<String> getAllPluginsInfo() {
List<String> li = new ArrayList<>();
final List<String> li = new ArrayList<String>();
li.add("§d仓库名称 §a插件名称 §e插件描述");
for (Entry<String, PluginInfo> pi : repocache.getPlugins().entrySet()) {
Plugin plugin = pi.getValue().plugin;
for (final Entry<String, PluginInfo> pi : repocache.getPlugins().entrySet()) {
final Plugin plugin = pi.getValue().plugin;
li.add(String.format("§d%s §a%s §6- §e%s", pi.getValue().repo, pi.getValue().name, plugin.description));
if (plugin.tags != null) {
li.add(" §b┗Tags §c标签 §a版本 §e类型");
List<TagInfo> taglist = plugin.tags;
final List<TagInfo> taglist = plugin.tags;
for (int i = 0; i < taglist.size(); i++) {
TagInfo tag = taglist.get(i);
final TagInfo tag = taglist.get(i);
li.add(" §b" + (i == taglist.size() - 1 ? "┗ " : "┣ ") + String.format("§c%s §a%s §e%s", tag.tag, tag.version, tag.type != null ? tag.type : URLType.Maven));
}
}
@ -93,16 +105,18 @@ public class RepositoryManager {
return li;
}
public PluginInfo getPlugin(String name) {
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
if (plugin.getValue().name.equalsIgnoreCase(name)) { return plugin.getValue(); }
public PluginInfo getPlugin(final String name) {
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
if (plugin.getValue().name.equalsIgnoreCase(name)) {
return plugin.getValue();
}
}
return null;
}
public List<PluginInfo> getPluginInfo(String name) {
List<PluginInfo> li = new ArrayList<>();
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
public List<PluginInfo> getPluginInfo(final String name) {
final List<PluginInfo> li = new ArrayList<PluginInfo>();
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
if (plugin.getValue().name.equalsIgnoreCase(name)) {
li.add(plugin.getValue());
}
@ -110,7 +124,7 @@ public class RepositoryManager {
return li;
}
public PluginInfo getPluginInfo(String groupId, String artifactId) {
public PluginInfo getPluginInfo(final String groupId, final String artifactId) {
return repocache.getPlugins().get(groupId + "." + artifactId);
}
@ -122,7 +136,7 @@ public class RepositoryManager {
return repocache;
}
public Repositories getRepoCache(String urlstring) {
public Repositories getRepoCache(final String urlstring) {
return repocache.getRepos().get(handerRepoUrl(urlstring));
}
@ -130,25 +144,36 @@ public class RepositoryManager {
return repocache.getRepos();
}
public boolean getRepositories(CommandSender sender, String urlstring) {
int urllength = urlstring.length();
String url = urlstring.substring(0, urlstring.endsWith("/") ? urllength - 1 : urllength);
public boolean getRepositories(final CommandSender sender, final String urlstring) {
final int urllength = urlstring.length();
final String url = urlstring.substring(0, urlstring.endsWith("/") ? urllength - 1 : urllength);
handerRepoUrl(url);
Repositories repo = repocache.addRepo(urlstring);
return repo != null && updateRepositories(sender, repo);
final Repositories repo = repocache.addRepo(urlstring);
if (repo == null) {
return false;
}
return updateRepositories(sender, repo);
}
public PackageInfo jsonToPackage(String json) {
return new PackageInfo((JSONObject) JSONValue.parse(json));
public PackageInfo jsonToPackage(final String json) {
try {
return JsonHandle.fromJson(json, PackageInfo.class);
} catch (final Exception e) {
return null;
}
}
public void updatePackage(CommandSender sender, PackageInfo pkg) {
for (Plugin plugin : pkg.plugins) {
PluginInfo pi = new PluginInfo();
pi.name = getNotNull(plugin.name, plugin.artifactId);
pi.branch = getNotNull(plugin.branch, "master");
pi.pom = getNotNull(plugin.pom, pkg.pom);
pi.url = getNotNull(plugin.url, pkg.url);
public Repositories jsonToRepositories(final String json) {
return JsonHandle.fromJson(json, Repositories.class);
}
public void updatePackage(final CommandSender sender, final PackageInfo pkg) {
for (final Plugin plugin : pkg.plugins) {
final PluginInfo pi = new PluginInfo();
pi.name = StrKit.getNotNull(plugin.name, plugin.artifactId);
pi.branch = StrKit.getNotNull(plugin.branch, "master");
pi.pom = StrKit.getNotNull(plugin.pom, pkg.pom);
pi.url = StrKit.getNotNull(plugin.url, pkg.url);
pi.type = plugin.type != null ? plugin.type : pkg.type;
pi.type = pi.type != null ? pi.type : URLType.Maven;
pi.plugin = plugin;
@ -158,19 +183,15 @@ public class RepositoryManager {
sender.sendMessage("§6仓库: §e" + pkg.name + " §a更新成功!");
}
public static String getNotNull(final String vault, final String def) {
return (vault == null || vault.isEmpty() || vault.equalsIgnoreCase("null")) ? def : vault;
}
public boolean updateRepositories(CommandSender sender) {
public boolean updateRepositories(final CommandSender sender) {
repocache.getPlugins().clear();
if (repocache.getRepos().isEmpty()) {
repocache.addRepo("http://data.yumc.pw/yumcenter/repo.info");
}
Iterator<Entry<String, Repositories>> keys = repocache.getRepos().entrySet().iterator();
final Iterator<Entry<String, Repositories>> keys = repocache.getRepos().entrySet().iterator();
while (keys.hasNext()) {
Entry<String, Repositories> string = keys.next();
Repositories repo = repocache.getRepo(string.getKey());
final Entry<String, Repositories> string = keys.next();
final Repositories repo = repocache.getRepo(string.getKey());
if (updateRepositories(sender, repo)) {
sender.sendMessage("§6源: §e" + repo.name + " §a更新成功!");
} else {
@ -181,22 +202,22 @@ public class RepositoryManager {
return true;
}
public boolean updateRepositories(CommandSender sender, Repositories repocenter) {
public boolean updateRepositories(CommandSender sender, final Repositories repocenter) {
if (sender == null) {
sender = Bukkit.getConsoleSender();
}
if (repocenter == null || repocenter.repos.isEmpty()) {
sender.sendMessage(String.format("§6[§bYum§6] 源 %s 数据为空或列表为空!", repocenter == null ? "null" : repocenter.name));
logger.debug("源地址为Null或源列表为空!");
return false;
}
for (Repository repo : repocenter.repos) {
for (final Repository repo : repocenter.repos) {
addPackage(sender, repo.url);
}
return true;
}
private String handerRepoUrl(String url) {
int urllength = url.length();
final int urllength = url.length();
url = url.substring(0, url.endsWith("/") ? urllength - 1 : urllength);
if (!url.startsWith("http://")) {
url = "http://" + url;

View File

@ -1,76 +1,9 @@
package pw.yumc.Yum.models;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import pw.yumc.YumCore.kit.StrKit;
public class BukkitDev implements Serializable {
public static String HOST = "https://api.curseforge.com";
public static String MODULE = "/servermods";
public static String SEARCH = HOST + MODULE + "/projects?search=%s";
public static String PLUGIN = HOST + MODULE + "/files?projectIds=%s";
public static class Files {
public int projectId;
public String name;
public String fileUrl;
public String fileName;
public String downloadUrl;
public String gameVersion;
public String md5;
public String releaseType;
public Files(JSONObject obj) {
projectId = Integer.parseInt(obj.get("projectId").toString());
name = obj.get("name").toString();
fileUrl = obj.get("fileUrl").toString();
fileName = obj.get("fileName").toString();
downloadUrl = obj.get("downloadUrl").toString();
gameVersion = obj.get("gameVersion").toString();
md5 = obj.get("md5").toString();
releaseType = obj.get("releaseType").toString();
}
public static List<Files> parseList(String json) {
if (StrKit.isBlank(json) || json.equals("[]")) { return Collections.emptyList(); }
List<Files> temp = new ArrayList<>();
JSONArray ja = (JSONArray) JSONValue.parse(json);
for (Object aJa : ja) {
temp.add(new Files((JSONObject) aJa));
}
Collections.reverse(temp);
return temp;
}
}
public static class Projects {
public int id;
public String name;
public String slug;
public String stage;
public Projects(JSONObject obj) {
id = Integer.parseInt(obj.get("id").toString());
name = obj.get("name").toString();
slug = obj.get("slug").toString();
stage = obj.get("stage").toString();
}
public static List<Projects> parseList(String json) {
if (StrKit.isBlank(json) || json.equals("[]")) { return Collections.emptyList(); }
List<Projects> temp = new ArrayList<>();
JSONArray ja = (JSONArray) JSONValue.parse(json);
for (Object aJa : ja) {
temp.add(new Projects((JSONObject) aJa));
}
return temp;
}
}
public String name;
public List<PluginInfo> pil;
}

View File

@ -2,16 +2,15 @@ package pw.yumc.Yum.models;
import java.io.Serializable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import cn.citycraft.PluginHelper.PluginHelperLogger;
import cn.citycraft.PluginHelper.kit.PKit;
import cn.citycraft.PluginHelper.utils.IOUtil;
import pw.yumc.Yum.models.RepoSerialization.Plugin;
import pw.yumc.Yum.models.RepoSerialization.TagInfo;
import pw.yumc.Yum.models.RepoSerialization.URLType;
import pw.yumc.YumCore.bukkit.Log;
public class PluginInfo implements Serializable {
public static String NMSVersion;
@ -19,8 +18,8 @@ public class PluginInfo implements Serializable {
static {
try {
NMSVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} catch (Exception e) {
Log.w("服务器NMS解析失败: " + Bukkit.getServer().getClass().getPackage().getName());
} catch (final Exception e) {
PKit.i().getLogger().warning("服务器NMS解析失败: " + Bukkit.getServer().getClass().getPackage().getName());
NMSVersion = "NONMS";
}
}
@ -36,6 +35,10 @@ public class PluginInfo implements Serializable {
/**
*
*
* @param sender
*
* @param version
*
* @return
*/
public String getDirectUrl() {
@ -45,11 +48,13 @@ public class PluginInfo implements Serializable {
/**
*
*
* @param sender
*
* @param version
*
* @return
*/
public String getDirectUrl(String version) {
public String getDirectUrl(final String version) {
return url.replace("[version]", version);
}
@ -69,41 +74,43 @@ public class PluginInfo implements Serializable {
*
* @return
*/
public String getFileName(String version) {
public String getFileName(final String version) {
return String.format("%1$s-%2$s.jar", plugin.artifactId, version);
}
/**
* Maven
*
* @param ver
* @param sender
* -
* @param version
* -
* @return
*/
public String getMavenUrl(String ver) {
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);
public String getMavenUrl(final String ver) {
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);
}
public String getUrl(CommandSender sender, String version) {
public String getUrl(final CommandSender sender, final String version) {
String ver = version;
if (ver == null) {
if (plugin.tags != null) {
Log.d("发现存在TAG标签 开始检索: " + NMSVersion);
for (TagInfo tagInfo : plugin.tags) {
PluginHelperLogger.getLogger().debug("发现存在TAG标签 开始检索: " + NMSVersion);
for (final TagInfo tagInfo : plugin.tags) {
if (tagInfo.tag.equalsIgnoreCase(NMSVersion)) {
sender.sendMessage("§6版本: §b从Tag标签中获取 §e" + NMSVersion + " §b的最新版本...");
ver = tagInfo.version;
if (tagInfo.type == URLType.DirectUrl) { return tagInfo.url; }
if (tagInfo.type == URLType.DirectUrl) {
return tagInfo.url;
}
break;
}
}
} else if (pom != null && !pom.isEmpty()) {
pom = pom.replace("[name]", name).replace("[branch]", branch);
sender.sendMessage("§6版本: §b尝试从在线POM文件获取最新版本...");
ver = getXMLTag(pom, "version", null);
System.out.println(pom);
ver = IOUtil.getXMLTag(pom, "version", null);
if (ver != null) {
sender.sendMessage("§6版本: §a成功获取到最新版本 §e" + ver + " §a...");
}
@ -122,26 +129,4 @@ public class PluginInfo implements Serializable {
return null;
}
}
/**
* XML
*
* @param url
* XML
* @param tag
*
* @param def
*
* @return
*/
public static String getXMLTag(final String url, final String tag, final String def) {
String result = def;
try {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
result = builder.parse(url).getElementsByTagName(tag).item(0).getTextContent();
} catch (final Exception ignored) {
}
return result;
}
}

View File

@ -7,32 +7,40 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import cn.citycraft.PluginHelper.PluginHelperLogger;
import cn.citycraft.PluginHelper.jsonresult.JsonHandle;
import cn.citycraft.PluginHelper.utils.IOUtil;
import pw.yumc.Yum.models.RepoSerialization.Repositories;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.kit.HttpKit;
public class RepoCache implements Serializable {
Map<String, PluginInfo> plugins = new HashMap<>();
Map<String, Repositories> repos = new HashMap<>();
PluginHelperLogger logger = PluginHelperLogger.getLogger();
Map<String, PluginInfo> plugins = new HashMap<String, PluginInfo>();
Map<String, Repositories> repos = new HashMap<String, Repositories>();
public void addPlugins(String name, PluginInfo info) {
public static RepoCache fromJson(final String json) {
return JsonHandle.fromJson(json, RepoCache.class);
}
public void addPlugins(final String name, final PluginInfo info) {
plugins.put(name, info);
}
public Repositories addRepo(String repo) {
if (repos.containsKey(repo) || repo.isEmpty()) { return null; }
Repositories reposes = getRepo(repo);
if (reposes == null) { return null; }
public Repositories addRepo(final String repo) {
if (repos.containsKey(repo) || repo.isEmpty()) {
logger.debug("源地址为空或已存在 " + repo);
return null;
}
final Repositories reposes = getRepo(repo);
if (reposes == null) {
return null;
}
repos.put(repo, reposes);
return reposes;
}
public List<String> getAllRepoInfo() {
List<String> repoinfo = new ArrayList<>();
for (Entry<String, Repositories> repo : repos.entrySet()) {
final List<String> repoinfo = new ArrayList<String>();
for (final Entry<String, Repositories> repo : repos.entrySet()) {
repoinfo.add(String.format("§d仓库: §e%s §6- §3%s", repo.getValue().name, repo.getKey()));
}
return repoinfo;
@ -42,29 +50,34 @@ public class RepoCache implements Serializable {
return plugins;
}
public Repositories getRepo(String repo) {
try {
String json = HttpKit.get(repo);
Repositories reposes = new Repositories((JSONObject) JSONValue.parse(json));
if (reposes.repos.isEmpty()) {
Log.console("§c源地址解析Json为空 §b" + repo);
return null;
}
return reposes;
} catch (Exception e) {
Throwable ex = e.getCause();
Log.console("§c源地址获取数据为空 §b%s §c异常: %s: %s", repo, ex.getClass().getName(), ex.getLocalizedMessage());
public Repositories getRepo(final String repo) {
final String json = IOUtil.getData(repo);
if (json == null || json.isEmpty()) {
logger.debug("源地址获取数据为空 " + repo);
return null;
}
final Repositories reposes = JsonHandle.fromJson(json, Repositories.class);
if (reposes == null || reposes.repos.isEmpty()) {
logger.debug("源地址解析Json为空 " + repo);
return null;
}
return reposes;
}
public Map<String, Repositories> getRepos() {
return repos;
}
public boolean removeRepo(String repo) {
if (repo.isEmpty() || !repos.containsKey(repo)) { return false; }
public boolean removeRepo(final String repo) {
if (repo.isEmpty() || !repos.containsKey(repo)) {
return false;
}
repos.remove(repo);
return true;
}
@Override
public String toString() {
return JsonHandle.toJson(this);
}
}

View File

@ -4,14 +4,9 @@
package pw.yumc.Yum.models;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
*
*
@ -19,39 +14,15 @@ import org.json.simple.JSONValue;
* @since 20158317:41:53
*/
public class RepoSerialization {
@SuppressWarnings("unchecked")
public static <E> List<E> parse(String json, Class<?> clazz) {
if (json == null || "null".equals(json) || json.isEmpty()) { return null; }
List<E> temp = new ArrayList<>();
JSONArray ja = (JSONArray) JSONValue.parse(json);
for (int i = 0; i < ja.size(); i++) {
try {
temp.add((E) clazz.getConstructor(JSONObject.class).newInstance((JSONObject) ja.get(i)));
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
return temp;
}
public static class PackageInfo implements Serializable {
public class PackageInfo implements Serializable {
public String name;
public List<Plugin> plugins = new ArrayList<>();
public String pom;
public String url;
public URLType type;
public PackageInfo(JSONObject obj) {
name = String.valueOf(obj.get("name"));
plugins = Plugin.parseList(String.valueOf(obj.get("plugins")));
pom = String.valueOf(obj.get("pom"));
url = String.valueOf(obj.get("url"));
Object tt = obj.get("type");
type = tt == null ? null : URLType.valueOf(tt.toString());
}
}
public static class Plugin implements Serializable {
public class Plugin implements Serializable {
public String artifactId;
public String branch;
public String description;
@ -62,75 +33,28 @@ public class RepoSerialization {
public List<TagInfo> tags;
public String version;
public URLType type;
public Plugin(JSONObject obj) {
artifactId = String.valueOf(obj.get("artifactId"));
branch = String.valueOf(obj.get("branch"));
description = String.valueOf(obj.get("description"));
groupId = String.valueOf(obj.get("groupId"));
name = String.valueOf(obj.get("name"));
url = String.valueOf(obj.get("url"));
pom = String.valueOf(obj.get("pom"));
tags = TagInfo.parseList(String.valueOf(obj.get("tags")));
version = String.valueOf(obj.get("version"));
Object tt = obj.get("type");
type = tt == null ? null : URLType.valueOf(tt.toString());
}
public static List<Plugin> parseList(String json) {
return parse(json, Plugin.class);
}
}
public static class Repositories implements Serializable {
public class Repositories implements Serializable {
public String name;
public List<Repository> repos;
public Repositories(JSONObject obj) {
name = String.valueOf(obj.get("name"));
repos = Repository.parseList(String.valueOf(obj.get("repos")));
}
}
public static class Repository implements Serializable {
public class Repository implements Serializable {
public String id;
public URLType type;
public String url;
public Repository(JSONObject obj) {
id = String.valueOf(obj.get("id"));
Object tt = obj.get("type");
type = tt == null ? null : URLType.valueOf(tt.toString());
url = String.valueOf(obj.get("url"));
}
public static List<Repository> parseList(String json) {
return parse(json, Repository.class);
}
}
public static class TagInfo implements Serializable {
public class TagInfo implements Serializable {
public String tag;
public String version;
public URLType type;
public String url;
public TagInfo(JSONObject obj) {
tag = String.valueOf(obj.get("tag"));
version = String.valueOf(obj.get("version"));
Object tt = obj.get("type");
type = tt == null ? null : URLType.valueOf(tt.toString());
url = String.valueOf(obj.get("url"));
}
public static List<TagInfo> parseList(String json) {
return parse(json, TagInfo.class);
}
}
public enum URLType {
Maven,
maven,
DirectUrl
DirectUrl;
}
}

View File

@ -1,17 +1,12 @@
package pw.yumc.Yum.runnables;
import java.lang.Thread.State;
import java.lang.reflect.Method;
import java.util.TimerTask;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.bukkit.compatible.C;
import pw.yumc.YumCore.kit.PKit;
import pw.yumc.YumCore.plugin.protocollib.PacketKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.kit.ServerKit;
/**
* 线
@ -20,26 +15,16 @@ import pw.yumc.YumCore.plugin.protocollib.PacketKit;
* @author
*/
public class MainThreadCheckTask extends TimerTask {
private static Method tickMethod;
private String prefix = "§6[§a线程管理§6] ";
private String warnPNet = "§6插件 §b%s §c在主线程进行网络操作 §4服务器处于停止状态...";
private String warnPIO = "§6插件 §b%s §c在主线程进行IO操作 §4服务器处于停止状态...";
private String warnNet = "§c主线程存在网络操作 §4服务器处于停止状态...";
private String warnIO = "§c主线程存在IO操作 §4服务器处于停止状态...";
private String deliver = "§c服务器处于停止状态 已超过 %s 秒 激活心跳 防止线程关闭...";
private String errStackTrace = " §e位于 §c%s.%s(§4%s:%s§c)";
private double stopTime = 0;
private Thread mainThread;
private final String prefix = "§6[§bYum §a线程管理§6] ";
private final String warnPNet = "§6插件 §b%s §c在主线程进行网络操作 §4服务器处于停止状态...";
private final String warnPIO = "§6插件 §b%s §c在主线程进行IO操作 §4服务器处于停止状态...";
private final String warnNet = "§c主线程存在网络操作 §4服务器处于停止状态...";
private final String warnIO = "§c主线程存在IO操作 §4服务器处于停止状态...";
private final String deliver = "§c服务器处于停止状态 已超过 %s 秒 激活心跳 防止线程关闭...";
private int stopTime = 0;
private final Thread mainThread;
static {
try {
Class clazz = Class.forName("org.spigotmc.WatchdogThread");
tickMethod = clazz.getDeclaredMethod("tick");
} catch (Exception ignored) {
}
}
public MainThreadCheckTask(Thread mainThread) {
public MainThreadCheckTask(final Thread mainThread) {
this.mainThread = mainThread;
}
@ -48,70 +33,54 @@ public class MainThreadCheckTask extends TimerTask {
// According to this post the thread is still in Runnable although it's waiting for
// file/http ressources
// https://stackoverflow.com/questions/20795295/why-jstack-out-says-thread-state-is-runnable-while-socketread
String tip = null;
if (mainThread.getState() == State.RUNNABLE) {
// Based on this post we have to check the top element of the stack
// https://stackoverflow.com/questions/20891386/how-to-detect-thread-being-blocked-by-io
StackTraceElement[] stackTrace = mainThread.getStackTrace();
StackTraceElement topElement = stackTrace[0];
final StackTraceElement[] stackTrace = mainThread.getStackTrace();
final StackTraceElement topElement = stackTrace[0];
if (topElement.isNativeMethod()) {
// Socket/SQL (connect) - java.net.DualStackPlainSocketImpl.connect0
// Socket/SQL (read) - java.net.SocketInputStream.socketRead0
// Socket/SQL (write) - java.net.SocketOutputStream.socketWrite0
if (isElementEqual(topElement, "java.net.DualStackPlainSocketImpl", "connect0") || isElementEqual(topElement, "java.net.SocketInputStream", "socketRead0")
if (isElementEqual(topElement, "java.net.DualStackPlainSocketImpl", "connect0")
|| isElementEqual(topElement, "java.net.SocketInputStream", "socketRead0")
|| isElementEqual(topElement, "java.net.SocketOutputStream", "socketWrite0")) {
Plugin plugin = PKit.getOperatePlugin(stackTrace);
tip = plugin != null ? String.format(warnPNet, plugin.getName()) : warnNet;
final Plugin plugin = PluginKit.getOperatePlugin(stackTrace);
if (plugin != null) {
PluginKit.sc(String.format(prefix + warnPNet, plugin.getName()));
} else {
PluginKit.sc(prefix + warnNet);
}
tick();
}
// File (in) - java.io.FileInputStream.readBytes
// File (out) - java.io.FileOutputStream.writeBytes
else if (isElementEqual(topElement, "java.io.FileInputStream", "readBytes") || isElementEqual(topElement, "java.io.FileOutputStream", "writeBytes")) {
Plugin plugin = PKit.getOperatePlugin(stackTrace);
tip = plugin != null ? String.format(warnPIO, plugin.getName()) : warnIO;
final Plugin plugin = PluginKit.getOperatePlugin(stackTrace);
if (plugin != null) {
PluginKit.sc(String.format(prefix + warnPIO, plugin.getName()));
} else {
PluginKit.sc(prefix + warnIO);
}
tick();
} else {
stopTime = 0;
}
}
if (tip != null) {
tick(tip, stackTrace);
} else {
stopTime = 0;
}
}
}
private boolean isElementEqual(StackTraceElement traceElement, String className, String methodName) {
private boolean isElementEqual(final StackTraceElement traceElement, final String className, final String methodName) {
return traceElement.getClassName().equals(className) && traceElement.getMethodName().equals(methodName);
}
private void tick(String tip, StackTraceElement[] stackTrace) {
stopTime += 0.5;
if (stopTime > 1 && stopTime < 2) {
Log.console(prefix + tip);
if (ConfigManager.i().isMainThreadDebug()) {
for (StackTraceElement ste : stackTrace) {
Log.console(errStackTrace, ste.getClassName(), ste.getMethodName(), ste.getFileName() == null ? "未知" : ste.getFileName(), ste.getLineNumber());
}
}
} else if (stopTime >= 45) {
if (stopTime < 46) {
Log.console(prefix + deliver, stopTime);
}
wttick();
}
}
/**
*
*/
public static void wttick() {
try {
if (tickMethod != null) {
tickMethod.invoke(null);
}
for (final Player player : C.Player.getOnlinePlayers()) {
Log.sender(player, "§4注意: §c服务器主线程处于停止状态 请等待操作完成!");
PacketKit.keep_live(player);
}
} catch (final Throwable ignored) {
private void tick() {
stopTime += 5;
if (stopTime >= 45) {
PluginKit.sc(String.format(prefix + deliver, stopTime));
ServerKit.tick();
}
}
}

View File

@ -3,14 +3,14 @@
############################
#配置版本号 请勿修改!!!
Version: 2.4
Version: 2.2
#是否只允许控制台执行插件仓库命令
onlyCommandConsole: ''
onlyCommandConsole: false
#是否只允许控制台执行插件网络管理命令
onlyNetCommandConsole: ''
onlyNetCommandConsole: false
#是否只允许控制台执行插件文件管理命令
onlyFileCommandConsole: ''
onlyFileCommandConsole: true
#禁止rm -rf的文件夹列表
blacklist:
- 'plugins'
@ -22,4 +22,3 @@ ignorelist:
- 'iConomy'
- 'GroupManager'
- 'PermissionsEx'
- 'Essentials'

View File

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

View File

@ -13,9 +13,6 @@ ShowInfo: true
NetworkDebug: false
#是否允许插件主线程访问网络
AllowPrimaryThread: false
#调试列表
Debug:
- AAC
#黑名单列表
Black:
- BukkitInjectedTools
@ -28,6 +25,4 @@ WhiteURL:
- mcstats.org
- report.mcstats.org
- www.spigotmc.org
- dev.bukkit.org
- api.curseforge.com
- bStats.org
- dev.bukkit.org

View File

@ -1,75 +1,75 @@
name: ${project.artifactId}
description: ${project.description}
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
version: ${project.version}-git-${env.GIT_COMMIT}
load: STARTUP
author: 喵♂呜
website: ${ciManagement.url}
commands:
yum:
description: MC插件仓库
aliases: [y,apt-get]
usage: §6使用 §a/yum help §6查看帮助!
permission: yum.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
net:
description: MC插件网络管理
aliases: [n]
usage: §6使用 §a/net help §6查看帮助!
permission: net.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
file:
description: MC文件管理命令
aliases: [f]
usage: §6使用 §a/file help §6查看帮助!
permission: file.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
security:
description: MC安全管理命令
aliases: [s]
usage: §6使用 §a/security help §6查看帮助!
permission: security.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
monitor:
description: MC系统监控命令
aliases: [mi]
usage: §6使用 §a/monitor help §6查看帮助!
permission: monitor.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
permissions:
yum.use:
description: 插件管理系统使用权限!
default: op
yum.delete:
description: 删除插件命令使用权限!
default: op
yum.install:
description: 安装插件命令使用权限!
default: op
yum.list:
description: 列出已安装插件使用权限!
default: op
yum.load:
description: 载入插件使用权限!
default: op
yum.reload:
description: 重载插件使用权限!
default: op
yum.repo:
description: 插件仓库使用权限!
default: op
yum.unload:
description: 卸载插件使用权限!
default: op
yum.update:
description: 更新插件使用权限!
default: op
yum.updateall:
description: 更新所有插件使用权限!
default: op
yum.upgrade:
description: 升级插件使用权限!
default: op
yum.reload:
description: 重新载入插件!
name: ${project.artifactId}
description: ${project.description}
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
version: ${project.version}-git-${env.GIT_COMMIT}
load: STARTUP
author: 喵♂呜
website: ${ciManagement.url}
commands:
yum:
description: MC插件仓库
aliases: [y,apt-get]
usage: §6使用§a/yum help§6查看帮助!
permission: yum.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
net:
description: MC插件网络管理
aliases: [n]
usage: §6使用§a/net help§6查看帮助!
permission: net.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
file:
description: MC文件管理命令
aliases: [f]
usage: §6使用§a/file help§6查看帮助!
permission: file.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
security:
description: MC安全管理命令
aliases: [s]
usage: §6使用§a/security help§6查看帮助!
permission: security.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
monitor:
description: MC系统监控命令
aliases: [m]
usage: §6使用§a/monitor help§6查看帮助!
permission: monitor.use
permission-message: §c你没有 <permission> 的权限来执行此命令!
permissions:
yum.use:
description: 插件管理系统使用权限!
default: op
yum.delete:
description: 删除插件命令使用权限!
default: op
yum.install:
description: 安装插件命令使用权限!
default: op
yum.list:
description: 列出已安装插件使用权限!
default: op
yum.load:
description: 载入插件使用权限!
default: op
yum.reload:
description: 重载插件使用权限!
default: op
yum.repo:
description: 插件仓库使用权限!
default: op
yum.unload:
description: 卸载插件使用权限!
default: op
yum.update:
description: 更新插件使用权限!
default: op
yum.updateall:
description: 更新所有插件使用权限!
default: op
yum.upgrade:
description: 升级插件使用权限!
default: op
yum.reload:
description: 重新载入插件!
default: op

View File

@ -3,11 +3,9 @@
############################
#配置版本号 请勿修改!!!
Version: 1.1
Version: 1.0
#是否开启线程安全检测
ThreadSafe: true
#是否开启主线程IO检测
MainThreadCheck: true
#是否开启调试模式
Debug: true
MainThreadCheck: true