配置文件及文件监听变化
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.Dependency;
|
||||||
import com.ilummc.tlib.annotations.Logger;
|
import com.ilummc.tlib.annotations.Logger;
|
||||||
import com.ilummc.tlib.inject.DependencyInjector;
|
import com.ilummc.tlib.inject.DependencyInjector;
|
||||||
|
import com.ilummc.tlib.inject.TConfigWatcher;
|
||||||
import com.ilummc.tlib.inject.TLibPluginManager;
|
import com.ilummc.tlib.inject.TLibPluginManager;
|
||||||
import com.ilummc.tlib.util.TLogger;
|
import com.ilummc.tlib.util.TLogger;
|
||||||
import me.skymc.taboolib.Main;
|
import me.skymc.taboolib.Main;
|
||||||
@ -23,6 +24,8 @@ public class TLib {
|
|||||||
|
|
||||||
private TLibConfig config;
|
private TLibConfig config;
|
||||||
|
|
||||||
|
private TConfigWatcher configWatcher = new TConfigWatcher();
|
||||||
|
|
||||||
private TLib() {
|
private TLib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +37,10 @@ public class TLib {
|
|||||||
return tLogger;
|
return tLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TConfigWatcher getConfigWatcher() {
|
||||||
|
return configWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
public static TLib getTLib() {
|
public static TLib getTLib() {
|
||||||
return tLib;
|
return tLib;
|
||||||
}
|
}
|
||||||
@ -55,8 +62,13 @@ public class TLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Config(name = "tlib.yml")
|
public static void unload() {
|
||||||
public class TLibConfig {
|
tLib.getConfigWatcher().unregisterAll();
|
||||||
|
DependencyInjector.eject(Main.getInst(), tLib);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Config(name = "tlib.yml", listenChanges = true)
|
||||||
|
public static class TLibConfig {
|
||||||
|
|
||||||
private int downloadPoolSize = 4;
|
private int downloadPoolSize = 4;
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public class DependencyInjector {
|
public class DependencyInjector {
|
||||||
@ -24,7 +26,26 @@ public class DependencyInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void onDisable(Plugin plugin) {
|
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) {
|
private static void injectConfig(Plugin plugin, Object o) {
|
||||||
@ -37,6 +58,25 @@ public class DependencyInjector {
|
|||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载");
|
TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载");
|
||||||
field.set(o, obj);
|
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) {
|
} catch (IllegalAccessException ignored) {
|
||||||
|
@ -10,6 +10,7 @@ import com.ilummc.tlib.annotations.Config;
|
|||||||
import com.ilummc.tlib.bean.Property;
|
import com.ilummc.tlib.bean.Property;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
@ -17,9 +18,7 @@ import org.yaml.snakeyaml.Yaml;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -50,7 +49,7 @@ public class TConfigInjector {
|
|||||||
.create().fromJson(new Gson().toJson(new Yaml()
|
.create().fromJson(new Gson().toJson(new Yaml()
|
||||||
.dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
|
.dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解");
|
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在");
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
try {
|
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 {
|
try {
|
||||||
Constructor constructor = clazz.getConstructor();
|
Config config = object.getClass().getAnnotation(Config.class);
|
||||||
constructor.setAccessible(true);
|
|
||||||
Config config = clazz.getAnnotation(Config.class);
|
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
return new Serializer(new LinkedHashMap<>(), constructor.newInstance(), config.excludeModifiers()).get();
|
return new Serializer(new LinkedHashMap<>(), object, config.excludeModifiers()).get();
|
||||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有无参构造方法");
|
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有 @Config 注解");
|
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败");
|
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveConfig(Plugin plugin, Class<?> clazz) throws IOException, NullPointerException {
|
public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
|
||||||
Object obj = serialize(plugin, clazz);
|
Config config = object.getClass().getAnnotation(Config.class);
|
||||||
Validate.notNull(obj);
|
|
||||||
Config config = clazz.getAnnotation(Config.class);
|
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
|
Object obj = serialize(plugin, object);
|
||||||
|
Validate.notNull(obj);
|
||||||
File target = new File(plugin.getDataFolder(), config.name());
|
File target = new File(plugin.getDataFolder(), config.name());
|
||||||
if (!target.exists()) target.createNewFile();
|
if (!target.exists()) target.createNewFile();
|
||||||
DumperOptions options = new DumperOptions();
|
DumperOptions options = new DumperOptions();
|
||||||
@ -143,7 +138,8 @@ public class TConfigInjector {
|
|||||||
return map;
|
return map;
|
||||||
} else if (o instanceof ConfigurationSerializable) {
|
} else if (o instanceof ConfigurationSerializable) {
|
||||||
Map map = new LinkedHashMap();
|
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());
|
map.putAll(((ConfigurationSerializable) o).serialize());
|
||||||
return map;
|
return map;
|
||||||
} else if (o instanceof Property) {
|
} 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;
|
package com.ilummc.tlib.inject;
|
||||||
|
|
||||||
|
import me.skymc.taboolib.Main;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
@ -15,6 +16,8 @@ public class TLibPluginManager implements PluginManager {
|
|||||||
|
|
||||||
private final PluginManager instance;
|
private final PluginManager instance;
|
||||||
|
|
||||||
|
private final Main main = (Main) Main.getInst();
|
||||||
|
|
||||||
public TLibPluginManager() {
|
public TLibPluginManager() {
|
||||||
instance = Bukkit.getPluginManager();
|
instance = Bukkit.getPluginManager();
|
||||||
}
|
}
|
||||||
@ -56,7 +59,10 @@ public class TLibPluginManager implements PluginManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disablePlugins() {
|
public void disablePlugins() {
|
||||||
instance.disablePlugins();
|
for (Plugin plugin : getPlugins()) {
|
||||||
|
if (plugin != main) disablePlugin(plugin);
|
||||||
|
}
|
||||||
|
disablePlugin(main);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,37 +26,37 @@ public class TLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void verbose(String msg) {
|
public void verbose(String msg) {
|
||||||
if (level >= VERBOSE)
|
if (level <= VERBOSE)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finest(String msg) {
|
public void finest(String msg) {
|
||||||
if (level >= FINEST)
|
if (level <= FINEST)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fine(String msg) {
|
public void fine(String msg) {
|
||||||
if (level >= FINE)
|
if (level <= FINE)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void info(String msg) {
|
public void info(String msg) {
|
||||||
if (level >= INFO)
|
if (level <= INFO)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void warn(String msg) {
|
public void warn(String msg) {
|
||||||
if (level >= WARN)
|
if (level <= WARN)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void error(String msg) {
|
public void error(String msg) {
|
||||||
if (level >= ERROR)
|
if (level <= ERROR)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fatal(String msg) {
|
public void fatal(String msg) {
|
||||||
if (level >= FATAL)
|
if (level <= FATAL)
|
||||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg));
|
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +275,8 @@ public class Main extends JavaPlugin implements Listener {
|
|||||||
connection.closeConnection();
|
connection.closeConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TLib.unload();
|
||||||
|
|
||||||
// 关闭服务器
|
// 关闭服务器
|
||||||
Bukkit.shutdown();
|
Bukkit.shutdown();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user