配置文件及文件监听变化
This commit is contained in:
parent
4bb5df7cbb
commit
d8f8ffc5a3
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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<String, Object> serialize(Plugin plugin, Class<?> clazz) {
|
||||
public static Map<String, Object> 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<? extends ConfigurationSerializable>) o.getClass()));
|
||||
map.putAll(((ConfigurationSerializable) o).serialize());
|
||||
return map;
|
||||
} else if (o instanceof Property) {
|
||||
|
59
src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java
Normal file
59
src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java
Normal file
@ -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<WatchService, Triple<File, Object, Consumer<Object>>> 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<Object> 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -275,6 +275,8 @@ public class Main extends JavaPlugin implements Listener {
|
||||
connection.closeConnection();
|
||||
}
|
||||
|
||||
TLib.unload();
|
||||
|
||||
// 关闭服务器
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user