From d8f8ffc5a3248ba9e7f26ee29cbe3c3ee83c248d Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Fri, 6 Apr 2018 15:09:36 +0800 Subject: [PATCH] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E5=8F=8A?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=9B=91=E5=90=AC=E5=8F=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 16 ++++- .../tlib/inject/DependencyInjector.java | 40 +++++++++++++ .../ilummc/tlib/inject/TConfigInjector.java | 30 ++++------ .../ilummc/tlib/inject/TConfigWatcher.java | 59 +++++++++++++++++++ .../ilummc/tlib/inject/TLibPluginManager.java | 8 ++- .../java/com/ilummc/tlib/util/TLogger.java | 14 ++--- src/main/java/me/skymc/taboolib/Main.java | 2 + 7 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index f9919a2..435af77 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; import com.ilummc.tlib.inject.DependencyInjector; +import com.ilummc.tlib.inject.TConfigWatcher; import com.ilummc.tlib.inject.TLibPluginManager; import com.ilummc.tlib.util.TLogger; import me.skymc.taboolib.Main; @@ -23,6 +24,8 @@ public class TLib { private TLibConfig config; + private TConfigWatcher configWatcher = new TConfigWatcher(); + private TLib() { } @@ -34,6 +37,10 @@ public class TLib { return tLogger; } + public TConfigWatcher getConfigWatcher() { + return configWatcher; + } + public static TLib getTLib() { return tLib; } @@ -55,8 +62,13 @@ public class TLib { } } - @Config(name = "tlib.yml") - public class TLibConfig { + public static void unload() { + tLib.getConfigWatcher().unregisterAll(); + DependencyInjector.eject(Main.getInst(), tLib); + } + + @Config(name = "tlib.yml", listenChanges = true) + public static class TLibConfig { private int downloadPoolSize = 4; diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index e09a874..e3e71e3 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -8,6 +8,8 @@ import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; public class DependencyInjector { @@ -24,7 +26,26 @@ public class DependencyInjector { } static void onDisable(Plugin plugin) { + ejectConfig(plugin, plugin); + } + public static void eject(Plugin plugin, Object o) { + ejectConfig(plugin, o); + } + + private static void ejectConfig(Plugin plugin, Object o) { + for (Field field : o.getClass().getDeclaredFields()) { + Config config; + if ((config = field.getType().getAnnotation(Config.class)) != null) { + try { + field.setAccessible(true); + TConfigInjector.saveConfig(plugin, o); + TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); + } catch (IOException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); + } + } + } } private static void injectConfig(Plugin plugin, Object o) { @@ -37,6 +58,25 @@ public class DependencyInjector { if (obj != null) { TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载"); field.set(o, obj); + if (config.listenChanges()) { + TLib.getTLib().getLogger().info("开始监听插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件"); + TLib.getTLib().getConfigWatcher().addOnListen( + new File(plugin.getDataFolder(), config.name()), + obj, + object -> { + try { + Object newObj = TConfigInjector.loadConfig(plugin, object.getClass()); + for (Field f : newObj.getClass().getDeclaredFields()) { + f.setAccessible(true); + f.set(obj, f.get(newObj)); + } + TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功重载"); + } catch (Exception ignored) { + TLib.getTLib().getLogger().warn("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件重载时发生错误"); + } + } + ); + } } } } catch (IllegalAccessException ignored) { diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 447484a..f599646 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -10,6 +10,7 @@ import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.bean.Property; import org.apache.commons.lang3.Validate; import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.Plugin; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -17,9 +18,7 @@ import org.yaml.snakeyaml.Yaml; import java.io.File; import java.io.IOException; import java.lang.reflect.Array; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.nio.charset.Charset; import java.util.*; import java.util.stream.Collectors; @@ -50,7 +49,7 @@ public class TConfigInjector { .create().fromJson(new Gson().toJson(new Yaml() .dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz); } catch (NullPointerException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在"); return null; } catch (Exception e) { try { @@ -62,28 +61,24 @@ public class TConfigInjector { } } - public static Map serialize(Plugin plugin, Class clazz) { + public static Map serialize(Plugin plugin, Object object) { try { - Constructor constructor = clazz.getConstructor(); - constructor.setAccessible(true); - Config config = clazz.getAnnotation(Config.class); + Config config = object.getClass().getAnnotation(Config.class); Validate.notNull(config); - return new Serializer(new LinkedHashMap<>(), constructor.newInstance(), config.excludeModifiers()).get(); - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有无参构造方法"); + return new Serializer(new LinkedHashMap<>(), object, config.excludeModifiers()).get(); } catch (NullPointerException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有 @Config 注解"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解"); } catch (Exception e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败"); } return null; } - public static void saveConfig(Plugin plugin, Class clazz) throws IOException, NullPointerException { - Object obj = serialize(plugin, clazz); - Validate.notNull(obj); - Config config = clazz.getAnnotation(Config.class); + public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException { + Config config = object.getClass().getAnnotation(Config.class); Validate.notNull(config); + Object obj = serialize(plugin, object); + Validate.notNull(obj); File target = new File(plugin.getDataFolder(), config.name()); if (!target.exists()) target.createNewFile(); DumperOptions options = new DumperOptions(); @@ -143,7 +138,8 @@ public class TConfigInjector { return map; } else if (o instanceof ConfigurationSerializable) { Map map = new LinkedHashMap(); - map.put("==", o.getClass().getName()); + map.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, + ConfigurationSerialization.getAlias((Class) o.getClass())); map.putAll(((ConfigurationSerializable) o).serialize()); return map; } else if (o instanceof Property) { diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java new file mode 100644 index 0000000..8327b96 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java @@ -0,0 +1,59 @@ +package com.ilummc.tlib.inject; + +import com.ilummc.tlib.TLib; +import org.apache.commons.lang3.tuple.Triple; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class TConfigWatcher { + + private ScheduledExecutorService service = Executors.newScheduledThreadPool(1); + + private Map>> map = new HashMap<>(); + + public TConfigWatcher() { + service.scheduleAtFixedRate(() -> { + map.forEach((service, triple) -> { + WatchKey key; + while ((key = service.poll()) != null) { + for (WatchEvent watchEvent : key.pollEvents()) { + if (triple.getLeft().getName().equals(Objects.toString(watchEvent.context()))) + triple.getRight().accept(triple.getMiddle()); + } + key.reset(); + } + }); + }, 1000, 100, TimeUnit.MILLISECONDS); + } + + public void addOnListen(File file, Object obj, Consumer consumer) { + try { + WatchService service = FileSystems.getDefault().newWatchService(); + file.getParentFile().toPath().register(service, StandardWatchEventKinds.ENTRY_MODIFY); + map.put(service, Triple.of(file, obj, consumer)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void unregisterAll() { + service.shutdown(); + map.forEach((service, pair) -> { + try { + service.close(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + +} diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java index f8a22f6..42f640d 100644 --- a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java @@ -1,5 +1,6 @@ package com.ilummc.tlib.inject; +import me.skymc.taboolib.Main; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; @@ -15,6 +16,8 @@ public class TLibPluginManager implements PluginManager { private final PluginManager instance; + private final Main main = (Main) Main.getInst(); + public TLibPluginManager() { instance = Bukkit.getPluginManager(); } @@ -56,7 +59,10 @@ public class TLibPluginManager implements PluginManager { @Override public void disablePlugins() { - instance.disablePlugins(); + for (Plugin plugin : getPlugins()) { + if (plugin != main) disablePlugin(plugin); + } + disablePlugin(main); } @Override diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java index 5d5aa42..e2f7bcb 100644 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -26,37 +26,37 @@ public class TLogger { } public void verbose(String msg) { - if (level >= VERBOSE) + if (level <= VERBOSE) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg)); } public void finest(String msg) { - if (level >= FINEST) + if (level <= FINEST) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg)); } public void fine(String msg) { - if (level >= FINE) + if (level <= FINE) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg)); } public void info(String msg) { - if (level >= INFO) + if (level <= INFO) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg)); } public void warn(String msg) { - if (level >= WARN) + if (level <= WARN) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg)); } public void error(String msg) { - if (level >= ERROR) + if (level <= ERROR) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg)); } public void fatal(String msg) { - if (level >= FATAL) + if (level <= FATAL) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg)); } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 2546d2c..f1733da 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -274,6 +274,8 @@ public class Main extends JavaPlugin implements Listener { if (connection != null && connection.isConnection()) { connection.closeConnection(); } + + TLib.unload(); // 关闭服务器 Bukkit.shutdown();