feat: 完善类载入流程 限制Yum重载

Signed-off-by: 502647092 <admin@yumc.pw>
dev
502647092 2016-07-28 15:59:08 +08:00
parent 2b3313579c
commit 8226293c3e
8 changed files with 96 additions and 40 deletions

View File

@ -18,6 +18,7 @@ import pw.yumc.Yum.commands.FileCommand;
import pw.yumc.Yum.commands.MonitorCommand;
import pw.yumc.Yum.commands.NetCommand;
import pw.yumc.Yum.commands.YumCommand;
import pw.yumc.Yum.inject.YumPluginLoader;
import pw.yumc.Yum.listeners.PluginListener;
import pw.yumc.Yum.listeners.PluginNetworkListener;
import pw.yumc.Yum.listeners.SecurityListener;
@ -37,6 +38,8 @@ public class Yum extends JavaPlugin {
public static Thread mainThread = null;
public static Timer task = new Timer();
public static TimerTask tt;
private static boolean isLoad = false;
private static boolean isEnable = false;
@Override
public FileConfiguration getConfig() {
@ -50,27 +53,34 @@ public class Yum extends JavaPlugin {
@Override
public void onEnable() {
if (Bukkit.isPrimaryThread()) {
mainThread = Thread.currentThread();
if (!isEnable) {
if (Bukkit.isPrimaryThread()) {
mainThread = Thread.currentThread();
}
new YumAPI();
initCommands();
initListeners();
initRunnable();
MonitorManager.init();
new VersionChecker(this);
YumAPI.updateRepo(Bukkit.getConsoleSender());
YumAPI.updateCheck(Bukkit.getConsoleSender());
}
new YumAPI();
initCommands();
initListeners();
initRunnable();
new VersionChecker(this);
YumAPI.updateRepo(Bukkit.getConsoleSender());
YumAPI.updateCheck(Bukkit.getConsoleSender());
MonitorManager.init();
}
@Override
public void onLoad() {
// 初始化配置
ConfigManager.i();
// 初始化更新列
UpdatePlugin.getUpdateList();
// 启用网络注入
NetworkManager.register(this);
if (!isLoad) {
// 初始化配置
ConfigManager.i();
// 注入插件加载器
YumPluginLoader.inject();
// 初始化更新列
UpdatePlugin.getUpdateList();
// 启用网络注入
NetworkManager.register(this);
isLoad = true;
}
}
/**

View File

@ -127,7 +127,7 @@ public class YumAPI {
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 plugman.load(sender, pluginFile, false);
}
return false;
}

View File

@ -50,7 +50,6 @@ public class MonitorCommand implements CommandExecutor {
private final String mieprefix = " §6事件名称 §a总耗时 §b执行次数 §d平均耗时";
private final String mitprefix = " §6任务名称 §a总耗时 §b执行次数 §d平均耗时";
private final String milist = "§6- §e%-20s §a%-9.2f §b%-9s §d%-9.5f";
private final String mialist = "§6- §e%-20s §a%-9.2f §b%-9s";
private final String miwlist = "§6- §c%-20s §a%-9.2f §b%-9s §c%-9.5f";
private final String reinject = prefix + "§a能耗监控器重载完毕!";
@ -104,7 +103,7 @@ public class MonitorCommand implements CommandExecutor {
final 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(mialist, command.getValue().getName(), injected.totalTime / um, injected.count));
sender.sendMessage(String.format(milist, command.getValue().getName(), injected.totalTime / um, injected.count, 0D));
}
}
}
@ -246,7 +245,7 @@ public class MonitorCommand implements CommandExecutor {
final 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(mialist, getClassName(executor.getOriginalTask().getClass()), executor.totalTime / um, executor.count));
sender.sendMessage(String.format(milist, getClassName(executor.getOriginalTask().getClass()), executor.totalTime / um, executor.count, 0D));
}
}
}

View File

@ -207,7 +207,7 @@ public class YumCommand implements Listener, CommandExecutor {
if (plugin != null) {
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) {
sender.sendMessage(String.format(version, pluginname, version));
sender.sendMessage(String.format(del, pluginname, version));
} else {
sender.sendMessage(String.format(delFailed, pluginname));
}

View File

@ -26,9 +26,13 @@ import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.UnknownDependencyException;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
public class YumPluginLoader implements PluginLoader {
private static boolean isInit = false;
private static final String needRestart = "§6[§bYum§6] §c由于修改了服务器内部文件 §bYum §c无法直接重载 §4请重启服务器!";
private static final YumPluginLoader yumPluginLoader = new YumPluginLoader(Bukkit.getServer());
private final JavaPluginLoader internal_loader;
private final Server server;
@ -38,8 +42,27 @@ public class YumPluginLoader implements PluginLoader {
internal_loader = new JavaPluginLoader(instance);
}
public static void replaceJavaPluginLoaders() {
final YumPluginLoader yumPluginLoader = new YumPluginLoader(Bukkit.getServer());
public static void inject() {
injectExistingPlugins(yumPluginLoader);
replaceJavaPluginLoaders(yumPluginLoader);
}
private static void injectExistingPlugins(final YumPluginLoader yumPluginLoader) {
for (final org.bukkit.plugin.Plugin p : Bukkit.getPluginManager().getPlugins()) {
if (p instanceof JavaPlugin) {
final JavaPlugin jp = (JavaPlugin) p;
try {
final Field f = JavaPlugin.class.getDeclaredField("loader");
f.setAccessible(true);
f.set(jp, yumPluginLoader);
} catch (final Exception e) {
Bukkit.getServer().getLogger().log(Level.SEVERE, "Yum failed injecting " + jp.getDescription().getFullName() + " with the new PluginLoader, contact the developers on YUMC!", e);
}
}
}
}
private static void replaceJavaPluginLoaders(final YumPluginLoader yumPluginLoader) {
final PluginManager spm = Bukkit.getPluginManager();
try {
final Field field = spm.getClass().getDeclaredField("fileAssociations");
@ -69,14 +92,25 @@ public class YumPluginLoader implements PluginLoader {
@Override
public void disablePlugin(final Plugin plugin) {
if (!plugin.getName().equalsIgnoreCase("Yum")) {
if (plugin.getName().equalsIgnoreCase("Yum")) {
Bukkit.getConsoleSender().sendMessage(needRestart);
} else {
internal_loader.disablePlugin(plugin);
}
}
@Override
public void enablePlugin(final Plugin arg0) {
internal_loader.enablePlugin(arg0);
public void enablePlugin(final Plugin plugin) {
if (plugin.getName().equalsIgnoreCase("Yum")) {
if (isInit) {
Bukkit.getConsoleSender().sendMessage(needRestart);
} else {
internal_loader.enablePlugin(plugin);
isInit = true;
}
} else {
internal_loader.enablePlugin(plugin);
}
}
@Override
@ -90,8 +124,16 @@ public class YumPluginLoader implements PluginLoader {
}
@Override
public Plugin loadPlugin(final File arg0) throws InvalidPluginException, UnknownDependencyException {
return internal_loader.loadPlugin(arg0);
public Plugin loadPlugin(final File file) throws InvalidPluginException, UnknownDependencyException {
try {
final PluginDescriptionFile description = getPluginDescription(file);
if (description.getName().equalsIgnoreCase("Yum")) {
Bukkit.getConsoleSender().sendMessage(needRestart);
return null;
}
} catch (final InvalidDescriptionException ex) {
}
return internal_loader.loadPlugin(file);
}
}

View File

@ -8,7 +8,9 @@ public class DataManager {
private static DataBase db = ConfigManager.i().getDataBase();
public static void init() {
db.createTables(TableName.cmd, new KeyValue("name", Type.VARCHAR.get()), null);
db.createTables(TableName.cmd, new KeyValue("plugin", Type.VARCHAR.get()).add("name", Type.VARCHAR.get()).add("total", Type.DOUBLE.get()).add("count", Type.INTEGER.get()), null);
db.createTables(TableName.event, new KeyValue("plugin", Type.VARCHAR.get()).add("name", Type.VARCHAR.get()).add("total", Type.DOUBLE.get()).add("count", Type.INTEGER.get()), null);
db.createTables(TableName.task, new KeyValue("plugin", Type.VARCHAR.get()).add("name", Type.VARCHAR.get()).add("total", Type.DOUBLE.get()).add("count", Type.INTEGER.get()), null);
}
static class TableName {

View File

@ -16,7 +16,6 @@ import org.bukkit.plugin.Plugin;
import cn.citycraft.PluginHelper.kit.LogKit;
import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.sql.DataBase;
/**
*
@ -42,17 +41,11 @@ public class MonitorManager {
private final static Map<String, Long> event = new ConcurrentHashMap<>();
private final static Map<String, Long> cmd = new ConcurrentHashMap<>();
private static DataBase db;
private final static double um = 1000000.00;
private final static LogKit mlog = new LogKit("monitor.log");
private final static LogKit elog = new LogKit("error.log");
public MonitorManager() {
db = ConfigManager.i().getDataBase();
}
public static void addCmd(final String pname, final long time) {
add(pname, time, monitor, cmd);
}

View File

@ -37,6 +37,7 @@ import com.google.common.base.Joiner;
import cn.citycraft.PluginHelper.utils.FileUtil;
import cn.citycraft.PluginHelper.utils.StringUtil;
import pw.yumc.Yum.inject.YumPluginLoader;
/**
*
@ -320,9 +321,12 @@ public class PluginsManager {
* -
* @return
*/
public boolean load(final CommandSender sender, final File pluginFile) {
public boolean load(final CommandSender sender, final File pluginFile, final boolean clean) {
Plugin target = null;
final String name = pluginFile.getName();
if (clean) {
YumPluginLoader.inject();
}
try {
target = Bukkit.getPluginManager().loadPlugin(pluginFile);
} catch (final InvalidDescriptionException e) {
@ -334,6 +338,9 @@ public class PluginsManager {
sender.sendMessage("§c服务器或JAVA的版本低于插件: " + name + " 所需要的版本!!");
return false;
} catch (final InvalidPluginException e) {
if (!clean) {
return load(sender, pluginFile, true);
}
sender.sendMessage("§4异常: §c" + e.getMessage());
sender.sendMessage("§4文件: §c" + name + " 不是一个可载入的插件!");
sender.sendMessage("§4注意: §cMOD服重载插件3次以上需重启服务器");
@ -344,7 +351,7 @@ public class PluginsManager {
return false;
}
if (target == null) {
sender.sendMessage("§4异常: §c服务器类加载器载入插件失败!");
sender.sendMessage("§4异常: §c服务器类加载器载入插件失败 请查看后台信息!");
return false;
}
target.onLoad();
@ -398,7 +405,7 @@ public class PluginsManager {
return false;
}
}
return load(sender, pluginFile);
return load(sender, pluginFile, false);
}
/**
@ -409,7 +416,7 @@ public class PluginsManager {
* @return
*/
public boolean load(final File pluginFile) {
return load(Bukkit.getConsoleSender(), pluginFile);
return load(Bukkit.getConsoleSender(), pluginFile, false);
}
/**
@ -534,6 +541,9 @@ public class PluginsManager {
sender = Bukkit.getConsoleSender();
}
final PluginManager pluginManager = Bukkit.getPluginManager();
if ("Yum".equalsIgnoreCase(name)) {
return true;
}
SimpleCommandMap commandMap = null;
List<Plugin> plugins = null;
Map<String, Plugin> lookupNames = null;