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

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
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.MonitorCommand;
import pw.yumc.Yum.commands.NetCommand; import pw.yumc.Yum.commands.NetCommand;
import pw.yumc.Yum.commands.YumCommand; import pw.yumc.Yum.commands.YumCommand;
import pw.yumc.Yum.inject.YumPluginLoader;
import pw.yumc.Yum.listeners.PluginListener; import pw.yumc.Yum.listeners.PluginListener;
import pw.yumc.Yum.listeners.PluginNetworkListener; import pw.yumc.Yum.listeners.PluginNetworkListener;
import pw.yumc.Yum.listeners.SecurityListener; import pw.yumc.Yum.listeners.SecurityListener;
@ -37,6 +38,8 @@ public class Yum extends JavaPlugin {
public static Thread mainThread = null; public static Thread mainThread = null;
public static Timer task = new Timer(); public static Timer task = new Timer();
public static TimerTask tt; public static TimerTask tt;
private static boolean isLoad = false;
private static boolean isEnable = false;
@Override @Override
public FileConfiguration getConfig() { public FileConfiguration getConfig() {
@ -50,6 +53,7 @@ public class Yum extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
if (!isEnable) {
if (Bukkit.isPrimaryThread()) { if (Bukkit.isPrimaryThread()) {
mainThread = Thread.currentThread(); mainThread = Thread.currentThread();
} }
@ -57,20 +61,26 @@ public class Yum extends JavaPlugin {
initCommands(); initCommands();
initListeners(); initListeners();
initRunnable(); initRunnable();
MonitorManager.init();
new VersionChecker(this); new VersionChecker(this);
YumAPI.updateRepo(Bukkit.getConsoleSender()); YumAPI.updateRepo(Bukkit.getConsoleSender());
YumAPI.updateCheck(Bukkit.getConsoleSender()); YumAPI.updateCheck(Bukkit.getConsoleSender());
MonitorManager.init(); }
} }
@Override @Override
public void onLoad() { public void onLoad() {
if (!isLoad) {
// 初始化配置 // 初始化配置
ConfigManager.i(); ConfigManager.i();
// 注入插件加载器
YumPluginLoader.inject();
// 初始化更新列 // 初始化更新列
UpdatePlugin.getUpdateList(); UpdatePlugin.getUpdateList();
// 启用网络注入 // 启用网络注入
NetworkManager.register(this); 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) { public static boolean install(final CommandSender sender, final String pluginname, final String url) {
final File pluginFile = new File(Bukkit.getUpdateFolderFile().getParentFile(), pluginname + ".jar"); final File pluginFile = new File(Bukkit.getUpdateFolderFile().getParentFile(), pluginname + ".jar");
if (download.run(sender, url, pluginFile)) { if (download.run(sender, url, pluginFile)) {
return plugman.load(sender, pluginFile); return plugman.load(sender, pluginFile, false);
} }
return 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 mieprefix = " §6事件名称 §a总耗时 §b执行次数 §d平均耗时";
private final String mitprefix = " §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 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 miwlist = "§6- §c%-20s §a%-9.2f §b%-9s §c%-9.5f";
private final String reinject = prefix + "§a能耗监控器重载完毕!"; private final String reinject = prefix + "§a能耗监控器重载完毕!";
@ -104,7 +103,7 @@ public class MonitorCommand implements CommandExecutor {
final double avgTime = injected.totalTime / um / injected.count; 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)); sender.sendMessage(String.format(avgTime < 10 ? milist : miwlist, command.getValue().getName(), injected.totalTime / um, injected.count, avgTime));
} else { } 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; 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)); sender.sendMessage(String.format(avgTime < 10 ? milist : miwlist, getClassName(executor.getOriginalTask().getClass()), executor.totalTime / um, executor.count, avgTime));
} else { } 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) { if (plugin != null) {
final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15); final String version = StringUtils.substring(plugin.getDescription().getVersion(), 0, 15);
if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) { if (YumAPI.getPlugman().fullDeletePlugin(sender, plugin)) {
sender.sendMessage(String.format(version, pluginname, version)); sender.sendMessage(String.format(del, pluginname, version));
} else { } else {
sender.sendMessage(String.format(delFailed, pluginname)); 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.PluginManager;
import org.bukkit.plugin.RegisteredListener; import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.UnknownDependencyException; import org.bukkit.plugin.UnknownDependencyException;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
public class YumPluginLoader implements PluginLoader { 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 JavaPluginLoader internal_loader;
private final Server server; private final Server server;
@ -38,8 +42,27 @@ public class YumPluginLoader implements PluginLoader {
internal_loader = new JavaPluginLoader(instance); internal_loader = new JavaPluginLoader(instance);
} }
public static void replaceJavaPluginLoaders() { public static void inject() {
final YumPluginLoader yumPluginLoader = new YumPluginLoader(Bukkit.getServer()); 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(); final PluginManager spm = Bukkit.getPluginManager();
try { try {
final Field field = spm.getClass().getDeclaredField("fileAssociations"); final Field field = spm.getClass().getDeclaredField("fileAssociations");
@ -69,14 +92,25 @@ public class YumPluginLoader implements PluginLoader {
@Override @Override
public void disablePlugin(final Plugin plugin) { 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); internal_loader.disablePlugin(plugin);
} }
} }
@Override @Override
public void enablePlugin(final Plugin arg0) { public void enablePlugin(final Plugin plugin) {
internal_loader.enablePlugin(arg0); if (plugin.getName().equalsIgnoreCase("Yum")) {
if (isInit) {
Bukkit.getConsoleSender().sendMessage(needRestart);
} else {
internal_loader.enablePlugin(plugin);
isInit = true;
}
} else {
internal_loader.enablePlugin(plugin);
}
} }
@Override @Override
@ -90,8 +124,16 @@ public class YumPluginLoader implements PluginLoader {
} }
@Override @Override
public Plugin loadPlugin(final File arg0) throws InvalidPluginException, UnknownDependencyException { public Plugin loadPlugin(final File file) throws InvalidPluginException, UnknownDependencyException {
return internal_loader.loadPlugin(arg0); 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(); private static DataBase db = ConfigManager.i().getDataBase();
public static void init() { 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 { 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.LogKit;
import cn.citycraft.PluginHelper.kit.PluginKit; 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> event = new ConcurrentHashMap<>();
private final static Map<String, Long> cmd = 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 double um = 1000000.00;
private final static LogKit mlog = new LogKit("monitor.log"); private final static LogKit mlog = new LogKit("monitor.log");
private final static LogKit elog = new LogKit("error.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) { public static void addCmd(final String pname, final long time) {
add(pname, time, monitor, cmd); 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.FileUtil;
import cn.citycraft.PluginHelper.utils.StringUtil; import cn.citycraft.PluginHelper.utils.StringUtil;
import pw.yumc.Yum.inject.YumPluginLoader;
/** /**
* 插件管理类 * 插件管理类
@ -320,9 +321,12 @@ public class PluginsManager {
* - 插件文件 * - 插件文件
* @return 是否成功 * @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; Plugin target = null;
final String name = pluginFile.getName(); final String name = pluginFile.getName();
if (clean) {
YumPluginLoader.inject();
}
try { try {
target = Bukkit.getPluginManager().loadPlugin(pluginFile); target = Bukkit.getPluginManager().loadPlugin(pluginFile);
} catch (final InvalidDescriptionException e) { } catch (final InvalidDescriptionException e) {
@ -334,6 +338,9 @@ public class PluginsManager {
sender.sendMessage("§c服务器或JAVA的版本低于插件: " + name + " 所需要的版本!!"); sender.sendMessage("§c服务器或JAVA的版本低于插件: " + name + " 所需要的版本!!");
return false; return false;
} catch (final InvalidPluginException e) { } catch (final InvalidPluginException e) {
if (!clean) {
return load(sender, pluginFile, true);
}
sender.sendMessage("§4异常: §c" + e.getMessage()); sender.sendMessage("§4异常: §c" + e.getMessage());
sender.sendMessage("§4文件: §c" + name + " 不是一个可载入的插件!"); sender.sendMessage("§4文件: §c" + name + " 不是一个可载入的插件!");
sender.sendMessage("§4注意: §cMOD服重载插件3次以上需重启服务器"); sender.sendMessage("§4注意: §cMOD服重载插件3次以上需重启服务器");
@ -344,7 +351,7 @@ public class PluginsManager {
return false; return false;
} }
if (target == null) { if (target == null) {
sender.sendMessage("§4异常: §c服务器类加载器载入插件失败!"); sender.sendMessage("§4异常: §c服务器类加载器载入插件失败 请查看后台信息!");
return false; return false;
} }
target.onLoad(); target.onLoad();
@ -398,7 +405,7 @@ public class PluginsManager {
return false; return false;
} }
} }
return load(sender, pluginFile); return load(sender, pluginFile, false);
} }
/** /**
@ -409,7 +416,7 @@ public class PluginsManager {
* @return 是否成功 * @return 是否成功
*/ */
public boolean load(final File pluginFile) { 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(); sender = Bukkit.getConsoleSender();
} }
final PluginManager pluginManager = Bukkit.getPluginManager(); final PluginManager pluginManager = Bukkit.getPluginManager();
if ("Yum".equalsIgnoreCase(name)) {
return true;
}
SimpleCommandMap commandMap = null; SimpleCommandMap commandMap = null;
List<Plugin> plugins = null; List<Plugin> plugins = null;
Map<String, Plugin> lookupNames = null; Map<String, Plugin> lookupNames = null;