mirror of https://e.coding.net/circlecloud/Yum.git
Compare commits
67 Commits
Author | SHA1 | Date |
---|---|---|
MiaoWoo | 18dc99e78e | |
MiaoWoo | 129f854382 | |
MiaoWoo | 0fd80ab8a0 | |
MiaoWoo | 37fb899e95 | |
MiaoWoo | 9f54734414 | |
MiaoWoo | 64686592a6 | |
MiaoWoo | 524a0121c8 | |
MiaoWoo | ecfd140ca8 | |
MiaoWoo | 9946f5caed | |
502647092 | 42ed92ac0f | |
502647092 | fcf06780f0 | |
502647092 | a9c6707fc7 | |
502647092 | 3c270657f8 | |
502647092 | 0a0e94a7fe | |
502647092 | 6aa2295adf | |
502647092 | 5d6035ba9e | |
502647092 | c18bae3b8e | |
502647092 | 5f628e08f1 | |
502647092 | eaddb97888 | |
502647092 | ce110a5dd6 | |
502647092 | 277f42bd2e | |
502647092 | 340d457e41 | |
502647092 | 887919552d | |
502647092 | adea1e58e0 | |
502647092 | 66c7508009 | |
502647092 | 31a2277672 | |
502647092 | 5c59bb1813 | |
502647092 | f8db0e1e51 | |
502647092 | 1ef47045de | |
502647092 | 6b5a91c73e | |
502647092 | fb1811d9f4 | |
502647092 | 56131b1274 | |
502647092 | 4a4cb932d7 | |
502647092 | 60c08f0aca | |
502647092 | 5491119c73 | |
502647092 | 6435f2a185 | |
502647092 | 632ee1f20c | |
502647092 | 6a75d33e85 | |
502647092 | c7fc35ab7e | |
502647092 | 50bbe6ff40 | |
502647092 | 2e9419a376 | |
502647092 | a0cb9c2ca7 | |
502647092 | 14d9438268 | |
502647092 | 8226293c3e | |
502647092 | 2b3313579c | |
502647092 | 829351e576 | |
502647092 | 844ae43eef | |
502647092 | 04e3e58c2f | |
502647092 | bc20088f0f | |
502647092 | 5f3db15b41 | |
502647092 | 720c796889 | |
502647092 | b066e8a81e | |
502647092 | e65246f55e | |
502647092 | adaff66241 | |
502647092 | 10bdef4763 | |
502647092 | e4e0c5509f | |
502647092 | 2cd540a953 | |
502647092 | 0fcecd63cf | |
502647092 | df4a8bc96f | |
502647092 | 8c43dba5f4 | |
502647092 | 935a2eb4f9 | |
502647092 | 58fe1d3f0c | |
502647092 | e1b72c1b60 | |
502647092 | 340718446b | |
502647092 | e954b10e82 | |
502647092 | ce4e6650d7 | |
502647092 | d772899f26 |
31
.classpath
31
.classpath
|
@ -1,31 +0,0 @@
|
|||
<?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>
|
|
@ -1,4 +1,7 @@
|
|||
# Eclipse stuff
|
||||
/.project
|
||||
/.classpath
|
||||
/.factorypath
|
||||
/.settings
|
||||
|
||||
# netbeans
|
||||
|
|
23
.project
23
.project
|
@ -1,23 +0,0 @@
|
|||
<?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
178
pom.xml
|
@ -1,107 +1,71 @@
|
|||
<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.2</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>&a全新 2.X 版本 更多守护与优化</update.description>
|
||||
<update.changes>
|
||||
&b2.6.2 &6- &d能耗监控添加忽略列表 &3详见monitor.yml...;
|
||||
&b2.6.1 &6- &c优化能耗监控 命令别名修改为mi(防止与ESS冲突)...;
|
||||
&b2.6 &6- &a添加能耗监控系统 事件错误监控...;
|
||||
</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>
|
||||
<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>
|
||||
|
|
|
@ -10,9 +10,6 @@ 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;
|
||||
|
@ -23,8 +20,13 @@ 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插件仓库
|
||||
|
@ -51,24 +53,35 @@ public class Yum extends JavaPlugin {
|
|||
public void onEnable() {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
mainThread = Thread.currentThread();
|
||||
} else {
|
||||
mainThread = getMainThread();
|
||||
}
|
||||
new YumAPI();
|
||||
initCommands();
|
||||
initListeners();
|
||||
initRunnable();
|
||||
new VersionChecker(this);
|
||||
MonitorManager.init();
|
||||
new Statistics();
|
||||
new SubscribeTask(true, SubscribeTask.UpdateType.MAVEN);
|
||||
YumAPI.updateRepo(Bukkit.getConsoleSender());
|
||||
YumAPI.updateCheck(Bukkit.getConsoleSender());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// 初始化配置
|
||||
ConfigManager.i();
|
||||
// 初始化更新列
|
||||
UpdatePlugin.getUpdateList();
|
||||
// 启用网络注入
|
||||
NetworkManager.register(this);
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,25 +100,25 @@ public class Yum extends JavaPlugin {
|
|||
private void initListeners() {
|
||||
if (ConfigManager.i().isSetOpEnable()) {
|
||||
try {
|
||||
final ClassLoader cl = Class.forName("pw.yumc.injected.event.SetOpEvent").getClassLoader();
|
||||
ClassLoader cl = Class.forName("pw.yumc.injected.event.SetOpEvent").getClassLoader();
|
||||
try {
|
||||
cl.getClass().getDeclaredField("plugin");
|
||||
throw new ClassNotFoundException();
|
||||
} catch (final NoSuchFieldException | SecurityException e) {
|
||||
} catch (NoSuchFieldException | SecurityException e) {
|
||||
new SecurityListener(this);
|
||||
PluginKit.scp("§a安全管理系统已启用...");
|
||||
Log.console("§a安全管理系统已启用...");
|
||||
}
|
||||
} catch (final ClassNotFoundException e) {
|
||||
PluginKit.scp("§c服务端未注入安全拦截器 关闭功能...");
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.console("§c服务端未注入安全拦截器 关闭功能...");
|
||||
}
|
||||
}
|
||||
if (ConfigManager.i().isNetworkEnable()) {
|
||||
new PluginNetworkListener(this);
|
||||
PluginKit.scp("§a网络管理系统已启用...");
|
||||
Log.console("§a网络管理系统已启用...");
|
||||
}
|
||||
if (ConfigManager.i().isThreadSafe()) {
|
||||
new ThreadSafetyListener(this);
|
||||
PluginKit.scp("§a线程管理系统已启用...");
|
||||
Log.console("§a线程管理系统已启用...");
|
||||
}
|
||||
if (ConfigManager.i().isMonitorEnable()) {
|
||||
new PluginListener();
|
||||
|
@ -118,11 +131,11 @@ public class Yum extends JavaPlugin {
|
|||
private void initRunnable() {
|
||||
// 需要在主线程注册任务
|
||||
if (ConfigManager.i().isMainThreadCheck() && mainThread != null) {
|
||||
PluginKit.scp("§aI O 管理系统已启用...");
|
||||
Log.console("§aI O 管理系统已启用...");
|
||||
if (tt != null) {
|
||||
tt.cancel();
|
||||
}
|
||||
task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 5000);
|
||||
task.scheduleAtFixedRate(tt = new MainThreadCheckTask(mainThread), 0, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,11 @@ 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;
|
||||
|
@ -21,6 +15,8 @@ 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管理中心
|
||||
|
@ -37,12 +33,9 @@ public class YumAPI {
|
|||
|
||||
/**
|
||||
* 初始化Yum管理中心
|
||||
*
|
||||
* @param plugin
|
||||
* 插件实体
|
||||
*/
|
||||
public YumAPI() {
|
||||
YumAPI.main = PKit.instance;
|
||||
YumAPI.main = P.instance;
|
||||
plugman = new PluginsManager(main);
|
||||
download = new DownloadManager(main);
|
||||
repo = new RepositoryManager(main);
|
||||
|
@ -55,7 +48,7 @@ public class YumAPI {
|
|||
* @param plugin
|
||||
* 插件实体
|
||||
*/
|
||||
public static void delete(final Plugin plugin) {
|
||||
public static void delete(Plugin plugin) {
|
||||
plugman.deletePlugin(plugin);
|
||||
}
|
||||
|
||||
|
@ -86,26 +79,13 @@ 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(final Plugin plugin) {
|
||||
public static void inject(Plugin plugin) {
|
||||
if (plugin.isEnabled() && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
|
||||
CommandInjector.inject(plugin);
|
||||
ListenerInjector.inject(plugin);
|
||||
|
@ -120,16 +100,11 @@ public class YumAPI {
|
|||
* 命令发送者
|
||||
* @param pluginname
|
||||
* 插件名称
|
||||
* @param version
|
||||
* 插件版本
|
||||
* @return 是否安装成功
|
||||
*/
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,11 +112,9 @@ public class YumAPI {
|
|||
*
|
||||
* @param pluginname
|
||||
* 插件名称
|
||||
* @param version
|
||||
* 插件版本
|
||||
* @return 是否安装成功
|
||||
*/
|
||||
public static boolean install(final String pluginname, final String url) {
|
||||
public static boolean install(String pluginname, String url) {
|
||||
return install(null, pluginname, url);
|
||||
}
|
||||
|
||||
|
@ -154,7 +127,7 @@ public class YumAPI {
|
|||
* 插件名称
|
||||
* @return 是否安装成功
|
||||
*/
|
||||
public static boolean installFromYum(final CommandSender sender, final String pluginname) {
|
||||
public static boolean installFromYum(CommandSender sender, String pluginname) {
|
||||
return installFromYum(sender, pluginname, null);
|
||||
}
|
||||
|
||||
|
@ -169,21 +142,17 @@ public class YumAPI {
|
|||
* 插件版本
|
||||
* @return 是否安装成功
|
||||
*/
|
||||
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));
|
||||
}
|
||||
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安装失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入插件
|
||||
*
|
||||
* @param pluginname
|
||||
* 插件名称
|
||||
*/
|
||||
public static void load(final File pluginFile) {
|
||||
public static void load(File pluginFile) {
|
||||
plugman.load(pluginFile);
|
||||
}
|
||||
|
||||
|
@ -193,7 +162,7 @@ public class YumAPI {
|
|||
* @param pluginname
|
||||
* 插件名称
|
||||
*/
|
||||
public static void load(final String pluginname) {
|
||||
public static void load(String pluginname) {
|
||||
plugman.load(pluginname);
|
||||
}
|
||||
|
||||
|
@ -203,18 +172,15 @@ public class YumAPI {
|
|||
* @param plugin
|
||||
* 插件实体
|
||||
*/
|
||||
public static void reload(final Plugin plugin) {
|
||||
public static void reload(Plugin plugin) {
|
||||
plugman.reload(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注入
|
||||
*
|
||||
* @param plugin
|
||||
* 插件
|
||||
*/
|
||||
public static void uninject() {
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
YumAPI.uninject(plugin);
|
||||
}
|
||||
}
|
||||
|
@ -225,9 +191,9 @@ public class YumAPI {
|
|||
* @param plugin
|
||||
* 插件
|
||||
*/
|
||||
public static void uninject(final Plugin plugin) {
|
||||
public static void uninject(Plugin plugin) {
|
||||
CommandInjector.uninject(plugin);
|
||||
// ListenerInjector.uninject(plugin);
|
||||
ListenerInjector.uninject(plugin);
|
||||
TaskInjector.uninject(plugin);
|
||||
}
|
||||
|
||||
|
@ -237,7 +203,7 @@ public class YumAPI {
|
|||
* @param plugin
|
||||
* 插件实体
|
||||
*/
|
||||
public static void unload(final Plugin plugin) {
|
||||
public static void unload(Plugin plugin) {
|
||||
plugman.unload(plugin);
|
||||
}
|
||||
|
||||
|
@ -252,8 +218,10 @@ public class YumAPI {
|
|||
* 新插件的下载地址
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
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()))) {
|
||||
public static boolean update(CommandSender sender, Plugin plugin, 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;
|
||||
|
@ -270,67 +238,10 @@ public class YumAPI {
|
|||
* 新插件的下载地址
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
public static boolean update(final Plugin plugin, final URL url) {
|
||||
public static boolean update(Plugin plugin, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新插件
|
||||
*
|
||||
|
@ -340,7 +251,7 @@ public class YumAPI {
|
|||
* 插件实体
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin) {
|
||||
public static boolean updateFromYum(CommandSender sender, Plugin plugin) {
|
||||
return updateFromYum(sender, plugin, null);
|
||||
}
|
||||
|
||||
|
@ -355,7 +266,7 @@ public class YumAPI {
|
|||
* 插件版本(null则自动获取)
|
||||
* @return
|
||||
*/
|
||||
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin, final String version) {
|
||||
public static boolean updateFromYum(CommandSender sender, Plugin plugin, String version) {
|
||||
return updateFromYum(sender, plugin, version, false);
|
||||
}
|
||||
|
||||
|
@ -372,16 +283,16 @@ public class YumAPI {
|
|||
* 是否一键更新
|
||||
* @return
|
||||
*/
|
||||
public static boolean updateFromYum(final CommandSender sender, final Plugin plugin, final String version, final boolean oneKeyUpdate) {
|
||||
final PluginInfo pi = repo.getPlugin(plugin.getName());
|
||||
public static boolean updateFromYum(CommandSender sender, Plugin plugin, String version, boolean oneKeyUpdate) {
|
||||
PluginInfo pi = repo.getPlugin(plugin.getName());
|
||||
if (pi != null) {
|
||||
final File pFile = new File(Bukkit.getUpdateFolderFile(), plugman.getPluginFile(plugin).getName());
|
||||
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 {
|
||||
|
@ -394,10 +305,10 @@ public class YumAPI {
|
|||
* 更新注入
|
||||
*/
|
||||
public static void updateInject() {
|
||||
PluginKit.runTaskLater(new Runnable() {
|
||||
PKit.runTaskLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
YumAPI.inject(plugin);
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +319,7 @@ public class YumAPI {
|
|||
* 更新Yum源数据
|
||||
*/
|
||||
public static void updateRepo(final CommandSender sender) {
|
||||
PluginKit.runTaskAsync(new Runnable() {
|
||||
PKit.runTaskAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
repo.updateRepositories(sender);
|
||||
|
@ -417,12 +328,24 @@ public class YumAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* 更新或安装插件
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
*/
|
||||
public static void upgrade(CommandSender sender) {
|
||||
plugman.upgrade(sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新或安装指定插件
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
* @param plugin
|
||||
* 插件实体
|
||||
*/
|
||||
public static void upgrade(final CommandSender sender, final Plugin plugin) {
|
||||
public static void upgrade(CommandSender sender, Plugin plugin) {
|
||||
plugman.upgrade(sender, plugin);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
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命令基类
|
||||
|
@ -19,67 +27,97 @@ import pw.yumc.Yum.api.YumAPI;
|
|||
* @since 2016年1月9日 上午10:02:39
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class FileCommand implements HandlerCommands {
|
||||
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";
|
||||
|
||||
Yum plugin;
|
||||
|
||||
public FileCommand(final Yum yum) {
|
||||
public FileCommand(Yum yum) {
|
||||
plugin = yum;
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
|
||||
cmdhandler.registerCommands(this);
|
||||
new CommandSub("file", this, PluginTabComplete.INSTANCE);
|
||||
}
|
||||
|
||||
@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();
|
||||
@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();
|
||||
if (!file.exists()) {
|
||||
sender.sendMessage("§c文件 " + file.getAbsolutePath() + " 不存在!");
|
||||
sender.sendMessage(String.format(file_not_found, fpath));
|
||||
} else {
|
||||
if (file.isDirectory()) {
|
||||
sender.sendMessage("§e" + file.getAbsolutePath() + " §c是一个目录 请使用file rm!");
|
||||
sender.sendMessage(String.format(file_is_dir, fpath));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!"));
|
||||
} catch (final Exception ex) {
|
||||
sender.sendMessage("§d文件 §e" + file.getAbsolutePath() + " 删除失败: " + ex.getMessage());
|
||||
sender.sendMessage("§d文件 §e" + fpath + " " + (file.delete() ? "§a删除成功!" : "§c删除失败!"));
|
||||
} catch (Exception ex) {
|
||||
sender.sendMessage("§d文件 §e" + fpath + " 删除失败: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "download", aliases = { "d" }, minimumArguments = 1, description = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]")
|
||||
public void download(final InvokeCommandEvent e) {
|
||||
final String[] args = e.getArgs();
|
||||
String urlstr = args[0];
|
||||
@Cmd(aliases = "d", minimumArguments = 1)
|
||||
@Help(value = "下载文件(默认保存到服务器更新文件夹)", possibleArguments = "<下载地址> [保存文件路径]")
|
||||
@Async
|
||||
public void download(CommandSender sender, String urlstr, String path) {
|
||||
if (!urlstr.startsWith("http")) {
|
||||
urlstr = "http://" + urlstr;
|
||||
}
|
||||
File file = null;
|
||||
if (args.length == 2) {
|
||||
file = new File(args[1]);
|
||||
if (path != null) {
|
||||
file = new File(path);
|
||||
} else {
|
||||
file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(urlstr));
|
||||
}
|
||||
YumAPI.getDownload().run(e.getSender(), urlstr, file);
|
||||
YumAPI.getDownload().run(sender, urlstr, file);
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "ls", aliases = { "l" }, description = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>")
|
||||
public void ls(final InvokeCommandEvent e) {
|
||||
final String[] args = e.getArgs();
|
||||
final CommandSender sender = e.getSender();
|
||||
@Cmd(aliases = "ls")
|
||||
@Help(value = "列出当前目录(服务器JAR为根目录)", possibleArguments = "<相对目录>")
|
||||
@Async
|
||||
public void ls(CommandSender sender, String filename) {
|
||||
File dir = new File(".");
|
||||
if (args.length == 1) {
|
||||
dir = new File(args[0]);
|
||||
if (filename != null) {
|
||||
dir = new File(filename);
|
||||
}
|
||||
if (!dir.isDirectory()) {
|
||||
sender.sendMessage("§6路径: §e " + dir.getAbsolutePath() + " §c不是一个目录!");
|
||||
return;
|
||||
}
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
for (final File file : dir.listFiles()) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
sb.append("§b");
|
||||
} else {
|
||||
|
@ -87,7 +125,7 @@ public class FileCommand implements HandlerCommands {
|
|||
}
|
||||
sb.append(file.getName() + " ");
|
||||
}
|
||||
final String filelist = sb.toString();
|
||||
String filelist = sb.toString();
|
||||
if (filelist.isEmpty()) {
|
||||
sender.sendMessage("§6目录: §e" + dir.getAbsolutePath() + " §c下没有文件或文件夹!");
|
||||
} else {
|
||||
|
@ -96,31 +134,29 @@ public class FileCommand implements HandlerCommands {
|
|||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@Cmd(aliases = "rn", minimumArguments = 2)
|
||||
@Help(value = "重命名文件(服务器JAR为根目录)", possibleArguments = "<文件相对路径> <文件名称>")
|
||||
@Async
|
||||
public void rename(CommandSender sender, String fpath, String des) {
|
||||
File file = new File(fpath);
|
||||
if (!file.exists()) {
|
||||
sender.sendMessage("§c文件 " + file.getAbsolutePath() + " 不存在!");
|
||||
} else {
|
||||
try {
|
||||
final File newFile = new File(file.getParentFile(), args[1]);
|
||||
File newFile = new File(file.getParentFile(), des);
|
||||
file.renameTo(newFile);
|
||||
sender.sendMessage("§a文件 §e" + file.getAbsolutePath() + " §a重命名为 §d" + newFile.getAbsolutePath());
|
||||
} catch (final Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
sender.sendMessage("§c文件 §e" + file.getAbsolutePath() + " §c重命名失败: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@Cmd(minimumArguments = 1)
|
||||
@Help(value = "删除文件夹(服务器JAR为根目录)", possibleArguments = "<相对目录>")
|
||||
@Async
|
||||
public void rm(CommandSender sender, String fpath, String option) {
|
||||
File file = new File(fpath);
|
||||
if (!file.exists()) {
|
||||
sender.sendMessage("§c目录 " + file.getAbsolutePath() + " 不存在!");
|
||||
} else {
|
||||
|
@ -128,19 +164,66 @@ public class FileCommand implements HandlerCommands {
|
|||
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!");
|
||||
return;
|
||||
}
|
||||
for (final String name : plugin.getConfig().getStringList("blacklist")) {
|
||||
for (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 && !(args.length > 1 && args[1].equalsIgnoreCase("-rf"))) {
|
||||
if (file.listFiles().length != 0 && !(option != null && option.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() + " " + (FileUtil.deleteDir(sender, file) ? "§a删除成功!" : "§c删除失败!"));
|
||||
sender.sendMessage("§d目录 §e" + file.getAbsolutePath() + " "
|
||||
+ (FileKit.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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package pw.yumc.Yum.commands;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -7,7 +8,6 @@ import java.util.Map.Entry;
|
|||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
|
@ -19,99 +19,129 @@ 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 2016年7月6日 下午5:13:32
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
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 avg_warn = "§6平均耗时: §c%.5f毫秒!";
|
||||
private final String p_n_f = prefix + "§c插件 §b%s §c不存在!";
|
||||
public class MonitorCommand implements Executor {
|
||||
public static Throwable lastError = null;
|
||||
|
||||
private final double um = 1000000.0;
|
||||
private String prefix = "§6[§bYum §a能耗监控§6] ";
|
||||
|
||||
public MonitorCommand(final Yum yum) {
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
|
||||
cmdhandler.registerCommands(this);
|
||||
cmdhandler.registerCommands(PluginTabComplete.instence);
|
||||
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);
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "cmd", description = "查看插件命令能耗", minimumArguments = 1, possibleArguments = "插件名称")
|
||||
public void cmd(final InvokeCommandEvent e) {
|
||||
final String pname = e.getArgs()[0];
|
||||
final CommandSender sender = e.getSender();
|
||||
@Cmd(aliases = "c", minimumArguments = 1)
|
||||
@Help(value = "查看插件命令能耗", possibleArguments = "[插件名称]")
|
||||
@Async
|
||||
public void cmd(CommandSender sender, String pname) {
|
||||
if (Bukkit.getPluginManager().getPlugin(pname) == null) {
|
||||
sender.sendMessage(String.format(p_n_f, pname));
|
||||
return;
|
||||
}
|
||||
final PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
|
||||
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的命令能耗如下!");
|
||||
final Map<String, Command> temp = new HashMap<>();
|
||||
for (final Command command : commandMap.getCommands()) {
|
||||
Map<String, Command> temp = new HashMap<>();
|
||||
for (Command command : commandMap.getCommands()) {
|
||||
if (command instanceof PluginCommand) {
|
||||
final PluginCommand pluginCommand = (PluginCommand) command;
|
||||
final Plugin plugin = pluginCommand.getPlugin();
|
||||
PluginCommand pluginCommand = (PluginCommand) command;
|
||||
Plugin plugin = pluginCommand.getPlugin();
|
||||
if (plugin.getName().equalsIgnoreCase(pname)) {
|
||||
temp.put(command.getName(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final Entry<String, Command> command : temp.entrySet()) {
|
||||
final CommandExecutor executor = Reflect.on(command.getValue()).get("executor");
|
||||
if (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");
|
||||
if (executor instanceof CommandInjector) {
|
||||
final CommandInjector injected = (CommandInjector) executor;
|
||||
final StringBuffer str = new StringBuffer();
|
||||
str.append("§6- §e" + command.getValue().getName() + " ");
|
||||
str.append(String.format(total, injected.totalTime / um));
|
||||
str.append(String.format(count, injected.count));
|
||||
CommandInjector injected = (CommandInjector) executor;
|
||||
if (injected.count != 0) {
|
||||
str.append(String.format(avg, injected.totalTime / um / injected.count));
|
||||
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));
|
||||
}
|
||||
e.getSender().sendMessage(str.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "event", description = "查看插件事件能耗", 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);
|
||||
@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);
|
||||
if (plugin == null) {
|
||||
sender.sendMessage(String.format(p_n_f, pname));
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的事件能耗如下!");
|
||||
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) {
|
||||
List<RegisteredListener> listeners = HandlerList.getRegisteredListeners(plugin);
|
||||
Map<String, Long> eventTotalTime = new HashMap<>();
|
||||
Map<String, Integer> eventCount = new HashMap<>();
|
||||
for (RegisteredListener listener : listeners) {
|
||||
if (listener instanceof TimedRegisteredListener) {
|
||||
final TimedRegisteredListener trl = (TimedRegisteredListener) listener;
|
||||
TimedRegisteredListener trl = (TimedRegisteredListener) listener;
|
||||
eventTotalTime.put(trl.getEventClass().getSimpleName(), trl.getTotalTime());
|
||||
eventCount.put(trl.getEventClass().getSimpleName(), trl.getCount());
|
||||
continue;
|
||||
}
|
||||
final EventExecutor executor = Reflect.on(listener).get("executor");
|
||||
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);
|
||||
}
|
||||
if (executor instanceof ListenerInjector) {
|
||||
final ListenerInjector injected = (ListenerInjector) executor;
|
||||
for (final String entry : injected.eventTotalTime.keySet()) {
|
||||
ListenerInjector injected = (ListenerInjector) executor;
|
||||
for (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));
|
||||
|
@ -122,46 +152,150 @@ public class MonitorCommand implements HandlerCommands {
|
|||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
final double avgTime = eventTotalTime.get(event) / um / eventCount.get(event);
|
||||
str.append(String.format(avgTime < 10 ? avg : avg_warn, avgTime));
|
||||
}
|
||||
e.getSender().sendMessage(str.toString());
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "task", description = "查看插件任务能耗", 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);
|
||||
@Cmd(aliases = "i", minimumArguments = 1)
|
||||
@Help(value = "注入能耗监控器", possibleArguments = "[插件名称]")
|
||||
public void inject(CommandSender sender, String pname) {
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(pname);
|
||||
if (plugin == null) {
|
||||
sender.sendMessage(String.format(p_n_f, pname));
|
||||
return;
|
||||
}
|
||||
final List<BukkitTask> pendingTasks = Bukkit.getScheduler().getPendingTasks();
|
||||
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;
|
||||
}
|
||||
sender.sendMessage(prefix + "§6插件 §b" + pname + " §6的任务能耗如下!");
|
||||
for (final BukkitTask pendingTask : pendingTasks) {
|
||||
sender.sendMessage(mitprefix);
|
||||
for (BukkitTask pendingTask : pendingTasks) {
|
||||
if (pendingTask.getOwner().getName().equalsIgnoreCase(pname)) {
|
||||
final Runnable task = Reflect.on(pendingTask).get("task");
|
||||
Runnable task = Reflect.on(pendingTask).get("task");
|
||||
if (task instanceof TaskInjector) {
|
||||
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));
|
||||
TaskInjector executor = (TaskInjector) task;
|
||||
if (executor.count != 0) {
|
||||
str.append(String.format(avg, executor.totalTime / um / executor.count));
|
||||
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));
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,78 @@
|
|||
package pw.yumc.Yum.commands;
|
||||
|
||||
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 java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
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 HandlerCommands {
|
||||
public class NetCommand implements Executor {
|
||||
public static HashMap<String, Integer> netlist = new HashMap<>();
|
||||
|
||||
public NetCommand(final Yum yum) {
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net");
|
||||
cmdhandler.registerCommands(this);
|
||||
cmdhandler.registerCommands(PluginTabComplete.instence);
|
||||
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);
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "list", aliases = "l", permission = "", description = "列出联网的插件")
|
||||
public void list(final InvokeCommandEvent e) {
|
||||
|
||||
public static void addNetCount(String pname) {
|
||||
if (netlist.containsKey(pname)) {
|
||||
netlist.put(pname, netlist.get(pname) + 1);
|
||||
} else {
|
||||
netlist.put(pname, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "off", description = "禁止插件联网", possibleArguments = "[插件名称]")
|
||||
public void off(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 = "on", description = "允许插件联网", possibleArguments = "[插件名称]")
|
||||
public void on(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黑名单"));
|
||||
}
|
||||
|
||||
@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白名单"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,35 +4,41 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cn.citycraft.PluginHelper.commands.HandlerCommands;
|
||||
import cn.citycraft.PluginHelper.commands.HandlerTabComplete;
|
||||
import cn.citycraft.PluginHelper.commands.InvokeCommandEvent;
|
||||
import cn.citycraft.PluginHelper.utils.StrKit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import pw.yumc.Yum.api.YumAPI;
|
||||
import pw.yumc.YumCore.commands.annotation.Tab;
|
||||
import pw.yumc.YumCore.commands.interfaces.Executor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 2016年7月7日 上午8:36:47
|
||||
* @author 喵♂呜
|
||||
* @since 2016年7月7日 上午8:36:47
|
||||
*/
|
||||
public class PluginTabComplete implements HandlerCommands {
|
||||
public static PluginTabComplete instence = new PluginTabComplete();
|
||||
public class PluginTabComplete implements Executor {
|
||||
public static PluginTabComplete INSTANCE = new PluginTabComplete();
|
||||
|
||||
@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>());
|
||||
@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:
|
||||
}
|
||||
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 null;
|
||||
return YumAPI.getPlugman().getPluginNames(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
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;
|
||||
|
@ -8,110 +11,225 @@ 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命令基类
|
||||
*
|
||||
* @since 2016年1月9日 上午10:02:24
|
||||
* @author 喵♂呜
|
||||
* @since 2016年1月9日 上午10:02:24
|
||||
*/
|
||||
public class YumCommand implements HandlerCommands, Listener {
|
||||
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文件解压错误!";
|
||||
|
||||
Yum main;
|
||||
|
||||
public YumCommand(final Yum yum) {
|
||||
public YumCommand(Yum yum) {
|
||||
main = yum;
|
||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum");
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false));
|
||||
cmdhandler.registerCommands(this);
|
||||
cmdhandler.registerCommands(PluginTabComplete.instence);
|
||||
new CommandSub("yum", this, PluginTabComplete.INSTANCE);
|
||||
}
|
||||
|
||||
@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);
|
||||
@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);
|
||||
if (plugin != null) {
|
||||
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
|
||||
String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
|
||||
if (YumAPI.getPlugman().deletePlugin(sender, plugin)) {
|
||||
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
|
||||
sender.sendMessage(String.format(del, pluginname, version));
|
||||
} else {
|
||||
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
|
||||
sender.sendMessage(String.format(delFailed, pluginname));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(pnf(pluginname));
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
@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) {
|
||||
try {
|
||||
final Class<?> clazz = Class.forName(classname);
|
||||
final Field field = clazz.getClassLoader().getClass().getDeclaredField("plugin");
|
||||
Class<?> clazz = Class.forName(classname);
|
||||
Field field = clazz.getClassLoader().getClass().getDeclaredField("plugin");
|
||||
field.setAccessible(true);
|
||||
final Plugin plugin = (JavaPlugin) field.get(clazz.getClassLoader());
|
||||
Plugin plugin = (JavaPlugin) field.get(clazz.getClassLoader());
|
||||
Bukkit.dispatchCommand(sender, "yum info " + plugin.getName());
|
||||
} catch (final ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
|
||||
sender.sendMessage("§4错误: 无法找到类 " + classname + " 所对应的插件信息 异常:" + e2.getClass().getSimpleName() + " " + e2.getMessage() + "!");
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@Cmd(aliases = "fdel", minimumArguments = 1)
|
||||
@Help(value = "删除插件以及数据文件夹", possibleArguments = "<插件名称>")
|
||||
@Sort(7)
|
||||
public void fulldelete(CommandSender sender, String pluginname) {
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
if (plugin != null) {
|
||||
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
|
||||
String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
|
||||
if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) {
|
||||
sender.sendMessage("§c删除: §a插件 §b" + pluginname + " §a版本 §d" + version + " §a已从服务器卸载并删除!");
|
||||
sender.sendMessage(String.format(del, pluginname, version));
|
||||
} else {
|
||||
sender.sendMessage("§c删除: §c插件 §b" + pluginname + " §c卸载或删除时发生错误 删除失败!");
|
||||
sender.sendMessage(String.format(delFailed, pluginname));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(pnf(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);
|
||||
@Cmd(minimumArguments = 1)
|
||||
@Help(value = "查看插件详情", possibleArguments = "<插件名称>")
|
||||
@Sort(2)
|
||||
@Async
|
||||
public void info(CommandSender sender, String pluginname) {
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
if (plugin != null) {
|
||||
final PluginDescriptionFile desc = plugin.getDescription();
|
||||
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() ? "无" : ""));
|
||||
StrKit.sendStringArray(sender, desc.getDepend(), "§6 - §a");
|
||||
sendStringArray(sender, desc.getDepend(), "§6 - §a");
|
||||
sender.sendMessage("§6插件软依赖: §3" + (desc.getSoftDepend().isEmpty() ? "无" : ""));
|
||||
StrKit.sendStringArray(sender, desc.getSoftDepend(), "§6 - §a");
|
||||
final Map<String, Map<String, Object>> clist = desc.getCommands();
|
||||
sendStringArray(sender, desc.getSoftDepend(), "§6 - §a");
|
||||
Map<String, Map<String, Object>> clist = desc.getCommands();
|
||||
if (clist != null) {
|
||||
sender.sendMessage("§6插件注册命令: §3" + (clist.isEmpty() ? "无" : ""));
|
||||
for (final Entry<String, Map<String, Object>> entry : clist.entrySet()) {
|
||||
for (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");
|
||||
|
@ -119,10 +237,10 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
sendEntry(sender, "§6 用法: §a", entry.getValue(), "usage");
|
||||
}
|
||||
}
|
||||
final List<Permission> plist = desc.getPermissions();
|
||||
List<Permission> plist = desc.getPermissions();
|
||||
if (plist != null) {
|
||||
sender.sendMessage("§6插件注册权限: " + (plist.isEmpty() ? "无" : ""));
|
||||
for (final Permission perm : plist) {
|
||||
for (Permission perm : plist) {
|
||||
sender.sendMessage("§6 - §a" + perm.getName() + "§6 - §e" + (perm.getDescription().isEmpty() ? "无描述" : perm.getDescription()));
|
||||
}
|
||||
}
|
||||
|
@ -132,20 +250,19 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@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);
|
||||
if (plugin == null) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(main, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (args.length < 2) {
|
||||
if (pluginversion == null) {
|
||||
YumAPI.installFromYum(sender, pluginname);
|
||||
} else {
|
||||
YumAPI.installFromYum(sender, pluginname, args[1]);
|
||||
YumAPI.installFromYum(sender, pluginname, pluginversion);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -154,20 +271,33 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "list", aliases = { "l" }, description = "列出已安装插件列表")
|
||||
public void list(final InvokeCommandEvent e) {
|
||||
final CommandSender sender = e.getSender();
|
||||
@Cmd(aliases = "l")
|
||||
@Help(value = "列出已安装插件列表")
|
||||
@Sort(1)
|
||||
@Async
|
||||
public void list(CommandSender sender) {
|
||||
sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: ");
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
sender.sendMessage("§6- " + YumAPI.getPlugman().getFormattedName(plugin, true));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@Cmd(minimumArguments = 1)
|
||||
@Help(value = "载入插件", possibleArguments = "<插件名称>")
|
||||
@Sort(3)
|
||||
public void load(CommandSender sender, String pluginname) {
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
if (plugin == null) {
|
||||
YumAPI.getPlugman().load(sender, pluginname);
|
||||
} else {
|
||||
|
@ -175,27 +305,20 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
@Cmd(aliases = "re")
|
||||
@Help(value = "重载插件", possibleArguments = "<插件名称|all|*>")
|
||||
@Sort(5)
|
||||
public void reload(CommandSender sender, String pluginname) {
|
||||
if (pluginname == null) {
|
||||
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;
|
||||
}
|
||||
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
if (plugin != null) {
|
||||
YumAPI.getPlugman().reload(sender, plugin);
|
||||
} else {
|
||||
|
@ -203,111 +326,91 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@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源地址未找到仓库信息或当前地址已缓存!");
|
||||
}
|
||||
@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的插件信息已缓存!");
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c请输入需要添加的源地址!");
|
||||
sender.sendMessage("§6仓库: §c源地址未找到仓库信息或当前地址已缓存!");
|
||||
}
|
||||
break;
|
||||
case "del":
|
||||
if (args.length == 2) {
|
||||
final Repositories delrepo = YumAPI.getRepo().getRepoCache(args[1]);
|
||||
if (delrepo != null) {
|
||||
YumAPI.getRepo().delRepositories(sender, args[1]);
|
||||
sender.sendMessage("§6仓库: §a源仓库 §e" + delrepo.name + " §c已删除 §a请使用 §b/yum repo update §a更新缓存!");
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c源地址未找到!");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c请输入需要删除的源地址!");
|
||||
}
|
||||
break;
|
||||
case "delall":
|
||||
YumAPI.getRepo().getRepoCache().getRepos().clear();
|
||||
sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!");
|
||||
break;
|
||||
case "list":
|
||||
sender.sendMessage("§6仓库: §b缓存的插件信息如下 ");
|
||||
StrKit.sendStringArray(sender, YumAPI.getRepo().getAllPluginsInfo());
|
||||
break;
|
||||
case "all":
|
||||
sender.sendMessage("§6仓库: §b缓存的仓库信息如下 ");
|
||||
StrKit.sendStringArray(sender, YumAPI.getRepo().getRepoCache().getAllRepoInfo());
|
||||
break;
|
||||
case "clean":
|
||||
YumAPI.getRepo().clean();
|
||||
sender.sendMessage("§6仓库: §a缓存的插件信息已清理!");
|
||||
break;
|
||||
case "update":
|
||||
YumAPI.getRepo().updateRepositories(sender);
|
||||
sender.sendMessage("§6仓库: §a仓库缓存数据已更新!");
|
||||
break;
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c请输入需要添加的源地址!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发生实体消息
|
||||
*
|
||||
* @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);
|
||||
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更新缓存!");
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c源地址未找到!");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("§6仓库: §c请输入需要删除的源地址!");
|
||||
}
|
||||
break;
|
||||
case "delall":
|
||||
YumAPI.getRepo().getRepoCache().getRepos().clear();
|
||||
sender.sendMessage("§6仓库: §a缓存的仓库信息已清理!");
|
||||
break;
|
||||
case "list":
|
||||
sender.sendMessage("§6仓库: §b缓存的插件信息如下 ");
|
||||
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
|
||||
*/
|
||||
@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(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);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@Cmd(minimumArguments = 1)
|
||||
@Help(value = "卸载插件", possibleArguments = "<插件名称>")
|
||||
@Sort(4)
|
||||
public void unload(CommandSender sender, String pluginname) {
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||
if (plugin != null) {
|
||||
YumAPI.getPlugman().unload(sender, plugin);
|
||||
} else {
|
||||
|
@ -315,75 +418,144 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@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:
|
||||
@Cmd(aliases = "u")
|
||||
@Help(value = "更新插件或缓存", possibleArguments = "[插件名称] [插件版本]")
|
||||
@Sort(13)
|
||||
@Async
|
||||
public void update(CommandSender sender, String argstring) {
|
||||
if (argstring == null) {
|
||||
YumAPI.getRepo().updateRepositories(sender);
|
||||
sender.sendMessage("§6仓库: §a仓库缓存数据已更新!");
|
||||
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) {
|
||||
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]);
|
||||
}
|
||||
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命令参数错误!");
|
||||
} else {
|
||||
sender.sendMessage("§c插件" + pluginname + "未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sender.sendMessage("§c命令参数错误!");
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
@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);
|
||||
if (plugin != null) {
|
||||
YumAPI.upgrade(sender, plugin);
|
||||
} else {
|
||||
sender.sendMessage("§c错误: §b插件 " + pluginname + " §c未安装或已卸载 需要安装请使用 §b/yum install " + pluginname + "!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
private String pnf(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,83 +1,84 @@
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
@ -46,20 +45,20 @@ import org.json.simple.JSONValue;
|
|||
*/
|
||||
|
||||
public class BukkitUpdater extends Updater {
|
||||
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 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 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 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 int BYTE_SIZE = 1024; // Used for downloading files
|
||||
private static int BYTE_SIZE = 1024; // Used for downloading files
|
||||
|
||||
// Update information
|
||||
// private static final String BUKKIT_DEV_SLUG = "protocollib";
|
||||
// private static final int BUKKIT_DEV_ID = 45564;
|
||||
// private static String BUKKIT_DEV_SLUG = "protocollib";
|
||||
// private static int BUKKIT_DEV_ID = 45564;
|
||||
|
||||
private URL url; // Connecting to RSS
|
||||
private File file; // The plugin's file
|
||||
|
@ -88,18 +87,18 @@ public class BukkitUpdater extends Updater {
|
|||
* @param announce
|
||||
* True if the program should announce the progress of new updates in console
|
||||
*/
|
||||
public BukkitUpdater(final Plugin plugin, final int id, final File file, final UpdateType type, final boolean announce) {
|
||||
public BukkitUpdater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
|
||||
this.file = file;
|
||||
this.id = id;
|
||||
this.updateFolder = plugin.getServer().getUpdateFolder();
|
||||
|
||||
final File dataFolder = plugin.getDataFolder();
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
if (dataFolder != null) {
|
||||
final File pluginFile = plugin.getDataFolder().getParentFile();
|
||||
final File updaterFile = new File(pluginFile, "Updater");
|
||||
final File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||
File pluginFile = plugin.getDataFolder().getParentFile();
|
||||
File updaterFile = new File(pluginFile, "Updater");
|
||||
File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||
|
||||
if (!updaterFile.exists()) {
|
||||
updaterFile.mkdir();
|
||||
|
@ -107,8 +106,9 @@ public class BukkitUpdater extends Updater {
|
|||
if (!updaterConfigFile.exists()) {
|
||||
try {
|
||||
updaterConfigFile.createNewFile();
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not create a configuration in " + updaterFile.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe(
|
||||
"The updater could not create a configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +128,9 @@ public class BukkitUpdater extends Updater {
|
|||
this.config.options().copyDefaults(true);
|
||||
try {
|
||||
this.config.save(updaterConfigFile);
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not save the configuration in " + updaterFile.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe(
|
||||
"The updater could not save the configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +150,7 @@ public class BukkitUpdater extends Updater {
|
|||
|
||||
try {
|
||||
this.url = new URL(BukkitUpdater.HOST + BukkitUpdater.QUERY + id);
|
||||
} catch (final MalformedURLException e) {
|
||||
} catch (MalformedURLException e) {
|
||||
plugin.getLogger().severe("The project ID provided for updating, " + id + " is invalid.");
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
e.printStackTrace();
|
||||
|
@ -166,7 +167,7 @@ public class BukkitUpdater extends Updater {
|
|||
*/
|
||||
/*
|
||||
* private boolean hasTag(String version) {
|
||||
* for (final String string : BukkitUpdater.NO_UPDATE_TAG) {
|
||||
* for (String string : BukkitUpdater.NO_UPDATE_TAG) {
|
||||
* if (version.contains(string)) {
|
||||
* return true;
|
||||
* }
|
||||
|
@ -177,7 +178,7 @@ public class BukkitUpdater extends Updater {
|
|||
|
||||
public boolean read() {
|
||||
try {
|
||||
final URLConnection conn = this.url.openConnection();
|
||||
URLConnection conn = this.url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
|
||||
if (this.apiKey != null) {
|
||||
|
@ -186,10 +187,10 @@ public class BukkitUpdater extends Updater {
|
|||
conn.addRequestProperty("User-Agent", "Updater (by Gravity)");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
final String response = reader.readLine();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String response = reader.readLine();
|
||||
|
||||
final JSONArray array = (JSONArray) JSONValue.parse(response);
|
||||
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);
|
||||
|
@ -197,7 +198,7 @@ public class BukkitUpdater extends Updater {
|
|||
return false;
|
||||
}
|
||||
|
||||
final JSONObject jsonObject = (JSONObject) array.get(array.size() - 1);
|
||||
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);
|
||||
|
@ -205,14 +206,16 @@ public class BukkitUpdater extends Updater {
|
|||
this.versionGameVersion = (String) jsonObject.get(BukkitUpdater.VERSION_VALUE);
|
||||
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
} catch (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();
|
||||
|
@ -228,7 +231,7 @@ public class BukkitUpdater extends Updater {
|
|||
* - the update type.
|
||||
*/
|
||||
@Override
|
||||
public void start(final UpdateType type) {
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
|
||||
this.type = type;
|
||||
|
@ -239,11 +242,9 @@ 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(final String name) {
|
||||
for (final File file : new File("plugins").listFiles()) {
|
||||
if (file.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
private boolean pluginFile(String name) {
|
||||
for (File file : new File("plugins").listFiles()) {
|
||||
if (file.getName().equals(name)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -251,7 +252,7 @@ public class BukkitUpdater extends Updater {
|
|||
/**
|
||||
* Save an update from dev.bukkit.org into the server's update folder.
|
||||
*/
|
||||
private void saveFile(final File folder, final String file, final String u) {
|
||||
private void saveFile(File folder, String file, String u) {
|
||||
if (!folder.exists()) {
|
||||
folder.mkdir();
|
||||
}
|
||||
|
@ -259,12 +260,12 @@ public class BukkitUpdater extends Updater {
|
|||
FileOutputStream fout = null;
|
||||
try {
|
||||
// Download the file
|
||||
final URL url = new URL(u);
|
||||
final int fileLength = url.openConnection().getContentLength();
|
||||
URL url = new URL(u);
|
||||
int fileLength = url.openConnection().getContentLength();
|
||||
in = new BufferedInputStream(url.openStream());
|
||||
fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
|
||||
|
||||
final byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
int count;
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
|
||||
|
@ -273,19 +274,19 @@ public class BukkitUpdater extends Updater {
|
|||
while ((count = in.read(data, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
|
||||
downloaded += count;
|
||||
fout.write(data, 0, count);
|
||||
final int percent = (int) ((downloaded * 100) / fileLength);
|
||||
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 (final File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
|
||||
for (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.
|
||||
final File dFile = new File(folder.getAbsolutePath() + "/" + file);
|
||||
File dFile = new File(folder.getAbsolutePath() + "/" + file);
|
||||
if (dFile.getName().endsWith(".zip")) {
|
||||
// Unzip
|
||||
this.unzip(dFile.getCanonicalPath());
|
||||
|
@ -293,7 +294,7 @@ public class BukkitUpdater extends Updater {
|
|||
if (this.announce) {
|
||||
this.plugin.getLogger().info("Finished updating.");
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
} catch (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 {
|
||||
|
@ -304,7 +305,7 @@ public class BukkitUpdater extends Updater {
|
|||
if (fout != null) {
|
||||
fout.close();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,10 +313,10 @@ public class BukkitUpdater extends Updater {
|
|||
/**
|
||||
* Part of Zip-File-Extractor, modified by Gravity for use with Bukkit
|
||||
*/
|
||||
private void unzip(final String file) {
|
||||
private void unzip(String file) {
|
||||
try {
|
||||
final File fSourceZip = new File(file);
|
||||
final String zipPath = file.substring(0, file.length() - 4);
|
||||
File fSourceZip = new File(file);
|
||||
String zipPath = file.substring(0, file.length() - 4);
|
||||
ZipFile zipFile = new ZipFile(fSourceZip);
|
||||
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
|
@ -325,20 +326,21 @@ public class BukkitUpdater extends Updater {
|
|||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
int b;
|
||||
final byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos, BukkitUpdater.BYTE_SIZE);
|
||||
byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||
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();
|
||||
final String name = destinationFilePath.getName();
|
||||
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;
|
||||
|
@ -348,15 +350,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 (final File dFile : new File(zipPath).listFiles()) {
|
||||
for (File dFile : new File(zipPath).listFiles()) {
|
||||
if (dFile.isDirectory()) {
|
||||
if (this.pluginFile(dFile.getName())) {
|
||||
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
|
||||
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
|
||||
{
|
||||
boolean found = false;
|
||||
for (final File xFile : contents) // Loop through contents to see if it exists
|
||||
for (File xFile : contents) // Loop through contents to see if it exists
|
||||
{
|
||||
if (xFile.getName().equals(cFile.getName())) {
|
||||
found = true;
|
||||
|
@ -377,7 +379,7 @@ public class BukkitUpdater extends Updater {
|
|||
}
|
||||
new File(zipPath).delete();
|
||||
fSourceZip.delete();
|
||||
} catch (final IOException ex) {
|
||||
} catch (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();
|
||||
|
@ -398,11 +400,11 @@ public class BukkitUpdater extends Updater {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
} catch (Exception e) {
|
||||
// Any generic error will be handled here
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (final Runnable listener : listeners) {
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
|
@ -410,8 +412,8 @@ public class BukkitUpdater extends Updater {
|
|||
|
||||
private void performUpdate() {
|
||||
if ((BukkitUpdater.this.versionLink != null) && (BukkitUpdater.this.type != UpdateType.NO_DOWNLOAD)) {
|
||||
final File pluginFolder = plugin.getDataFolder().getParentFile();
|
||||
final File destinationFolder = new File(pluginFolder, updateFolder);
|
||||
File pluginFolder = plugin.getDataFolder().getParentFile();
|
||||
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
|
||||
|
|
|
@ -33,21 +33,22 @@ import com.google.common.io.Closer;
|
|||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class SpigotUpdater extends Updater {
|
||||
private static final String PROTOCOL = "https://";
|
||||
public class SpigotUpdater extends Updater {
|
||||
private static String PROTOCOL = "https://";
|
||||
|
||||
private static final String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
|
||||
private static String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
|
||||
|
||||
private static final String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
|
||||
private static String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
|
||||
|
||||
private static final String ACTION = "POST";
|
||||
private static String ACTION = "POST";
|
||||
|
||||
private static final int ID = 1997;
|
||||
private static int ID = 1997;
|
||||
|
||||
private static final byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=" + ID).getBytes(Charsets.UTF_8);
|
||||
private static byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource="
|
||||
+ ID).getBytes(Charsets.UTF_8);
|
||||
private String remoteVersion;
|
||||
|
||||
public SpigotUpdater(final Plugin plugin, final UpdateType type, final boolean announce) {
|
||||
public SpigotUpdater(Plugin plugin, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
}
|
||||
|
||||
|
@ -63,15 +64,15 @@ public final class SpigotUpdater extends Updater {
|
|||
}
|
||||
|
||||
public String getSpigotVersion() throws IOException {
|
||||
final Closer closer = Closer.create();
|
||||
Closer closer = Closer.create();
|
||||
try {
|
||||
final HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
|
||||
con.setDoOutput(true);
|
||||
con.setRequestMethod(ACTION);
|
||||
con.getOutputStream().write(API_KEY);
|
||||
|
||||
final InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
|
||||
final BufferedReader br = closer.register(new BufferedReader(isr));
|
||||
InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
|
||||
BufferedReader br = closer.register(new BufferedReader(isr));
|
||||
return br.readLine();
|
||||
} finally {
|
||||
closer.close();
|
||||
|
@ -79,7 +80,7 @@ public final class SpigotUpdater extends Updater {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void start(final UpdateType type) {
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
this.type = type;
|
||||
this.thread = new Thread(new SpigotUpdateRunnable());
|
||||
|
@ -90,17 +91,17 @@ public final class SpigotUpdater extends Updater {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String version = getSpigotVersion();
|
||||
String version = getSpigotVersion();
|
||||
remoteVersion = version;
|
||||
if (versionCheck(version)) {
|
||||
result = UpdateResult.SPIGOT_UPDATE_AVAILABLE;
|
||||
} else {
|
||||
result = UpdateResult.NO_UPDATE;
|
||||
}
|
||||
} catch (final Throwable ex) {
|
||||
} catch (Throwable ex) {
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (final Runnable listener : listeners) {
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public abstract class Updater {
|
|||
|
||||
protected List<Runnable> listeners = new CopyOnWriteArrayList<Runnable>();
|
||||
|
||||
public static Updater create(final Plugin protocolLib, final int id, final File file, final UpdateType type, final boolean announce) {
|
||||
public static Updater create(Plugin protocolLib, int id, File file, UpdateType type, boolean announce) {
|
||||
// if (Util.isUsingSpigot()) {
|
||||
return new SpigotUpdater(protocolLib, type, announce);
|
||||
// } else {
|
||||
|
@ -53,7 +53,7 @@ public abstract class Updater {
|
|||
// }
|
||||
}
|
||||
|
||||
protected Updater(final Plugin plugin, final UpdateType type, final boolean announce) {
|
||||
protected Updater(Plugin plugin, UpdateType type, 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(final Runnable listener) {
|
||||
public void addListener(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(final Runnable listener) {
|
||||
public boolean removeListener(Runnable listener) {
|
||||
return listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ public abstract class Updater {
|
|||
|
||||
public abstract void start(UpdateType type);
|
||||
|
||||
public boolean versionCheck(final String title) {
|
||||
public boolean versionCheck(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("-"));
|
||||
}
|
||||
|
||||
final String[] splitTitle = title.split(" ");
|
||||
String[] splitTitle = title.split(" ");
|
||||
String remoteVersion;
|
||||
|
||||
if (splitTitle.length == 2) {
|
||||
|
@ -165,9 +165,13 @@ public abstract class Updater {
|
|||
remoteVersion = splitTitle[0];
|
||||
} else {
|
||||
// The file's name did not contain the string 'vVersion'
|
||||
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]'");
|
||||
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;
|
||||
|
@ -178,7 +182,7 @@ public abstract class Updater {
|
|||
remoteVersion = remoteVersion.substring(1);
|
||||
}
|
||||
|
||||
final String localVersion = plugin.getDescription().getVersion();
|
||||
String localVersion = plugin.getDescription().getVersion();
|
||||
|
||||
if (devBuild && remoteVersion.equals(localVersion)) {
|
||||
// They're using a dev build and this version has been released
|
||||
|
@ -196,7 +200,7 @@ public abstract class Updater {
|
|||
if (thread != null && thread.isAlive()) {
|
||||
try {
|
||||
thread.join();
|
||||
} catch (final InterruptedException ex) {
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -255,9 +259,9 @@ public abstract class Updater {
|
|||
*/
|
||||
SPIGOT_UPDATE_AVAILABLE("The updater found an update: %s (Running %s). Download at %s");
|
||||
|
||||
private final String description;
|
||||
private String description;
|
||||
|
||||
private UpdateResult(final String description) {
|
||||
private UpdateResult(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,75 +1,86 @@
|
|||
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;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
|
||||
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;
|
||||
|
||||
private final CommandExecutor originalExecutor;
|
||||
private final TabCompleter originalCompleter;
|
||||
private Plugin plugin;
|
||||
|
||||
public long totalTime;
|
||||
public int count;
|
||||
|
||||
public CommandInjector(final CommandExecutor originalCommandExecutor, final TabCompleter originalTabCompleter) {
|
||||
public CommandInjector(CommandExecutor originalCommandExecutor, TabCompleter originalTabCompleter, Plugin plugin) {
|
||||
this.originalExecutor = originalCommandExecutor;
|
||||
this.originalCompleter = originalTabCompleter;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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(final Plugin toUninject) {
|
||||
final PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
final SimpleCommandMap commandMap = Reflect.on(pluginManager).get("commandMap");
|
||||
for (final Command command : commandMap.getCommands()) {
|
||||
if (command instanceof PluginCommand) {
|
||||
final PluginCommand pluginCommand = (PluginCommand) command;
|
||||
final Plugin plugin = pluginCommand.getPlugin();
|
||||
if (plugin.equals(toUninject)) {
|
||||
final CommandExecutor executor = Reflect.on(command).get("executor");
|
||||
if (executor instanceof CommandInjector) {
|
||||
final CommandInjector injected = (CommandInjector) executor;
|
||||
Reflect.on(command).set("executor", injected.getOriginalExecutor());
|
||||
}
|
||||
final TabCompleter completer = Reflect.on(command).get("completer");
|
||||
if (completer instanceof CommandInjector) {
|
||||
final CommandInjector injected = (CommandInjector) completer;
|
||||
Reflect.on(command).set("completer", injected.getOriginalCompleter());
|
||||
public 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,26 +93,38 @@ public class CommandInjector implements TabExecutor {
|
|||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
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();
|
||||
|
||||
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();
|
||||
totalTime += end - start;
|
||||
count++;
|
||||
return result;
|
||||
|
|
|
@ -1,104 +1,119 @@
|
|||
package pw.yumc.Yum.inject;
|
||||
|
||||
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;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
import org.bukkit.plugin.TimedRegisteredListener;
|
||||
|
||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import pw.yumc.Yum.managers.ConfigManager;
|
||||
|
||||
public class ListenerInjector implements EventExecutor {
|
||||
private final String prefix = "§6[§bYum §a事件监控§6] ";
|
||||
private final EventExecutor originalExecutor;
|
||||
|
||||
private final Plugin plugin;
|
||||
|
||||
public Map<String, Long> eventTotalTime;
|
||||
public Map<String, Integer> eventCount;
|
||||
|
||||
public ListenerInjector(final EventExecutor originalExecutor, final Plugin plugin) {
|
||||
this.originalExecutor = originalExecutor;
|
||||
this.plugin = plugin;
|
||||
eventTotalTime = new HashMap<>();
|
||||
eventCount = new HashMap<>();
|
||||
}
|
||||
|
||||
public static void inject(final Plugin plugin) {
|
||||
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(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final Listener listener, final Event event) throws EventException {
|
||||
try {
|
||||
if (!event.isAsynchronous()) {
|
||||
final long start = System.nanoTime();
|
||||
// TODO 当操作大于10ms的时候添加一个Lag提示
|
||||
originalExecutor.execute(listener, event);
|
||||
final long end = System.nanoTime();
|
||||
final String en = event.getEventName();
|
||||
final long lag = end - start;
|
||||
if (lag / 1000000 > 10 && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
|
||||
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时§c耗时 §4" + lag / 1000000 + "ms!");
|
||||
}
|
||||
if (eventTotalTime.containsKey(en)) {
|
||||
eventTotalTime.put(en, eventTotalTime.get(en) + lag);
|
||||
eventCount.put(en, eventCount.get(en) + 1);
|
||||
} else {
|
||||
eventTotalTime.put(en, end - start);
|
||||
eventCount.put(en, 1);
|
||||
}
|
||||
} else {
|
||||
originalExecutor.execute(listener, event);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null) {
|
||||
e = e.getCause();
|
||||
}
|
||||
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)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EventExecutor getOriginalExecutor() {
|
||||
return originalExecutor;
|
||||
}
|
||||
}
|
||||
package pw.yumc.Yum.inject;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
import 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;
|
||||
|
||||
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 Plugin plugin;
|
||||
|
||||
public Map<String, Long> eventTotalTime = new ConcurrentHashMap<>();
|
||||
public Map<String, Integer> eventCount = new ConcurrentHashMap<>();
|
||||
|
||||
public ListenerInjector(EventExecutor originalExecutor, Plugin plugin) {
|
||||
this.originalExecutor = originalExecutor;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
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 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());
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
try {
|
||||
if (!event.isAsynchronous()) {
|
||||
long start = System.nanoTime();
|
||||
originalExecutor.execute(listener, event);
|
||||
long end = System.nanoTime();
|
||||
String en = event.getEventName();
|
||||
long lag = end - start;
|
||||
if (eventTotalTime.containsKey(en)) {
|
||||
eventTotalTime.put(en, eventTotalTime.get(en) + lag);
|
||||
eventCount.put(en, eventCount.get(en) + 1);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null) {
|
||||
e = e.getCause();
|
||||
}
|
||||
MonitorCommand.lastError = e;
|
||||
MonitorManager.printThrowable(plugin, String.format(err, plugin.getName(), event.getEventName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
public EventExecutor getOriginalExecutor() {
|
||||
return originalExecutor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,91 @@
|
|||
package pw.yumc.Yum.inject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import pw.yumc.Yum.commands.MonitorCommand;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.kit.StrKit;
|
||||
import pw.yumc.YumCore.reflect.Reflect;
|
||||
|
||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
import java.util.List;
|
||||
|
||||
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";
|
||||
|
||||
private final Runnable originalTask;
|
||||
static {
|
||||
BukkitTask task = Bukkit.getServer().getScheduler().runTask(P.instance, new Runnable() {
|
||||
@Override
|
||||
public void run() {}
|
||||
});
|
||||
try {
|
||||
Reflect.on(task).get("rTask");
|
||||
taskFieldName = "rTask";
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable originalTask;
|
||||
private Plugin plugin;
|
||||
|
||||
private String taskName;
|
||||
|
||||
public long totalTime;
|
||||
public int count;
|
||||
|
||||
public TaskInjector(final Runnable originalTask) {
|
||||
public TaskInjector(Runnable originalTask, Plugin plugin) {
|
||||
this.originalTask = originalTask;
|
||||
this.plugin = plugin;
|
||||
Class<? extends Runnable> taskClass = getOriginalTask().getClass();
|
||||
taskName = StrKit.isBlank(taskClass.getSimpleName()) ? taskClass.getName() : taskClass.getSimpleName();
|
||||
}
|
||||
|
||||
// 当前注入只能对TimerTask有效
|
||||
// 对于单次执行的任务 我们需要注册一个动态的代理
|
||||
public static void inject(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;
|
||||
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);
|
||||
}
|
||||
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(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());
|
||||
public static void uninject(Plugin plugin) {
|
||||
Validate.notNull(plugin, plugin_is_null);
|
||||
try {
|
||||
BukkitScheduler scheduler = Bukkit.getScheduler();
|
||||
List<BukkitTask> pendingTasks = scheduler.getPendingTasks();
|
||||
for (BukkitTask pendingTask : pendingTasks) {
|
||||
// 忽略异步任务
|
||||
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
|
||||
Runnable originalTask = Reflect.on(pendingTask).get("task");
|
||||
if (originalTask instanceof TaskInjector) {
|
||||
Reflect.on(pendingTask).set("task", ((TaskInjector) originalTask).getOriginalTask());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,11 +95,25 @@ public class TaskInjector implements Runnable {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
final long start = System.nanoTime();
|
||||
// TODO 当操作大于10ms的时候添加一个Lag提示
|
||||
originalTask.run();
|
||||
final long end = System.nanoTime();
|
||||
totalTime += end - start;
|
||||
count++;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@ 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;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -18,17 +21,24 @@ import pw.yumc.Yum.api.YumAPI;
|
|||
public class PluginListener implements Listener {
|
||||
|
||||
public PluginListener() {
|
||||
Bukkit.getPluginManager().registerEvents(this, PKit.i());
|
||||
PluginKit.scp("§a性能监控系统已启用...");
|
||||
Bukkit.getPluginManager().registerEvents(this, P.instance);
|
||||
Log.console("§a性能监控系统已启用...");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(final PluginDisableEvent e) {
|
||||
public void onPluginDisable(PluginDisableEvent e) {
|
||||
YumAPI.uninject(e.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(final PluginEnableEvent e) {
|
||||
YumAPI.inject(e.getPlugin());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,11 @@ 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] ";
|
||||
|
@ -17,49 +18,46 @@ public class PluginNetworkListener implements Listener {
|
|||
public String breaked = "§c已阻止插件 §b%s §c访问网络!";
|
||||
public String url = "§6地址: §c%s";
|
||||
|
||||
public PluginNetworkListener(final Yum yum) {
|
||||
public PluginNetworkListener(Yum yum) {
|
||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||
}
|
||||
|
||||
public void breakNetwork(final PluginNetworkEvent e) {
|
||||
public void breakNetwork(PluginNetworkEvent e) {
|
||||
if (ConfigManager.i().isNetworkShowInfo()) {
|
||||
PluginKit.sc(String.format(prefix + breaked, e.getPlugin().getName()));
|
||||
PluginKit.sc(String.format(prefix + url, e.getUrl().toString()));
|
||||
Log.console(prefix + breaked, e.getPlugin().getName());
|
||||
Log.console(prefix + url, e.getUrl().toString());
|
||||
}
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
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 大神你好 = "反编译的大神们我知道你们又要说了这货有后门";
|
||||
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 大神你好 = "反编译的大神们我知道你们又要说了这货有后门";
|
||||
大神你好.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()) {
|
||||
PluginKit.sc(String.format(prefix + warnMain, plugin.getName()));
|
||||
Log.console(prefix + warnMain, plugin.getName());
|
||||
if (!ConfigManager.i().isAllowPrimaryThread()) {
|
||||
breakNetwork(e);
|
||||
}
|
||||
} else {
|
||||
PluginKit.sc(String.format(prefix + warn, plugin.getName()));
|
||||
PluginKit.sc(String.format(prefix + url, urlinfo));
|
||||
Log.console(prefix + warn, plugin.getName());
|
||||
Log.console(prefix + url, urlinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +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.managers.ConfigManager;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.kit.PKit;
|
||||
import pw.yumc.injected.event.SetOpEvent;
|
||||
|
||||
/**
|
||||
|
@ -16,26 +17,24 @@ import pw.yumc.injected.event.SetOpEvent;
|
|||
* @author 喵♂呜
|
||||
*/
|
||||
public class SecurityListener implements Listener {
|
||||
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安全系统已成功拦截!";
|
||||
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安全系统已成功拦截!";
|
||||
|
||||
public SecurityListener(final Yum yum) {
|
||||
public SecurityListener(Yum yum) {
|
||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void setop(final SetOpEvent e) {
|
||||
final Plugin plugin = PluginKit.getOperatePlugin();
|
||||
public void setop(SetOpEvent e) {
|
||||
Plugin plugin = PKit.getOperatePlugin();
|
||||
if (plugin != null) {
|
||||
if (ConfigManager.i().getSetOpBlackList().contains(plugin.getName())) {
|
||||
PluginKit.sc(String.format(prefix + prevent, plugin, e.getOfflinePlayer().getName()));
|
||||
Log.console(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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,98 +1,94 @@
|
|||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,105 +1,129 @@
|
|||
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 final FileConfig monitor;
|
||||
|
||||
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");
|
||||
monitor = new FileConfig(plugin, "monitor.yml");
|
||||
}
|
||||
|
||||
public static ConfigManager i() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public List<String> getBlackList() {
|
||||
return config.getStringList("blacklist");
|
||||
}
|
||||
|
||||
public List<String> getIgnoreList() {
|
||||
return config.getStringList("ignorelist");
|
||||
}
|
||||
|
||||
public List<String> getMonitorIgnoreList() {
|
||||
return monitor.getStringList(IGNORE);
|
||||
}
|
||||
|
||||
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 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 void reload() {
|
||||
setop.reload();
|
||||
network.reload();
|
||||
thread.reload();
|
||||
monitor.reload();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
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";
|
||||
}
|
||||
}
|
|
@ -3,8 +3,10 @@ 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;
|
||||
|
@ -12,6 +14,8 @@ import org.bukkit.command.CommandSender;
|
|||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
|
||||
import pw.yumc.YumCore.callback.CallBack.One;
|
||||
|
||||
/**
|
||||
* 下载管理类
|
||||
*
|
||||
|
@ -21,7 +25,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
|
|||
public class DownloadManager {
|
||||
Plugin plugin;
|
||||
|
||||
public DownloadManager(final Plugin main) {
|
||||
public DownloadManager(Plugin main) {
|
||||
this.plugin = main;
|
||||
}
|
||||
|
||||
|
@ -32,8 +36,8 @@ public class DownloadManager {
|
|||
* - 地址
|
||||
* @return 文件名称
|
||||
*/
|
||||
public String getFileName(final String url) {
|
||||
final int end = url.lastIndexOf('/');
|
||||
public String getFileName(String url) {
|
||||
int end = url.lastIndexOf('/');
|
||||
return url.substring(end + 1);
|
||||
}
|
||||
|
||||
|
@ -44,7 +48,7 @@ public class DownloadManager {
|
|||
* - 地址
|
||||
* @return 文件名称
|
||||
*/
|
||||
public String getFileName(final URL url) {
|
||||
public String getFileName(URL url) {
|
||||
return getFileName(url.getFile());
|
||||
}
|
||||
|
||||
|
@ -57,8 +61,8 @@ public class DownloadManager {
|
|||
* - 下载地址
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(final CommandSender sender, final String urlstring) {
|
||||
return run(sender, urlstring, new File("plugins", getFileName(urlstring)));
|
||||
public boolean run(CommandSender sender, String urlstring) {
|
||||
return run(sender, urlstring, new File("plugins", getFileName(urlstring)), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,11 +76,35 @@ public class DownloadManager {
|
|||
* - 保存文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(final CommandSender sender, final String urlstring, final File file) {
|
||||
public boolean run(CommandSender sender, String urlstring, File file) {
|
||||
try {
|
||||
final URL url = new URL(urlstring);
|
||||
URL url = new URL(urlstring);
|
||||
return run(sender, url, file);
|
||||
} catch (final MalformedURLException e) {
|
||||
} 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) {
|
||||
sender.sendMessage("§4错误: §c无法识别的URL地址...");
|
||||
sender.sendMessage("§4地址: §c" + urlstring);
|
||||
return false;
|
||||
|
@ -94,7 +122,24 @@ public class DownloadManager {
|
|||
* - 保存文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(CommandSender sender, final URL url, final File file) {
|
||||
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) {
|
||||
BufferedInputStream in = null;
|
||||
FileOutputStream fout = null;
|
||||
if (sender == null) {
|
||||
|
@ -103,14 +148,27 @@ public class DownloadManager {
|
|||
try {
|
||||
sender.sendMessage("§6开始下载: §3" + getFileName(url));
|
||||
sender.sendMessage("§6下载地址: §3" + url.toString());
|
||||
final int fileLength = url.openConnection().getContentLength();
|
||||
if (fileLength < 0) {
|
||||
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) {
|
||||
sender.sendMessage("§6下载: §c文件 " + file.getName() + " 获取长度错误(可能是网络问题)!");
|
||||
sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!");
|
||||
return false;
|
||||
}
|
||||
sender.sendMessage("§6文件长度: §3" + fileLength);
|
||||
in = new BufferedInputStream(url.openStream());
|
||||
sender.sendMessage("§6文件长度: §3" + (dyml ? "动态长度" : fileLength));
|
||||
in = new BufferedInputStream(uc.getInputStream());
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
sender.sendMessage("§6创建新目录: §d" + file.getParentFile().getAbsolutePath());
|
||||
|
@ -121,31 +179,38 @@ public class DownloadManager {
|
|||
file.createNewFile();
|
||||
sender.sendMessage("§6创建新文件: §d" + file.getAbsolutePath());
|
||||
fout = new FileOutputStream(file);
|
||||
final byte[] data = new byte[1024];
|
||||
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);
|
||||
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));
|
||||
if (dyml) {
|
||||
if (System.currentTimeMillis() - time > 1000) {
|
||||
sender.sendMessage(String.format("§6已下载: §a%sk", downloaded / 1024));
|
||||
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 {
|
||||
final PluginDescriptionFile desc = plugin.getPluginLoader().getPluginDescription(file);
|
||||
PluginDescriptionFile desc = plugin.getPluginLoader().getPluginDescription(file);
|
||||
pVer = StringUtils.substring(desc.getVersion(), 0, 15);
|
||||
} catch (final Exception e) {
|
||||
} catch (Exception e) {
|
||||
pVer = "";
|
||||
}
|
||||
sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName() + (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!");
|
||||
return true;
|
||||
} catch (final Exception ex) {
|
||||
sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName()
|
||||
+ (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!");
|
||||
} catch (Exception ex) {
|
||||
sender.sendMessage("§6异常: §c" + ex.getMessage());
|
||||
sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!");
|
||||
return false;
|
||||
|
@ -157,9 +222,13 @@ public class DownloadManager {
|
|||
if (fout != null) {
|
||||
fout.close();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.run(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,7 +238,7 @@ public class DownloadManager {
|
|||
* - 下载地址
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(final String urlstring) {
|
||||
public boolean run(String urlstring) {
|
||||
return run(null, urlstring);
|
||||
}
|
||||
|
||||
|
@ -182,8 +251,8 @@ public class DownloadManager {
|
|||
* - 保存文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(final String urlstring, final File file) {
|
||||
return run(null, urlstring, file);
|
||||
public boolean run(String urlstring, File file) {
|
||||
return run(null, urlstring, file, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,12 +264,12 @@ public class DownloadManager {
|
|||
* - 保存文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean run(final URL url, final File file) {
|
||||
return run(null, url, file);
|
||||
public boolean run(URL url, File file) {
|
||||
return run(null, url, file, null);
|
||||
}
|
||||
|
||||
private String getPer(final int per) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
private String getPer(int per) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 11; i++) {
|
||||
if (per > i) {
|
||||
sb.append("==");
|
||||
|
@ -213,4 +282,23 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
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 2016年7月19日 下午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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Map按value进行排序
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,10 +9,11 @@ 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;
|
||||
|
||||
/**
|
||||
* 网络代理处理类
|
||||
|
@ -22,27 +23,27 @@ import pw.yumc.Yum.events.PluginNetworkEvent;
|
|||
*/
|
||||
public class NetworkManager {
|
||||
|
||||
public static void register(final Yum plugin) {
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
||||
public static void register(Yum plugin) {
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
||||
ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin));
|
||||
}
|
||||
|
||||
public static void unregister() {
|
||||
final ProxySelector cur = ProxySelector.getDefault();
|
||||
ProxySelector cur = ProxySelector.getDefault();
|
||||
if (cur instanceof YumProxySelector) {
|
||||
ProxySelector.setDefault(((YumProxySelector) cur).getDefaultSelector());
|
||||
}
|
||||
}
|
||||
|
||||
static class YumProxySelector extends ProxySelector {
|
||||
private final ProxySelector defaultSelector;
|
||||
private ProxySelector defaultSelector;
|
||||
|
||||
public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) {
|
||||
public YumProxySelector(ProxySelector defaultSelector, Yum plugin) {
|
||||
this.defaultSelector = defaultSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(final URI uri, final SocketAddress sa, final IOException ioe) {
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
defaultSelector.connectFailed(uri, sa, ioe);
|
||||
}
|
||||
|
||||
|
@ -51,11 +52,12 @@ public class NetworkManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(final URI uri) {
|
||||
final PluginNetworkEvent pne = new PluginNetworkEvent(PluginKit.getOperatePlugin(), uri, Bukkit.isPrimaryThread());
|
||||
public List<Proxy> select(URI uri) {
|
||||
if (uri.toString().startsWith("socket")) { return defaultSelector.select(uri); }
|
||||
PluginNetworkEvent pne = new PluginNetworkEvent(PKit.getOperatePlugin(), uri, Bukkit.isPrimaryThread());
|
||||
Bukkit.getPluginManager().callEvent(pne);
|
||||
if (pne.isCancelled()) {
|
||||
ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 并被联网规则拦截!"));
|
||||
ExKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 并被联网规则拦截!"));
|
||||
}
|
||||
return defaultSelector.select(uri);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,3 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package pw.yumc.Yum.managers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -11,11 +8,9 @@ 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;
|
||||
|
@ -24,6 +19,7 @@ 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;
|
||||
|
||||
/**
|
||||
* 仓库管理类
|
||||
|
@ -32,72 +28,64 @@ import pw.yumc.Yum.models.RepoSerialization.URLType;
|
|||
* @since 2016年1月9日 上午10:02:57
|
||||
*/
|
||||
public class RepositoryManager {
|
||||
PluginHelperLogger logger = PluginHelperLogger.getLogger();
|
||||
org.bukkit.plugin.Plugin main;
|
||||
RepoCache repocache;
|
||||
|
||||
public RepositoryManager(final org.bukkit.plugin.Plugin plugin) {
|
||||
public RepositoryManager(org.bukkit.plugin.Plugin plugin) {
|
||||
this.main = plugin;
|
||||
repocache = new RepoCache();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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; }
|
||||
updatePackage(sender, pkg);
|
||||
return true;
|
||||
}
|
||||
|
||||
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 boolean addRepositories(CommandSender sender, String urlstring) {
|
||||
String url = handerRepoUrl(urlstring);
|
||||
Repositories repo = repocache.addRepo(url);
|
||||
return repo != null && updateRepositories(sender, repo);
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
repocache.getPlugins().clear();
|
||||
}
|
||||
|
||||
public boolean delRepositories(final CommandSender sender, final String urlstring) {
|
||||
public boolean delRepositories(CommandSender sender, String urlstring) {
|
||||
return repocache.removeRepo(handerRepoUrl(urlstring));
|
||||
}
|
||||
|
||||
public List<PluginInfo> getAllPlugin() {
|
||||
final List<PluginInfo> li = new ArrayList<PluginInfo>();
|
||||
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
List<PluginInfo> li = new ArrayList<>();
|
||||
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
li.add(plugin.getValue());
|
||||
}
|
||||
return li;
|
||||
}
|
||||
|
||||
public List<String> getAllPluginName() {
|
||||
final List<String> li = new ArrayList<String>();
|
||||
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
List<String> li = new ArrayList<>();
|
||||
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
li.add(plugin.getValue().name);
|
||||
}
|
||||
return li;
|
||||
}
|
||||
|
||||
public List<String> getAllPluginsInfo() {
|
||||
final List<String> li = new ArrayList<String>();
|
||||
List<String> li = new ArrayList<>();
|
||||
li.add("§d仓库名称 §a插件名称 §e插件描述");
|
||||
for (final Entry<String, PluginInfo> pi : repocache.getPlugins().entrySet()) {
|
||||
final Plugin plugin = pi.getValue().plugin;
|
||||
for (Entry<String, PluginInfo> pi : repocache.getPlugins().entrySet()) {
|
||||
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类型");
|
||||
final List<TagInfo> taglist = plugin.tags;
|
||||
List<TagInfo> taglist = plugin.tags;
|
||||
for (int i = 0; i < taglist.size(); i++) {
|
||||
final TagInfo tag = taglist.get(i);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -105,18 +93,16 @@ public class RepositoryManager {
|
|||
return li;
|
||||
}
|
||||
|
||||
public PluginInfo getPlugin(final String name) {
|
||||
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
if (plugin.getValue().name.equalsIgnoreCase(name)) {
|
||||
return plugin.getValue();
|
||||
}
|
||||
public PluginInfo getPlugin(String name) {
|
||||
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
if (plugin.getValue().name.equalsIgnoreCase(name)) { return plugin.getValue(); }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<PluginInfo> getPluginInfo(final String name) {
|
||||
final List<PluginInfo> li = new ArrayList<PluginInfo>();
|
||||
for (final Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
public List<PluginInfo> getPluginInfo(String name) {
|
||||
List<PluginInfo> li = new ArrayList<>();
|
||||
for (Entry<String, PluginInfo> plugin : repocache.getPlugins().entrySet()) {
|
||||
if (plugin.getValue().name.equalsIgnoreCase(name)) {
|
||||
li.add(plugin.getValue());
|
||||
}
|
||||
|
@ -124,7 +110,7 @@ public class RepositoryManager {
|
|||
return li;
|
||||
}
|
||||
|
||||
public PluginInfo getPluginInfo(final String groupId, final String artifactId) {
|
||||
public PluginInfo getPluginInfo(String groupId, String artifactId) {
|
||||
return repocache.getPlugins().get(groupId + "." + artifactId);
|
||||
}
|
||||
|
||||
|
@ -136,7 +122,7 @@ public class RepositoryManager {
|
|||
return repocache;
|
||||
}
|
||||
|
||||
public Repositories getRepoCache(final String urlstring) {
|
||||
public Repositories getRepoCache(String urlstring) {
|
||||
return repocache.getRepos().get(handerRepoUrl(urlstring));
|
||||
}
|
||||
|
||||
|
@ -144,36 +130,25 @@ public class RepositoryManager {
|
|||
return repocache.getRepos();
|
||||
}
|
||||
|
||||
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);
|
||||
public boolean getRepositories(CommandSender sender, String urlstring) {
|
||||
int urllength = urlstring.length();
|
||||
String url = urlstring.substring(0, urlstring.endsWith("/") ? urllength - 1 : urllength);
|
||||
handerRepoUrl(url);
|
||||
final Repositories repo = repocache.addRepo(urlstring);
|
||||
if (repo == null) {
|
||||
return false;
|
||||
}
|
||||
return updateRepositories(sender, repo);
|
||||
Repositories repo = repocache.addRepo(urlstring);
|
||||
return repo != null && updateRepositories(sender, repo);
|
||||
}
|
||||
|
||||
public PackageInfo jsonToPackage(final String json) {
|
||||
try {
|
||||
return JsonHandle.fromJson(json, PackageInfo.class);
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
public PackageInfo jsonToPackage(String json) {
|
||||
return new PackageInfo((JSONObject) JSONValue.parse(json));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
pi.type = plugin.type != null ? plugin.type : pkg.type;
|
||||
pi.type = pi.type != null ? pi.type : URLType.Maven;
|
||||
pi.plugin = plugin;
|
||||
|
@ -183,15 +158,19 @@ public class RepositoryManager {
|
|||
sender.sendMessage("§6仓库: §e" + pkg.name + " §a更新成功!");
|
||||
}
|
||||
|
||||
public boolean updateRepositories(final CommandSender sender) {
|
||||
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) {
|
||||
repocache.getPlugins().clear();
|
||||
if (repocache.getRepos().isEmpty()) {
|
||||
repocache.addRepo("http://data.yumc.pw/yumcenter/repo.info");
|
||||
}
|
||||
final Iterator<Entry<String, Repositories>> keys = repocache.getRepos().entrySet().iterator();
|
||||
Iterator<Entry<String, Repositories>> keys = repocache.getRepos().entrySet().iterator();
|
||||
while (keys.hasNext()) {
|
||||
final Entry<String, Repositories> string = keys.next();
|
||||
final Repositories repo = repocache.getRepo(string.getKey());
|
||||
Entry<String, Repositories> string = keys.next();
|
||||
Repositories repo = repocache.getRepo(string.getKey());
|
||||
if (updateRepositories(sender, repo)) {
|
||||
sender.sendMessage("§6源: §e" + repo.name + " §a更新成功!");
|
||||
} else {
|
||||
|
@ -202,22 +181,22 @@ public class RepositoryManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean updateRepositories(CommandSender sender, final Repositories repocenter) {
|
||||
public boolean updateRepositories(CommandSender sender, Repositories repocenter) {
|
||||
if (sender == null) {
|
||||
sender = Bukkit.getConsoleSender();
|
||||
}
|
||||
if (repocenter == null || repocenter.repos.isEmpty()) {
|
||||
logger.debug("源地址为Null或源列表为空!");
|
||||
sender.sendMessage(String.format("§6[§bYum§6] 源 %s 数据为空或列表为空!", repocenter == null ? "null" : repocenter.name));
|
||||
return false;
|
||||
}
|
||||
for (final Repository repo : repocenter.repos) {
|
||||
for (Repository repo : repocenter.repos) {
|
||||
addPackage(sender, repo.url);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String handerRepoUrl(String url) {
|
||||
final int urllength = url.length();
|
||||
int urllength = url.length();
|
||||
url = url.substring(0, url.endsWith("/") ? urllength - 1 : urllength);
|
||||
if (!url.startsWith("http://")) {
|
||||
url = "http://" + url;
|
||||
|
|
|
@ -1,9 +1,76 @@
|
|||
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 String name;
|
||||
public List<PluginInfo> pil;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,16 @@ 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;
|
||||
|
@ -18,8 +19,8 @@ public class PluginInfo implements Serializable {
|
|||
static {
|
||||
try {
|
||||
NMSVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
} catch (final Exception e) {
|
||||
PKit.i().getLogger().warning("服务器NMS解析失败: " + Bukkit.getServer().getClass().getPackage().getName());
|
||||
} catch (Exception e) {
|
||||
Log.w("服务器NMS解析失败: " + Bukkit.getServer().getClass().getPackage().getName());
|
||||
NMSVersion = "NONMS";
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +36,6 @@ public class PluginInfo implements Serializable {
|
|||
/**
|
||||
* 获得下载直链
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
* @param version
|
||||
* 版本
|
||||
* @return 下载直链
|
||||
*/
|
||||
public String getDirectUrl() {
|
||||
|
@ -48,13 +45,11 @@ public class PluginInfo implements Serializable {
|
|||
/**
|
||||
* 获得下载直链
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
* @param version
|
||||
* 版本
|
||||
* @return 下载直链
|
||||
*/
|
||||
public String getDirectUrl(final String version) {
|
||||
public String getDirectUrl(String version) {
|
||||
return url.replace("[version]", version);
|
||||
}
|
||||
|
||||
|
@ -74,42 +69,41 @@ public class PluginInfo implements Serializable {
|
|||
* 插件版本
|
||||
* @return 文件名称
|
||||
*/
|
||||
public String getFileName(final String version) {
|
||||
public String getFileName(String version) {
|
||||
return String.format("%1$s-%2$s.jar", plugin.artifactId, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Maven仓库指定插件的下载地址
|
||||
*
|
||||
* @param sender
|
||||
* - 命令发送者
|
||||
* @param version
|
||||
* @param ver
|
||||
* - 需要更新的版本
|
||||
* @return 更新地址
|
||||
*/
|
||||
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 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 getUrl(final CommandSender sender, final String version) {
|
||||
public String getUrl(CommandSender sender, String version) {
|
||||
String ver = version;
|
||||
if (ver == null) {
|
||||
if (plugin.tags != null) {
|
||||
PluginHelperLogger.getLogger().debug("发现存在TAG标签 开始检索: " + NMSVersion);
|
||||
for (final TagInfo tagInfo : plugin.tags) {
|
||||
Log.d("发现存在TAG标签 开始检索: " + NMSVersion);
|
||||
for (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 = IOUtil.getXMLTag(pom, "version", null);
|
||||
ver = getXMLTag(pom, "version", null);
|
||||
if (ver != null) {
|
||||
sender.sendMessage("§6版本: §a成功获取到最新版本 §e" + ver + " §a...");
|
||||
}
|
||||
|
@ -128,4 +122,26 @@ 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;
|
||||
}
|
||||
}
|
|
@ -7,40 +7,32 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import cn.citycraft.PluginHelper.PluginHelperLogger;
|
||||
import cn.citycraft.PluginHelper.jsonresult.JsonHandle;
|
||||
import cn.citycraft.PluginHelper.utils.IOUtil;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import pw.yumc.Yum.models.RepoSerialization.Repositories;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.kit.HttpKit;
|
||||
|
||||
public class RepoCache implements Serializable {
|
||||
PluginHelperLogger logger = PluginHelperLogger.getLogger();
|
||||
Map<String, PluginInfo> plugins = new HashMap<String, PluginInfo>();
|
||||
Map<String, Repositories> repos = new HashMap<String, Repositories>();
|
||||
Map<String, PluginInfo> plugins = new HashMap<>();
|
||||
Map<String, Repositories> repos = new HashMap<>();
|
||||
|
||||
public static RepoCache fromJson(final String json) {
|
||||
return JsonHandle.fromJson(json, RepoCache.class);
|
||||
}
|
||||
|
||||
public void addPlugins(final String name, final PluginInfo info) {
|
||||
public void addPlugins(String name, PluginInfo info) {
|
||||
plugins.put(name, info);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
public Repositories addRepo(String repo) {
|
||||
if (repos.containsKey(repo) || repo.isEmpty()) { return null; }
|
||||
Repositories reposes = getRepo(repo);
|
||||
if (reposes == null) { return null; }
|
||||
repos.put(repo, reposes);
|
||||
return reposes;
|
||||
}
|
||||
|
||||
public List<String> getAllRepoInfo() {
|
||||
final List<String> repoinfo = new ArrayList<String>();
|
||||
for (final Entry<String, Repositories> repo : repos.entrySet()) {
|
||||
List<String> repoinfo = new ArrayList<>();
|
||||
for (Entry<String, Repositories> repo : repos.entrySet()) {
|
||||
repoinfo.add(String.format("§d仓库: §e%s §6- §3%s", repo.getValue().name, repo.getKey()));
|
||||
}
|
||||
return repoinfo;
|
||||
|
@ -50,34 +42,29 @@ public class RepoCache implements Serializable {
|
|||
return plugins;
|
||||
}
|
||||
|
||||
public Repositories getRepo(final String repo) {
|
||||
final String json = IOUtil.getData(repo);
|
||||
if (json == null || json.isEmpty()) {
|
||||
logger.debug("源地址获取数据为空 " + repo);
|
||||
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());
|
||||
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(final String repo) {
|
||||
if (repo.isEmpty() || !repos.containsKey(repo)) {
|
||||
return false;
|
||||
}
|
||||
public boolean removeRepo(String repo) {
|
||||
if (repo.isEmpty() || !repos.containsKey(repo)) { return false; }
|
||||
repos.remove(repo);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonHandle.toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,14 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* 源仓库序列化类
|
||||
*
|
||||
|
@ -14,15 +19,39 @@ import java.util.List;
|
|||
* @since 2015年8月31日下午7:41:53
|
||||
*/
|
||||
public class RepoSerialization {
|
||||
public class PackageInfo implements Serializable {
|
||||
@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 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 class Plugin implements Serializable {
|
||||
public static class Plugin implements Serializable {
|
||||
public String artifactId;
|
||||
public String branch;
|
||||
public String description;
|
||||
|
@ -33,28 +62,75 @@ 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 class Repositories implements Serializable {
|
||||
public static 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 class Repository implements Serializable {
|
||||
public static 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 class TagInfo implements Serializable {
|
||||
public static 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,
|
||||
DirectUrl;
|
||||
maven,
|
||||
DirectUrl
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
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 cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import cn.citycraft.PluginHelper.kit.ServerKit;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 线程安全检查任务
|
||||
|
@ -15,16 +20,26 @@ import cn.citycraft.PluginHelper.kit.ServerKit;
|
|||
* @author 喵♂呜
|
||||
*/
|
||||
public class MainThreadCheckTask extends TimerTask {
|
||||
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;
|
||||
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;
|
||||
|
||||
public MainThreadCheckTask(final Thread mainThread) {
|
||||
static {
|
||||
try {
|
||||
Class clazz = Class.forName("org.spigotmc.WatchdogThread");
|
||||
tickMethod = clazz.getDeclaredMethod("tick");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public MainThreadCheckTask(Thread mainThread) {
|
||||
this.mainThread = mainThread;
|
||||
}
|
||||
|
||||
|
@ -33,54 +48,70 @@ 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
|
||||
final StackTraceElement[] stackTrace = mainThread.getStackTrace();
|
||||
final StackTraceElement topElement = stackTrace[0];
|
||||
StackTraceElement[] stackTrace = mainThread.getStackTrace();
|
||||
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")) {
|
||||
final Plugin plugin = PluginKit.getOperatePlugin(stackTrace);
|
||||
if (plugin != null) {
|
||||
PluginKit.sc(String.format(prefix + warnPNet, plugin.getName()));
|
||||
} else {
|
||||
PluginKit.sc(prefix + warnNet);
|
||||
}
|
||||
tick();
|
||||
Plugin plugin = PKit.getOperatePlugin(stackTrace);
|
||||
tip = plugin != null ? String.format(warnPNet, plugin.getName()) : warnNet;
|
||||
}
|
||||
// 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")) {
|
||||
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;
|
||||
Plugin plugin = PKit.getOperatePlugin(stackTrace);
|
||||
tip = plugin != null ? String.format(warnPIO, plugin.getName()) : warnIO;
|
||||
}
|
||||
}
|
||||
if (tip != null) {
|
||||
tick(tip, stackTrace);
|
||||
} else {
|
||||
stopTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isElementEqual(final StackTraceElement traceElement, final String className, final String methodName) {
|
||||
private boolean isElementEqual(StackTraceElement traceElement, String className, String methodName) {
|
||||
return traceElement.getClassName().equals(className) && traceElement.getMethodName().equals(methodName);
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
stopTime += 5;
|
||||
if (stopTime >= 45) {
|
||||
PluginKit.sc(String.format(prefix + deliver, stopTime));
|
||||
ServerKit.tick();
|
||||
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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
############################
|
||||
|
||||
#配置版本号 请勿修改!!!
|
||||
Version: 2.2
|
||||
Version: 2.4
|
||||
|
||||
#是否只允许控制台执行插件仓库命令
|
||||
onlyCommandConsole: false
|
||||
onlyCommandConsole: ''
|
||||
#是否只允许控制台执行插件网络管理命令
|
||||
onlyNetCommandConsole: false
|
||||
onlyNetCommandConsole: ''
|
||||
#是否只允许控制台执行插件文件管理命令
|
||||
onlyFileCommandConsole: true
|
||||
onlyFileCommandConsole: ''
|
||||
#禁止rm -rf的文件夹列表
|
||||
blacklist:
|
||||
- 'plugins'
|
||||
|
@ -22,3 +22,4 @@ ignorelist:
|
|||
- 'iConomy'
|
||||
- 'GroupManager'
|
||||
- 'PermissionsEx'
|
||||
- 'Essentials'
|
|
@ -1,12 +1,19 @@
|
|||
############################
|
||||
### 能耗监控系统配置文件
|
||||
############################
|
||||
|
||||
#配置版本号 请勿修改!!!
|
||||
Version: 1.1
|
||||
|
||||
#是否开启
|
||||
Enable: true
|
||||
#忽略检测列表
|
||||
Ignore:
|
||||
- Essentials
|
||||
############################
|
||||
### 能耗监控系统配置文件
|
||||
############################
|
||||
|
||||
#配置版本号 请勿修改!!!
|
||||
Version: 1.4
|
||||
|
||||
#是否开启
|
||||
Enable: true
|
||||
#是否显示开发人员信息
|
||||
Debug: false
|
||||
#是否保存Lag日志到文件
|
||||
LogToFile: true
|
||||
#忽略检测列表
|
||||
Ignore:
|
||||
- PluginHelper
|
||||
#忽略报错的插件列表
|
||||
IgnoreError:
|
||||
- PluginHelper
|
||||
|
|
|
@ -13,6 +13,9 @@ ShowInfo: true
|
|||
NetworkDebug: false
|
||||
#是否允许插件主线程访问网络
|
||||
AllowPrimaryThread: false
|
||||
#调试列表
|
||||
Debug:
|
||||
- AAC
|
||||
#黑名单列表
|
||||
Black:
|
||||
- BukkitInjectedTools
|
||||
|
@ -25,4 +28,6 @@ WhiteURL:
|
|||
- mcstats.org
|
||||
- report.mcstats.org
|
||||
- www.spigotmc.org
|
||||
- dev.bukkit.org
|
||||
- dev.bukkit.org
|
||||
- api.curseforge.com
|
||||
- bStats.org
|
|
@ -9,31 +9,31 @@ commands:
|
|||
yum:
|
||||
description: MC插件仓库
|
||||
aliases: [y,apt-get]
|
||||
usage: §6使用§a/yum help§6查看帮助!
|
||||
usage: §6使用 §a/yum help §6查看帮助!
|
||||
permission: yum.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
net:
|
||||
description: MC插件网络管理
|
||||
aliases: [n]
|
||||
usage: §6使用§a/net help§6查看帮助!
|
||||
usage: §6使用 §a/net help §6查看帮助!
|
||||
permission: net.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
file:
|
||||
description: MC文件管理命令
|
||||
aliases: [f]
|
||||
usage: §6使用§a/file help§6查看帮助!
|
||||
usage: §6使用 §a/file help §6查看帮助!
|
||||
permission: file.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
security:
|
||||
description: MC安全管理命令
|
||||
aliases: [s]
|
||||
usage: §6使用§a/security help§6查看帮助!
|
||||
usage: §6使用 §a/security help §6查看帮助!
|
||||
permission: security.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
monitor:
|
||||
description: MC系统监控命令
|
||||
aliases: [mi]
|
||||
usage: §6使用§a/monitor help§6查看帮助!
|
||||
usage: §6使用 §a/monitor help §6查看帮助!
|
||||
permission: monitor.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
permissions:
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
############################
|
||||
|
||||
#配置版本号 请勿修改!!!
|
||||
Version: 1.0
|
||||
Version: 1.1
|
||||
|
||||
#是否开启线程安全检测
|
||||
ThreadSafe: true
|
||||
#是否开启主线程IO检测
|
||||
MainThreadCheck: true
|
||||
MainThreadCheck: true
|
||||
#是否开启调试模式
|
||||
Debug: true
|
Loading…
Reference in New Issue