版本更新至:4.04

调整:命令帮助的格式现在可以在语言文件中更改了。
调整:@CommandRegister 现在可以直接标注在 BaseSubCommand 成员变量上进行注册了(详见 TabooLibPluginMainCommand 写法)。
调整:TagAPI,TagManager 作废,但部分方法仍可使用。
新增:BaseSubCommand 类新增 getPermission 方法用于判断子命令权限
新增:TagDataHandler 类用于代替 TagManager 类
新增:TagPacket 类用于代替 TagAPI 类
修复:前后缀以及昵称的各种不兼容问题
修复:ItemUtils 工具载入物品时因 material 值不存在而导致的报错
删除:me.skymc.taboolib.team.TagUtils 类永久删除
This commit is contained in:
坏黑
2018-05-23 04:36:51 +08:00
parent ffa2d616c4
commit 0acf324b15
29 changed files with 1996 additions and 1844 deletions

View File

@@ -84,4 +84,4 @@ public class TDependency {
private static int getDownloadPoolSize() {
return Main.getInst().getConfig().getInt("DOWNLOAD-POOL-SIZE", 4);
}
}
}

View File

@@ -1,113 +1,61 @@
package com.ilummc.tlib.inject;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ilummc.tlib.annotations.TConfig;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.fileutils.ConfigUtils;
import com.google.gson.annotations.SerializedName;
import com.ilummc.tlib.TLib;
import com.ilummc.tlib.annotations.Config;
import com.ilummc.tlib.bean.Property;
import org.apache.commons.lang3.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
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;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
public class TConfigInjector {
public static void fixUnicode(YamlConfiguration configuration) {
try {
Field field = YamlConfiguration.class.getDeclaredField("yamlOptions");
field.setAccessible(true);
field.set(configuration, NoUnicodeDumperOption.INSTANCE);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
private static final class NoUnicodeDumperOption extends DumperOptions {
private static final NoUnicodeDumperOption INSTANCE = new NoUnicodeDumperOption();
@Override
public void setAllowUnicode(boolean allowUnicode) {
super.setAllowUnicode(false);
}
@Override
public boolean isAllowUnicode() {
return false;
}
@Override
public void setLineBreak(LineBreak lineBreak) {
super.setLineBreak(LineBreak.getPlatformLineBreak());
}
}
public static Object loadConfig(Plugin plugin, Class<?> clazz) {
try {
TConfig config = clazz.getAnnotation(TConfig.class);
Config config = clazz.getAnnotation(Config.class);
Validate.notNull(config);
File file = new File(plugin.getDataFolder(), config.name());
if (!file.exists()) {
if (config.fromJar()) {
plugin.saveResource(config.name(), true);
} else {
saveConfig(plugin, clazz.newInstance());
}
}
Object obj = unserialize(plugin, clazz);
if (config.readOnly()) {
saveConfig(plugin, obj);
}
return obj;
if (!file.exists()) if (config.fromJar()) plugin.saveResource(config.name(), true);
else saveConfig(plugin, clazz.newInstance());
return unserialize(plugin, clazz);
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), clazz.getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解");
} catch (Exception e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), clazz.getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败");
}
return null;
}
public static void reloadConfig(Plugin plugin, Object object) {
try {
TConfig config = object.getClass().getAnnotation(TConfig.class);
Validate.notNull(config);
File file = new File(plugin.getDataFolder(), config.name());
Map<String, Object> map = ConfigUtils.confToMap(ConfigUtils.loadYaml(plugin, file));
Object obj = ConfigUtils.mapToObj(map, object);
if (config.readOnly()) {
saveConfig(plugin, obj);
}
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
} catch (Exception e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), object.getClass().getSimpleName());
}
}
public static Object unserialize(Plugin plugin, Class<?> clazz) {
try {
TConfig config = clazz.getAnnotation(TConfig.class);
Config config = clazz.getAnnotation(Config.class);
Validate.notNull(config);
return ConfigUtils.confToObj(
ConfigUtils.mapToConf(
ConfigUtils.yamlToMap(
Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
return new GsonBuilder().disableHtmlEscaping().excludeFieldsWithModifiers(config.excludeModifiers())
.create().fromJson(new Gson().toJson(new Yaml()
.dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-FILE", plugin.toString(), clazz.getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在");
return null;
} catch (Exception e) {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e1) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), clazz.getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败");
return null;
}
}
@@ -115,29 +63,95 @@ public class TConfigInjector {
public static Map<String, Object> serialize(Plugin plugin, Object object) {
try {
TConfig config = object.getClass().getAnnotation(TConfig.class);
Config config = object.getClass().getAnnotation(Config.class);
Validate.notNull(config);
return ConfigUtils.objToMap(ConfigUtils.objToConf(object).getValues(false), config.excludeModifiers());
return new Serializer(new LinkedHashMap<>(), object, config.excludeModifiers()).get();
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.SAVE-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解");
} catch (Exception e) {
TLocale.Logger.warn("CONFIG.SAVE-FAIL", plugin.toString(), object.getClass().getSimpleName());
TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败");
}
return null;
}
public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
TConfig config = object.getClass().getAnnotation(TConfig.class);
Config config = object.getClass().getAnnotation(Config.class);
Validate.notNull(config);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
Map map = gson.fromJson(gson.toJson(object), HashMap.class);
YamlConfiguration configuration = (YamlConfiguration) ConfigUtils.mapToConf(map);
Object obj = serialize(plugin, object);
Validate.notNull(obj);
File target = new File(plugin.getDataFolder(), config.name());
if (!target.exists()) {
target.createNewFile();
}
byte[] arr = configuration.saveToString().getBytes(config.charset());
if (!target.exists()) target.createNewFile();
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
String str = yaml.dump(obj);
byte[] arr = str.getBytes(config.charset());
Files.write(arr, target);
}
private static final List<Class<?>> primitiveType = Lists.newArrayList(Integer.class,
Double.class, Float.class, Boolean.class, Short.class, Byte.class, Character.class, Long.class, String.class);
private static class Serializer {
private HashMap<String, Object> map;
private Object o;
private int modifiers;
private Serializer(HashMap<String, Object> map, Object o, int modifiers) {
this.map = map;
this.o = o;
this.modifiers = modifiers;
}
private HashMap<String, Object> get() {
for (Field field : o.getClass().getDeclaredFields()) {
if ((field.getModifiers() & modifiers) == 0 && !field.isSynthetic())
try {
SerializedName node = field.getAnnotation(SerializedName.class);
if (!field.isAccessible()) field.setAccessible(true);
Object obj = field.get(o);
map.put(node == null ? field.getName() : node.value(), serialize(obj));
} catch (Exception ignored) {
}
}
return map;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private Object serialize(Object o) {
try {
if (o.getClass().isPrimitive() || primitiveType.contains(o.getClass())) {
return o;
} else if (o.getClass().isArray()) {
List list = new ArrayList<>();
int len = (int) o.getClass().getField("length").get(o);
for (int i = 0; i < len; i++) {
list.add(serialize(Array.get(o, i)));
}
return list;
} else if (o instanceof Collection) {
return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList());
} else if (o instanceof Map) {
Map map = new LinkedHashMap<>();
((Map) o).forEach((o1, o2) -> map.put((String) o1, serialize(o2)));
return map;
} else if (o instanceof ConfigurationSerializable) {
Map map = new LinkedHashMap<>();
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) {
return serialize(((Property) o).get());
} else {
return new Serializer(new HashMap<>(), o, modifiers).get();
}
} catch (Exception ignored) {
return null;
}
}
}
}