diff --git a/TabooLib.iml b/TabooLib.iml index 88212e0..e1d93e7 100644 --- a/TabooLib.iml +++ b/TabooLib.iml @@ -26,7 +26,6 @@ - diff --git a/pom.xml b/pom.xml index 8be3a23..287e3fc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.0 + 4.01 UTF-8 diff --git a/src/main/java/com/ilummc/tlib/resources/TLocale.java b/src/main/java/com/ilummc/tlib/resources/TLocale.java index 982671e..b2dc858 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocale.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocale.java @@ -1,17 +1,20 @@ package com.ilummc.tlib.resources; import com.ilummc.tlib.TLib; +import com.ilummc.tlib.bungee.api.ChatColor; import com.ilummc.tlib.inject.TLoggerManager; import com.ilummc.tlib.util.Ref; import com.ilummc.tlib.util.Strings; +import me.clip.placeholderapi.PlaceholderAPI; import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.entity.Player; -import java.lang.reflect.Field; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class TLocale { @@ -20,15 +23,15 @@ public class TLocale { } static String asString(String path, Class callerClass, String... args) { - return TLocaleLoader.asString(getCallerPlugin(callerClass), path, args); + return TLocaleLoader.asString(Ref.getCallerPlugin(callerClass), path, args); } static List asStringList(String path, Class callerClass, String... args) { - return TLocaleLoader.asStringList(getCallerPlugin(callerClass), path, args); + return TLocaleLoader.asStringList(Ref.getCallerPlugin(callerClass), path, args); } private static void sendTo(String path, CommandSender sender, String[] args, Class callerClass) { - TLocaleLoader.sendTo(getCallerPlugin(callerClass), path, sender, args); + TLocaleLoader.sendTo(Ref.getCallerPlugin(callerClass), path, sender, args); } public static void sendToConsole(String path, String... args) { @@ -45,7 +48,7 @@ public class TLocale { public static String asString(String path, String... args) { try { - return asString(path, Ref.getCallerClassNotOptional(3), args); + return asString(path, Ref.getCallerClass(3).orElse(Main.class), args); } catch (Exception e) { TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path)); TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage())); @@ -55,7 +58,7 @@ public class TLocale { public static List asStringList(String path, String... args) { try { - return asStringList(path, Ref.getCallerClassNotOptional(3), args); + return asStringList(path, Ref.getCallerClass(3).orElse(Main.class), args); } catch (Exception e) { TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path)); TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage())); @@ -64,48 +67,64 @@ public class TLocale { } public static void reload() { - Ref.getCallerClass(3).ifPresent(clazz -> TLocaleLoader.load(getCallerPlugin(clazz), false)); + Ref.getCallerClass(3).ifPresent(clazz -> TLocaleLoader.load(Ref.getCallerPlugin(clazz), false)); } - private static JavaPlugin getCallerPlugin(Class callerClass) { - try { - Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); - pluginField.setAccessible(true); - return (JavaPlugin) pluginField.get(callerClass.getClassLoader()); - } catch (Exception ignored) { - TLib.getTLib().getLogger().error("无效的语言文件发送形式: &4" + callerClass.getName()); + public static final class Translate extends TLocale { + + public static boolean isPlaceholderUseDefault() { + return Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false); + } + + public static boolean isPlaceholderPluginEnabled() { + return Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null && Bukkit.getPluginManager().getPlugin("PlaceholderAPI").isEnabled(); + } + + public static String setColored(String args) { + return ChatColor.translateAlternateColorCodes('&', args); + } + + public static List setColored(List args) { + return args.stream().map(var -> ChatColor.translateAlternateColorCodes('&', var)).collect(Collectors.toList()); + } + + public static String setPlaceholders(CommandSender sender, String args) { + return isPlaceholderPluginEnabled() ? sender instanceof Player ? PlaceholderAPI.setPlaceholders((Player) sender, args) : args : args; + } + + public static List setPlaceholders(CommandSender sender, List args) { + return isPlaceholderPluginEnabled() ? sender instanceof Player ? PlaceholderAPI.setPlaceholders((Player) sender, args) : args : args; } - return (JavaPlugin) Main.getInst(); } public static final class Logger extends TLocale { public static void info(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).info(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).info(locale))); } public static void warn(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).warn(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).warn(locale))); } public static void error(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).error(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).error(locale))); } public static void fatal(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).fatal(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).fatal(locale))); } public static void fine(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).fine(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).fine(locale))); } public static void finest(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).finest(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).finest(locale))); } public static void verbose(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> TLoggerManager.getLogger(TLocale.getCallerPlugin(clazz)).verbose(asString(path, clazz, args))); + Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).verbose(locale))); } } diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java index 5664243..e77ec67 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList; import com.ilummc.tlib.TLib; import com.ilummc.tlib.resources.type.TLocaleText; import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.TabooLib; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; @@ -11,19 +12,17 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import javax.annotation.concurrent.ThreadSafe; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @ThreadSafe @SuppressWarnings("rawtypes") class TLocaleInstance { - private final Map> map = new HashMap<>(); + private final Map> map = new HashMap<>(); private final Plugin plugin; + private final AtomicInteger latestUpdateNodes = new AtomicInteger(); TLocaleInstance(Plugin plugin) { this.plugin = plugin; @@ -38,7 +37,7 @@ class TLocaleInstance { return map.size(); } - public Map> getMap() { + public Map> getMap() { return map; } @@ -46,58 +45,71 @@ class TLocaleInstance { return plugin; } + public AtomicInteger getLatestUpdateNodes() { + return latestUpdateNodes; + } + public void sendTo(String path, CommandSender sender, String... args) { try { - map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).forEach(sendable -> { + map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).forEach(tSender -> { if (Bukkit.isPrimaryThread()) { - sendable.sendTo(sender, args); + tSender.sendTo(sender, args); } else { - Bukkit.getScheduler().runTask(plugin, () -> sendable.sendTo(sender, args)); + Bukkit.getScheduler().runTask(plugin, () -> tSender.sendTo(sender, args)); } }); } catch (Exception | Error e) { TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("SEND-LOCALE-ERROR"), path)); TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.toString())); - e.printStackTrace(); } } public String asString(String path, String... args) { - return map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).get(0).asString(args); + return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asString(args); } public List asStringList(String path, String... args) { - return map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).get(0).asStringList(args); + return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asStringList(args); } - private static final Function TO_SENDABLE = o -> { - if (o instanceof TLocaleSendable) { - return ((TLocaleSendable) o); - } else if (o instanceof String || (o instanceof List && isListString(((List) o)))) { - return TLocaleText.of(o); - } else { - return TLocaleText.of(String.valueOf(o)); - } - }; - private static boolean isListString(List list) { for (Object o : list) { - if (!(o instanceof String)) return false; + if (!(o instanceof String)) { + return false; + } } return true; } public void load(YamlConfiguration configuration) { - configuration.getKeys(true).forEach(s -> { - Object object = configuration.get(s); - if (object instanceof TLocaleSendable) { - map.put(s, Collections.singletonList((TLocaleSendable) object)); - } else if (object instanceof List && !((List) object).isEmpty()) { - map.put(s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); - } else if (!(object instanceof ConfigurationSection)) { - String str = String.valueOf(object); - map.put(s, Collections.singletonList(str.length() == 0 ? TLocaleSendable.getEmpty() : TLocaleText.of(str))); + load(configuration, false); + } + + public void load(YamlConfiguration configuration, boolean cleanup) { + int originNodes = map.size(); + int updateNodes = 0; + if (cleanup) { + map.clear(); + } + for (String s : configuration.getKeys(true)) { + boolean updated = false; + Object value = configuration.get(s); + if (value instanceof TLocaleSerialize) { + updated = map.put(s, Collections.singletonList((TLocaleSerialize) value)) != null; + } else if (value instanceof List && !((List) value).isEmpty()) { + if (isListString((List) value)) { + updated = map.put(s, Collections.singletonList(TLocaleText.of(value))) != null; + } else { + updated = map.put(s, ((List) value).stream().map(o -> o instanceof TLocaleSerialize ? (TLocaleSerialize) o : TLocaleText.of(String.valueOf(o))).collect(Collectors.toList())) != null; + } + } else if (!(value instanceof ConfigurationSection)) { + String str = String.valueOf(value); + updated = map.put(s, Collections.singletonList(str.length() == 0 ? TLocaleSerialize.getEmpty() : TLocaleText.of(str))) != null; } - }); + if (updated) { + updateNodes++; + } + } + latestUpdateNodes.set(originNodes - updateNodes); } } diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java index 9b27c8e..31ddcad 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java @@ -1,25 +1,22 @@ package com.ilummc.tlib.resources; -import com.google.common.io.Files; import com.ilummc.tlib.TLib; import com.ilummc.tlib.annotations.TLocalePlugin; import com.ilummc.tlib.logger.TLogger; import com.ilummc.tlib.resources.type.*; import com.ilummc.tlib.util.IO; import com.ilummc.tlib.util.Strings; +import me.skymc.taboocode.TabooCodeLang; import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.other.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.YamlConfiguration; 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.io.InputStream; import java.nio.charset.Charset; import java.util.*; @@ -38,6 +35,7 @@ public class TLocaleLoader { } public static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) { + TabooLib.debug(plugin, "TLocaleLoader.sendTo: " + plugin + ", path: " + path + ", sender: " + sender + ", args: " + Arrays.asList(args)); if (Bukkit.isPrimaryThread()) { Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args)); } else { @@ -48,6 +46,7 @@ public class TLocaleLoader { } public static String asString(Plugin plugin, String path, String... args) { + TabooLib.debug(plugin, "TLocaleLoader.asString: " + plugin.getName() + ", path: " + path + ", args: " + Arrays.asList(args)); TLocaleInstance tLocaleInstance = map.get(plugin.getName()); if (tLocaleInstance != null) { return tLocaleInstance.asString(path, args); @@ -57,6 +56,7 @@ public class TLocaleLoader { } public static List asStringList(Plugin plugin, String path, String... args) { + TabooLib.debug(plugin, "TLocaleLoader.asStringList: " + plugin + ", path: " + path + ", args: " + Arrays.asList(args)); TLocaleInstance tLocaleInstance = map.get(plugin.getName()); if (tLocaleInstance != null) { return tLocaleInstance.asStringList(path, args); @@ -76,20 +76,23 @@ public class TLocaleLoader { if (isLoadLocale(plugin, isCover)) { // 获取文件 File localeFile = getLocaleFile(plugin); + if (localeFile == null) { + return; + } // 加载文件 infoLogger("TRY-LOADING-LANG", plugin.getName(), localeFile.getName()); - Map originMap = getLocaleAtStream(plugin, localeFile); - - TLib.getTLib().getConfigWatcher().removeListener(localeFile); + YamlConfiguration localeConfiguration = ConfigUtils.loadYaml(plugin, localeFile); + YamlConfiguration localeConfigurationAtStream = getLocaleAtStream(plugin, localeFile); // 载入配置 - updateAndLoad(plugin, localeFile, originMap); + loadPluginLocale(plugin, localeFile, localeConfiguration, localeConfigurationAtStream); // 注册监听 + TLib.getTLib().getConfigWatcher().removeListener(localeFile); TLib.getTLib().getConfigWatcher().addListener(localeFile, null, obj -> { infoLogger("RELOADING-LANG", plugin.getName()); - updateAndLoad(plugin, localeFile, getLocaleAtStream(plugin, localeFile)); + loadPluginLocale(plugin, localeFile, ConfigUtils.loadYaml(plugin, localeFile), getLocaleAtStream(plugin, localeFile)); }); } } catch (Exception e) { @@ -97,6 +100,18 @@ public class TLocaleLoader { } } + public static boolean isLocaleLoaded(Plugin plugin) { + return map.containsKey(plugin.getName()); + } + + public static boolean isDependWithTabooLib(Plugin plugin) { + return plugin.getClass().getAnnotation(TLocalePlugin.class) != null || plugin.getDescription().getDepend().contains(Main.getInst().getName()) || plugin.getDescription().getSoftDepend().contains(Main.getInst().getName()); + } + + public static List getLocalePriority() { + return Main.getInst().getConfig().contains("LOCALE.PRIORITY") ? Main.getInst().getConfig().getStringList("LOCALE.PRIORITY") : Collections.singletonList("zh_CN"); + } + private static boolean isLoadLocale(Plugin plugin, boolean isCover) { return (isCover || !isLocaleLoaded(plugin)) && (plugin.equals(Main.getInst()) || isDependWithTabooLib(plugin)); } @@ -109,98 +124,43 @@ public class TLocaleLoader { TLogger.getGlobalLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString(path), args)); } - private static boolean isVersionOutOfDate(YamlConfiguration configuration, YamlConfiguration configurationAtSteam) { - return (configurationAtSteam != null && configurationAtSteam.contains("VERSION") && configuration.contains("VERSION")) && NumberUtils.getDouble(configurationAtSteam.get("VERSION").toString()) > NumberUtils.getDouble(configuration.get("VERSION").toString()); - } - private static File getLocaleFile(Plugin plugin) { releaseLocales(plugin); - return getLocalePriority().stream().map(localeName -> new File(plugin.getDataFolder(), "lang/" + localeName + ".yml")).filter(File::exists).findFirst().orElseThrow(NullPointerException::new); + return getLocalePriority().stream().map(localeName -> new File(plugin.getDataFolder(), "lang/" + localeName + ".yml")).filter(File::exists).findFirst().orElse(null); } private static void releaseLocales(Plugin plugin) { getLocalePriority().stream().filter(localeName -> !new File(plugin.getDataFolder(), "lang/" + localeName + ".yml").exists() && plugin.getResource("lang/" + localeName + ".yml") != null).forEach(localeName -> plugin.saveResource("lang/" + localeName + ".yml", true)); } - private static boolean isLocaleLoaded(Plugin plugin) { - return map.containsKey(plugin.getName()); - } - - private static boolean isDependWithTabooLib(Plugin plugin) { - return plugin.getClass().getAnnotation(TLocalePlugin.class) != null || plugin.getDescription().getDepend().contains(Main.getInst().getName()) || plugin.getDescription().getSoftDepend().contains(Main.getInst().getName()); - } - - private static List getLocalePriority() { - return Main.getInst().getConfig().contains("LOCALE.PRIORITY") ? Main.getInst().getConfig().getStringList("LOCALE.PRIORITY") : Collections.singletonList("zh_CN"); - } - private static TLocaleInstance getLocaleInstance(Plugin plugin) { TLocaleInstance instance = new TLocaleInstance(plugin); map.put(plugin.getName(), instance); return instance; } - private static Map getLocaleAtStream(Plugin plugin, File localeFile) { + private static YamlConfiguration getLocaleAtStream(Plugin plugin, File localeFile) { InputStream localeInputSteam = plugin.getClass().getResourceAsStream("/lang/" + localeFile.getName()); try { String yamlText = new String(IO.readFully(localeInputSteam), Charset.forName("utf-8")); - Object load = new Yaml().load(yamlText); - return load instanceof Map ? (Map) load : new HashMap<>(0); - } catch (Exception e) { - return new HashMap<>(0); + YamlConfiguration yaml = new YamlConfiguration(); + yaml.loadFromString(yamlText); + return yaml; + } catch (Exception ignored) { + return null; } } - private static Map currentLocaleMap(File localeFile) { - try { - Object load = new Yaml().load(Files.toString(localeFile, Charset.forName("utf-8"))); - return load instanceof Map ? (Map) load : new HashMap<>(0); - } catch (Exception e) { - return new HashMap<>(0); - } - } - - private static int compareAndSet(Map origin, Map current, File file) { - int i = compareMaps(origin, current); - /* - if (i > 0) { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setAllowUnicode(false); - Yaml yaml = new Yaml(options); - String dump = yaml.dump(current); - try { - Files.write(dump.getBytes(Charset.forName("utf-8")), file); - } catch (IOException ignored) { - } - } - */ - return i; - } - - @SuppressWarnings("unchecked") - private static int compareMaps(Map origin, Map current) { - int res = 0; - for (Map.Entry entry : origin.entrySet()) { - if (current.putIfAbsent(entry.getKey(), entry.getValue()) != null) { - if (entry.getValue() instanceof Map && !((Map) entry.getValue()).containsKey("==") && current.get(entry.getKey()) instanceof Map) { - res += compareMaps((Map) entry.getValue(), (Map) current.get(entry.getKey())); - } - } else ++res; - } - return res; - } - - private static void updateAndLoad(Plugin plugin, File localeFile, Map originMap) { - Map currentMap = currentLocaleMap(localeFile); - int update = compareAndSet(originMap, currentMap, localeFile); + private static void loadPluginLocale(Plugin plugin, File localeFile, YamlConfiguration localeConfiguration, YamlConfiguration localeConfigurationAtStream) { TLocaleInstance localeInstance = getLocaleInstance(plugin); - YamlConfiguration localeConfiguration = (YamlConfiguration) ConfigUtils.mapToConf(currentMap); + if (localeConfigurationAtStream != null) { + localeInstance.load(localeConfigurationAtStream); + } localeInstance.load(localeConfiguration); - if (update == 0) { + if (localeInstance.getLatestUpdateNodes().get() <= 0) { infoLogger("SUCCESS-LOADING-LANG-NORMAL", plugin.getName(), localeFile.getName().split("\\.")[0], String.valueOf(localeInstance.size())); } else { - infoLogger("SUCCESS-LOADING-LANG-UPDATE", plugin.getName(), localeFile.getName().split("\\.")[0], String.valueOf(localeInstance.size()), String.valueOf(update)); + infoLogger("SUCCESS-LOADING-LANG-UPDATE", plugin.getName(), localeFile.getName().split("\\.")[0], String.valueOf(localeInstance.size()), String.valueOf(localeInstance.getLatestUpdateNodes().get())); } } } diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java b/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java deleted file mode 100644 index 99d2c11..0000000 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.ilummc.tlib.resources; - -import org.bukkit.command.CommandSender; - -import java.util.Collections; -import java.util.List; - -public interface TLocaleSendable { - - static TLocaleSendable getEmpty() { - return (sender, args) -> { - // Empty - }; - } - - static TLocaleSendable getEmpty(String path) { - return new TLocaleSendable() { - - @Override - public void sendTo(CommandSender sender, String... args) { - sender.sendMessage("§4<" + path + "§4>"); - } - - @Override - public String asString(String... args) { - return "§4<" + path + "§4>"; - } - - @Override - public List asStringList(String... args) { - return Collections.singletonList("§4<" + path + "§4>"); - } - }; - } - - void sendTo(CommandSender sender, String... args); - - default String asString(String... args) { - return ""; - } - - default List asStringList(String... args) { - return Collections.emptyList(); - } -} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleSender.java b/src/main/java/com/ilummc/tlib/resources/TLocaleSender.java new file mode 100644 index 0000000..6d75fd4 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleSender.java @@ -0,0 +1,37 @@ +package com.ilummc.tlib.resources; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +/** + * @Author sky + * @Since 2018-05-12 13:58 + */ +public interface TLocaleSender { + + /** + * 发送信息 + * + * @param sender 发送目标 + * @param args 参数 + */ + void sendTo(CommandSender sender, String... args); + + /** + * 获取文本 + * + * @param args 参数 + * @return 文本 + */ + String asString(String... args); + + /** + * 获取文本集合 + * + * @param args 参数 + * @return 文本集合 + */ + List asStringList(String... args); + +} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleSerialize.java b/src/main/java/com/ilummc/tlib/resources/TLocaleSerialize.java new file mode 100644 index 0000000..3155d74 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleSerialize.java @@ -0,0 +1,84 @@ +package com.ilummc.tlib.resources; + +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * @Author sky + * @Since 2018-05-12 14:01 + */ +public abstract class TLocaleSerialize implements TLocaleSender, ConfigurationSerializable { + + public static boolean isPlaceholderEnabled(Map map) { + Object placeholderObject = map.getOrDefault("papi", TLocale.Translate.isPlaceholderUseDefault()); + return placeholderObject instanceof Boolean ? (boolean) placeholderObject : placeholderObject instanceof String && "true".equals(placeholderObject); + } + + public static String getStringOrDefault(Map map, String path, String def) { + Object var = map.getOrDefault(path, def); + return var instanceof String ? (String) var : def; + } + + public static Integer getIntegerOrDefault(Map map, String path, Integer def) { + Object var = map.getOrDefault(path, def); + return var instanceof Integer ? (Integer) var : def; + } + + public static Double getDoubleOrDefault(Map map, String path, Double def) { + Object var = map.getOrDefault(path, def); + return var instanceof Double ? (Double) var : def; + } + + static TLocaleSerialize getEmpty() { + return new TLocaleSerialize() { + + @Override + public void sendTo(CommandSender sender, String... args) { + } + + @Override + public Map serialize() { + return null; + } + }; + } + + static TLocaleSerialize getEmpty(String path) { + return new TLocaleSerialize() { + + @Override + public Map serialize() { + return null; + } + + @Override + public void sendTo(CommandSender sender, String... args) { + sender.sendMessage("§8<" + path + "§8>"); + } + + @Override + public String asString(String... args) { + return "§8<" + path + "§8>"; + } + + @Override + public List asStringList(String... args) { + return Collections.singletonList("§4<" + path + "§4>"); + } + }; + } + + @Override + public String asString(String... args) { + return ""; + } + + @Override + public List asStringList(String... args) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java index 1a0f255..614efae 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java @@ -3,12 +3,11 @@ package com.ilummc.tlib.resources.type; import com.google.common.collect.Maps; import com.ilummc.tlib.compat.PlaceholderHook; import com.ilummc.tlib.nms.ActionBar; -import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.entity.Player; @@ -17,7 +16,7 @@ import java.util.Map; @Immutable @SerializableAs("ACTION") -public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializable { +public class TLocaleActionBar extends TLocaleSerialize { private final String text; private final boolean papi; @@ -29,8 +28,7 @@ public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializa public static TLocaleActionBar valueOf(Map map) { String text = ChatColor.translateAlternateColorCodes('&', String.valueOf(map.getOrDefault("text", "Empty Action bar message."))); - boolean papi = (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); - return new TLocaleActionBar(text, papi); + return new TLocaleActionBar(text, isPlaceholderEnabled(map)); } @Override diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java index c30aad5..4cc689b 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java @@ -7,13 +7,11 @@ import com.ilummc.tlib.TLib; import com.ilummc.tlib.bungee.api.chat.*; import com.ilummc.tlib.bungee.chat.ComponentSerializer; import com.ilummc.tlib.compat.PlaceholderHook; -import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.util.Strings; -import me.skymc.taboolib.Main; import me.skymc.taboolib.jsonformatter.JSONFormatter; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.entity.Player; @@ -25,7 +23,7 @@ import java.util.stream.Collectors; @ThreadSafe @SerializableAs("JSON") -public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { +public class TLocaleJson extends TLocaleSerialize { private static final Pattern pattern = Pattern.compile("<([^<>]*)?@([^<>]*)>"); private final List components; @@ -39,9 +37,6 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { } public static TLocaleJson valueOf(Map map) { - boolean papi = (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); - - // text 里面的东西 List textList = getTextList(map.getOrDefault("text", "Empty Node")); // 分析 args 并替换 @@ -73,7 +68,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { // 如果 args 有这个 xxx if (section.containsKey(node)) { Map arg = (Map) section.get(node); - text = ChatColor.translateAlternateColorCodes('&', String.valueOf(arg.getOrDefault("text", text))); + text = TLocale.Translate.setColored(String.valueOf(arg.getOrDefault("text", text))); // 可能有很多个 BaseComponent,于是为每个 component 单独设置各种事件 BaseComponent[] component = TextComponent.fromLegacyText(text); arg.forEach((key, value) -> { @@ -82,7 +77,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { } else if ("command".equalsIgnoreCase(key) || "commands".equalsIgnoreCase(key)) { Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.valueOf(value)))); } else if ("hover".equalsIgnoreCase(key)) { - Arrays.stream(component).forEach(baseComponent -> baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(ChatColor.translateAlternateColorCodes('&', String.valueOf(value))).create()))); + Arrays.stream(component).forEach(baseComponent -> baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(TLocale.Translate.setColored(String.valueOf(value))).create()))); } }); // 添加到原来的 list 里面 @@ -99,16 +94,16 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { } return builder.toArray(new BaseComponent[0]); }).collect(Collectors.toList()); - return new TLocaleJson(collect, papi, map); + return new TLocaleJson(collect, isPlaceholderEnabled(map), map); } - return new TLocaleJson(textList.stream().map(TextComponent::fromLegacyText).collect(Collectors.toList()), papi, map); + return new TLocaleJson(textList.stream().map(TextComponent::fromLegacyText).collect(Collectors.toList()), isPlaceholderEnabled(map), map); } private static List getTextList(Object textObj) { if (textObj instanceof List) { - return ((List) textObj).stream().map(Object::toString).map(s -> ChatColor.translateAlternateColorCodes('&', s)).collect(Collectors.toList()); + return ((List) textObj).stream().map(Object::toString).map(s -> TLocale.Translate.setColored(s)).collect(Collectors.toList()); } else if (textObj instanceof String) { - return Lists.newArrayList(ChatColor.translateAlternateColorCodes('&', (String) textObj)); + return Lists.newArrayList(TLocale.Translate.setColored((String) textObj)); } else { return Collections.emptyList(); } diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleSound.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleSound.java index 26e2e22..5aec6e1 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleSound.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleSound.java @@ -1,10 +1,9 @@ package com.ilummc.tlib.resources.type; import com.google.common.collect.Maps; -import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.resources.TLocaleSerialize; import me.skymc.taboolib.sound.SoundPack; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.entity.Player; @@ -20,7 +19,7 @@ import java.util.stream.Collectors; */ @Immutable @SerializableAs("ACTION") -public class TLocaleSound implements TLocaleSendable, ConfigurationSerializable { +public class TLocaleSound extends TLocaleSerialize { private final List soundPacks; diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java index b23185e..fc5e587 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java @@ -4,12 +4,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.ilummc.tlib.compat.PlaceholderHook; -import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import javax.annotation.concurrent.Immutable; @@ -19,7 +18,7 @@ import java.util.stream.Collectors; @Immutable @SerializableAs("TEXT") @SuppressWarnings({"unchecked", "rawtypes"}) -public class TLocaleText implements TLocaleSendable, ConfigurationSerializable { +public class TLocaleText extends TLocaleSerialize { private final Object text; private final boolean usePlaceholder; @@ -35,68 +34,46 @@ public class TLocaleText implements TLocaleSendable, ConfigurationSerializable { } } - private String replaceMsg(CommandSender sender, String s) { - return usePlaceholder ? PlaceholderHook.replace(sender, s) : s; - } - - public static TLocaleText valueOf(Map map) { - if (map.containsKey("text")) { - Object object = map.get("text"); - Object objPapi = map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); - boolean papi = objPapi instanceof Boolean ? (boolean) objPapi : objPapi instanceof String && "true".equals(objPapi); - if (object instanceof List) { - return new TLocaleText(((List) object).stream() - .map(s -> ChatColor.translateAlternateColorCodes('&', s)) - .collect(Collectors.toList()), papi); - } else if (object instanceof String[]) { - return new TLocaleText(Arrays.stream(((String[]) object)) - .map(s -> ChatColor.translateAlternateColorCodes('&', s)) - .collect(Collectors.toList()), papi); - } else { - return new TLocaleText(ChatColor.translateAlternateColorCodes('&', Objects.toString(object)), papi); - } - } - return new TLocaleText("§cError chat message loaded.", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); - } - public static TLocaleText of(String s) { - return new TLocaleText(ChatColor.translateAlternateColorCodes('&', s), Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); + return new TLocaleText(TLocale.Translate.setColored(s), TLocale.Translate.isPlaceholderUseDefault()); } public static TLocaleText of(Object o) { return o instanceof String ? of(((String) o)) : new TLocaleText(o, false); } + public static TLocaleText valueOf(Map map) { + if (map.containsKey("text")) { + Object object = map.get("text"); + if (object instanceof String[]) { + return new TLocaleText(Arrays.stream(((String[]) object)).collect(Collectors.toList()), isPlaceholderEnabled(map)); + } else { + return new TLocaleText(Objects.toString(object), isPlaceholderEnabled(map)); + } + } + return new TLocaleText("§cError chat message loaded.", TLocale.Translate.isPlaceholderUseDefault()); + } + @Override public void sendTo(CommandSender sender, String... args) { if (text instanceof String) { - sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder((String) text, args))); + sender.sendMessage(replaceText(sender, Strings.replaceWithOrder((String) text, args))); } else if (text instanceof List) { - ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder(String.valueOf(s), args)))); + ((List) text).forEach(s -> sender.sendMessage(replaceText(sender, Strings.replaceWithOrder(String.valueOf(s), args)))); } } @Override public String asString(String... args) { - return Strings.replaceWithOrder(objectToString(text), args); + return Strings.replaceWithOrder(TLocale.Translate.setColored(objectToString(text)), args); } @Override public List asStringList(String... args) { - if (text instanceof String) { - return Collections.singletonList(((String) text)); + if (text instanceof List) { + return ((List) text).stream().map(x -> Strings.replaceWithOrder(TLocale.Translate.setColored(x), args)).collect(Collectors.toList()); } else { - return ((List) text); - } - } - - private String objectToString(Object text) { - if (text instanceof String) { - return ((String) text); - } else { - StringJoiner joiner = new StringJoiner("\n"); - ((List) text).forEach(joiner::add); - return joiner.toString(); + return Collections.singletonList(asString(args)); } } @@ -111,9 +88,20 @@ public class TLocaleText implements TLocaleSendable, ConfigurationSerializable { @Override public Map serialize() { - if (usePlaceholder) { - return Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)); + return usePlaceholder ? Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)) : Maps.newHashMap(ImmutableMap.of("text", text)); + } + + private String replaceText(CommandSender sender, String args) { + return usePlaceholder ? TLocale.Translate.setPlaceholders(sender, args) : TLocale.Translate.setColored(args); + } + + private String objectToString(Object text) { + if (text instanceof String) { + return ((String) text); + } else { + StringJoiner joiner = new StringJoiner("\n"); + ((List) text).forEach(joiner::add); + return joiner.toString(); } - return Maps.newHashMap(ImmutableMap.of("text", text)); } } diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java index 460c2c5..59fcf6e 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java @@ -1,15 +1,11 @@ package com.ilummc.tlib.resources.type; import com.google.common.collect.Maps; -import com.ilummc.tlib.compat.PlaceholderHook; import com.ilummc.tlib.resources.TLocale; -import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.util.Strings; -import me.skymc.taboolib.Main; import me.skymc.taboolib.display.TitleUtils; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.entity.Player; @@ -24,7 +20,7 @@ import java.util.Map; @Immutable @SerializableAs("TITLE") -public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable { +public class TLocaleTitle extends TLocaleSerialize { private final String title; private final String subtitle; @@ -47,12 +43,12 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable TLocaleTitle title; try { title = new TLocaleTitle( - (String) map.getOrDefault("title", ""), - (String) map.getOrDefault("subtitle", ""), - (int) map.getOrDefault("fadein", 10), - (int) map.getOrDefault("fadeout", 10), - (int) map.getOrDefault("stay", 20), - (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false))); + getStringOrDefault(map, "title", ""), + getStringOrDefault(map, "subtitle", ""), + getIntegerOrDefault(map, "fadein", 10), + getIntegerOrDefault(map, "fadeout", 10), + getIntegerOrDefault(map, "stay", 10), + isPlaceholderEnabled(map)); } catch (Exception e) { title = new TLocaleTitle("Empty Title message.", e.getMessage(), 10, 20, 10, false); } @@ -70,7 +66,7 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable @Override public String asString(String... args) { - return Strings.replaceWithOrder("TITLE: [title: '" + title + "', subtitle: '" + subtitle + "', fadeIn: " + fadein + ", fadeOut: " + fadeout + "]", args); + return Strings.replaceWithOrder(Strings.replaceWithOrder("TITLE: [title: ''{0}'', subtitle: ''{1}'', fadeIn: {2}, fadeOut: {3}]", title, subtitle, fadein, fadeout), args); } @Override @@ -90,7 +86,7 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable return map; } - private String replaceText(CommandSender sender, String s) { - return ChatColor.translateAlternateColorCodes('&', usePlaceholder ? PlaceholderHook.replace(sender, s) : s); + private String replaceText(CommandSender sender, String args) { + return usePlaceholder ? TLocale.Translate.setPlaceholders(sender, args) : TLocale.Translate.setColored(args); } } diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java index 866cdfc..69374de 100644 --- a/src/main/java/com/ilummc/tlib/util/Ref.java +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -2,7 +2,10 @@ package com.ilummc.tlib.util; import com.google.gson.annotations.SerializedName; import com.ilummc.tlib.TLib; +import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.asm.AsmAnalyser; +import me.skymc.taboolib.Main; +import org.bukkit.plugin.java.JavaPlugin; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import sun.reflect.Reflection; @@ -96,6 +99,17 @@ public class Ref { return Optional.empty(); } + public static JavaPlugin getCallerPlugin(Class callerClass) { + try { + Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); + pluginField.setAccessible(true); + return (JavaPlugin) pluginField.get(callerClass.getClassLoader()); + } catch (Exception ignored) { + TLocale.Logger.error("LOCALE.CALLER-PLUGIN-NOT-FOUND", callerClass.getName()); + } + return (JavaPlugin) Main.getInst(); + } + private static abstract class CallerClass { private static CallerClass impl; diff --git a/src/main/java/com/ilummc/tlib/util/Strings.java b/src/main/java/com/ilummc/tlib/util/Strings.java index 4aff5d5..e454212 100644 --- a/src/main/java/com/ilummc/tlib/util/Strings.java +++ b/src/main/java/com/ilummc/tlib/util/Strings.java @@ -27,4 +27,16 @@ public class Strings { } return stringBuilder.toString(); } + + public static String replaceWithOrder(String template, String... args) { + return replaceWithOrder(template, (Object[]) args); + } + + public static boolean isBlank(String var) { + return var == null || var.trim().isEmpty(); + } + + public static boolean isEmpty(CharSequence var) { + return var == null || var.length() == 0; + } } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 111c451..a866bb4 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -1,6 +1,8 @@ package me.skymc.taboolib; import com.ilummc.tlib.TLib; +import com.ilummc.tlib.inject.TConfigWatcher; +import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.anvil.AnvilContainerAPI; import me.skymc.taboolib.bstats.Metrics; import me.skymc.taboolib.commands.TabooLibMainCommand; @@ -24,6 +26,7 @@ import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.mysql.protect.MySQLConnection; import me.skymc.taboolib.nms.item.DabItemUtils; import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.packet.PacketUtils; import me.skymc.taboolib.permission.PermissionUtils; import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.sign.SignUtils; @@ -179,7 +182,7 @@ public class Main extends JavaPlugin implements Listener { String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString(); // 如果这个值和我的值不同 if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) { - MsgUtils.warn("检测到本服序列号与其他服务器相同, 已重新生成!"); + TLocale.Logger.error("NOTIFY.ERROR-SERVER-KEY"); // 重新生成序列号 TabooLib.resetServerUID(); // 关服 @@ -188,7 +191,7 @@ public class Main extends JavaPlugin implements Listener { } } else { // 提示 - MsgUtils.warn("数据库连接失败, 请检查配置是否正确!"); + TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FALL"); // 关服 Bukkit.shutdown(); } @@ -223,12 +226,10 @@ public class Main extends JavaPlugin implements Listener { TimeCycleManager.load(); // 启动脚本 JavaShell.javaShellSetup(); - // 载入语言文件 - exampleLanguage2 = new Language2("Language2", this); // 注册脚本 SkriptHandler.getInst(); - // 注册昵称 - TagAPI.inst(); + // 载入语言文件 + exampleLanguage2 = new Language2("Language2", this); // 启动数据库储存方法 if (getStorageType() == StorageType.SQL) { @@ -236,14 +237,16 @@ public class Main extends JavaPlugin implements Listener { } // 载入完成 - MsgUtils.send("§7插件载入完成!"); - MsgUtils.send("§7插件版本: §f" + getDescription().getVersion()); - MsgUtils.send("§7插件作者: §f" + getDescription().getAuthors()); - MsgUtils.send("§7游戏版本: §f" + TabooLib.getVerint()); + TLocale.Logger.info("NOTIFY.SUCCESS-LOADED", getDescription().getAuthors().toString(), getDescription().getVersion(), String.valueOf(TabooLib.getVersion())); // 文件保存 Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120); Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60); + // 文件监控 + TLib.getTLib().getConfigWatcher().addListener(new File(getDataFolder(), "config.yml"), null, obj -> { + reloadConfig(); + TLocale.Logger.info("CONFIG.RELOAD-SUCCESS", inst.getName(), "config.yml"); + }); // 插件联动 new BukkitRunnable() { @@ -253,6 +256,9 @@ public class Main extends JavaPlugin implements Listener { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { new SupportPlaceholder(getInst(), "taboolib").hook(); } + if (PacketUtils.isProtocolLibEnabled()) { + TagAPI.inst(); + } // 载入 SpecialItem 接口 SpecialItem.getInst().loadItems(); // 载入 TLM 接口 @@ -275,8 +281,7 @@ public class Main extends JavaPlugin implements Listener { // 如果插件尚未启动完成 if (!started) { - MsgUtils.send("&c插件尚未启动完成, 已跳过卸载代码"); - MsgUtils.send("&c插件作者: &4坏黑"); + TLocale.Logger.error("NOTIFY.FALL-DISABLE"); return; } @@ -310,8 +315,7 @@ public class Main extends JavaPlugin implements Listener { } // 提示信息 - MsgUtils.send("&c插件已卸载, 感谢您使用&4禁忌书库"); - MsgUtils.send("&c插件作者: &4坏黑"); + TLocale.Logger.error("NOTIFY.SUCCESS-DISABLE"); // 清理头衔 TagUtils.delete(); diff --git a/src/main/java/me/skymc/taboolib/TabooLib.java b/src/main/java/me/skymc/taboolib/TabooLib.java index d0fcfc6..21ced84 100644 --- a/src/main/java/me/skymc/taboolib/TabooLib.java +++ b/src/main/java/me/skymc/taboolib/TabooLib.java @@ -10,6 +10,10 @@ import java.util.UUID; public class TabooLib { + public static boolean isDebug() { + return Main.getInst().getConfig().getBoolean("DEBUG"); + } + public static void debug(Plugin plugin, String... args) { if (Main.getInst().getConfig().getBoolean("DEBUG")) { Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var)); diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java index 7031477..b9a4246 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java @@ -1,8 +1,6 @@ package me.skymc.taboolib.anvil; -import com.ilummc.tlib.util.asm.AsmClassTransformer; import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; /** diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java index ac17535..cffc5d8 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java @@ -46,7 +46,7 @@ public class AnvilContainerAPI implements Listener { meta.setDisplayName(str); item.setItemMeta(meta); - p.getOpenInventory().setItem(0, item); + p.getOpenInventory().getTopInventory().setItem(0, item); p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1); } diff --git a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java index e21c576..a036026 100644 --- a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java @@ -106,10 +106,41 @@ public class TabooLibMainCommand extends BaseMainCommand { return new CommandArgument[0]; } + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + new InfoCommand(sender, args); + } + }); + } + + @CommandRegister(priority = 3.1) + void infoList() { + registerSubCommand(new BaseSubCommand() { + + @Override + public String getLabel() { + return "itemList"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[0]; + } + @Override public void onCommand(CommandSender sender, Command command, String label, String[] args) { new ItemListCommand(sender, args); } + + @Override + public boolean ignoredLabel() { + return false; + } }); } diff --git a/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java index d9c9eb8..9116be8 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java @@ -2,6 +2,8 @@ package me.skymc.taboolib.commands.internal; import com.google.common.base.Preconditions; import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.resources.TLocaleLoader; +import com.ilummc.tlib.util.Ref; import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.commands.internal.type.CommandRegister; @@ -10,8 +12,11 @@ import me.skymc.taboolib.string.ArrayUtils; import me.skymc.taboolib.string.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.*; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; @@ -35,6 +40,7 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor, baseMainCommand.getRegisterCommand().setExecutor(baseMainCommand); baseMainCommand.getRegisterCommand().setTabCompleter(baseMainCommand); baseMainCommand.getLinkClasses().add(baseMainCommand.getClass()); + baseMainCommand.disguisedPlugin(); loadCommandRegister(baseMainCommand); return baseMainCommand; } @@ -149,7 +155,7 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor, } private boolean isConfirmType(CommandSender sender, CommandType commandType) { - return commandType == CommandType.ALL || sender instanceof ConsoleCommandSender && commandType == CommandType.CONSOLE; + return commandType == CommandType.ALL || (sender instanceof Player && commandType == CommandType.PLAYER); } private void helpCommand(CommandSender sender, String label) { @@ -159,4 +165,17 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor, subCommands.stream().map(subCommand -> subCommand == null ? getEmptyLine() : subCommand.getCommandString(label)).forEach(sender::sendMessage); sender.sendMessage(getEmptyLine()); } + + private void disguisedPlugin() { + linkClasses.forEach(clazz -> disguisedPlugin(clazz, (JavaPlugin) registerCommand.getPlugin())); + } + + private void disguisedPlugin(Class targetClass, JavaPlugin plugin) { + try { + Field pluginField = targetClass.getClassLoader().getClass().getDeclaredField("plugin"); + pluginField.setAccessible(true); + pluginField.set(targetClass.newInstance(), plugin); + } catch (Exception ignored) { + } + } } diff --git a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java index cf29a86..74bf64a 100644 --- a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java @@ -4,6 +4,7 @@ import com.google.common.base.Joiner; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.ISubCommand; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.plugin.PluginUtils; import me.skymc.taboolib.string.ArrayUtils; @@ -12,6 +13,7 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -30,6 +32,21 @@ public class TabooLibPluginMainCommand extends BaseMainCommand { reloadCommand(); } + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) { + if (args.length == 1) { + return getSubCommands().stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(ISubCommand::getLabel).collect(Collectors.toList()); + } else if (args.length > 1 && isPluginCommand(args[0])) { + return Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(x -> !PluginUtils.isIgnored(x)).collect(Collectors.toList()).stream().filter(plugin -> args[1].isEmpty() || plugin.getName().toLowerCase().startsWith(args[1].toLowerCase())).map(Plugin::getName).collect(Collectors.toList()); + } else { + return null; + } + } + + private boolean isPluginCommand(String label) { + return "info".equalsIgnoreCase(label) || "load".equalsIgnoreCase(label) || "unload".equalsIgnoreCase(label) || "reload".equalsIgnoreCase(label); + } + @Override public String getCommandTitle() { return TLocale.asString("COMMANDS.TPLUGIN.COMMAND-TITLE"); diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java index 7890de1..31b880d 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java @@ -19,7 +19,7 @@ public class InfoCommand extends SubCommand { TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.INVALID-ITEM"); } else { NBTItem nbt = new NBTItem(player.getItemInHand()); - TLocale.sendTo(sender, "COMAMNDS.TABOOLIB.INFO.ITEM-INFO", + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.ITEM-INFO", player.getItemInHand().getType().name(), ItemUtils.getCustomName(player.getItemInHand()), player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(), diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java index 25d9869..5dbcbda 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java @@ -27,12 +27,11 @@ public class TagDeleteCommand extends SubCommand { return; } - TagManager.getInst().removeData(player); + TagManager.getInst().unloadData(player); TagAPI.removePlayerDisplayName(player); if (sender instanceof Player) { TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DELETE", args[1]); } } - } diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java index d7cc2e0..42d3bf7 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java @@ -44,7 +44,13 @@ public class ListenerItemListCommand implements Listener { if (loop >= (page - 1) * 28) { if (loop < page * 28) { int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28)); - inventory.setItem(slot, getItem(map, name)); + ItemStack item = map.get(name).clone(); + ItemMeta meta = item.getItemMeta(); + List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); + lore.addAll(TLocale.asStringList("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name)); + meta.setLore(lore); + item.setItemMeta(meta); + inventory.setItem(slot, item); holder.ITEMS_DATA.put(slot, name); } else { break; @@ -62,16 +68,6 @@ public class ListenerItemListCommand implements Listener { player.openInventory(inventory); } - private static ItemStack getItem(HashMap map, String name) { - ItemStack item = map.get(name).clone(); - ItemMeta meta = item.getItemMeta(); - List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); - lore.addAll(TLocale.asStringList("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name)); - meta.setLore(lore); - item.setItemMeta(meta); - return item; - } - @EventHandler public void inventoryClick(InventoryClickEvent e) { if (e.getInventory().getHolder() instanceof ItemLibraryHolder) { diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java index 91e7f56..3985f99 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java @@ -34,13 +34,19 @@ public class ListenerSoundsCommand implements Listener { SoundLibraryHolder holder = new SoundLibraryHolder(page, search); Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.TITLE", String.valueOf(page))); List soundFilter = Arrays.stream(Sound.values()).filter(sound -> search == null || sound.name().contains(search.toUpperCase())).collect(Collectors.toList()); + List soundLore = TLocale.asStringList("COMMANDS.TABOOLIB.SOUNDS.MENU.LORE"); int loop = 0; for (Sound sound : soundFilter) { if (loop >= (page - 1) * 28) { if (loop < page * 28) { int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28)); - inventory.setItem(slot, getSoundItem(sound.name())); + ItemStack item = new ItemStack(Material.MAP); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName("§f§n" + sound); + meta.setLore(soundLore); + item.setItemMeta(meta); + inventory.setItem(slot, item); holder.SOUNDS_DATA.put(slot, sound); } else { break; @@ -62,15 +68,6 @@ public class ListenerSoundsCommand implements Listener { player.openInventory(inventory); } - private static ItemStack getSoundItem(String sound) { - ItemStack item = new ItemStack(Material.MAP); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("§f§n" + sound); - meta.setLore(TLocale.asStringList("COMMANDS.TABOOLIB.SOUNDS.MENU.LORE")); - item.setItemMeta(meta); - return item; - } - @EventHandler public void inventoryClick(InventoryClickEvent e) { if (e.getInventory().getHolder() instanceof SoundLibraryHolder) { diff --git a/src/main/java/me/skymc/taboolib/display/ActionUtils.java b/src/main/java/me/skymc/taboolib/display/ActionUtils.java index b80e2b3..530224b 100644 --- a/src/main/java/me/skymc/taboolib/display/ActionUtils.java +++ b/src/main/java/me/skymc/taboolib/display/ActionUtils.java @@ -1,22 +1,49 @@ package me.skymc.taboolib.display; -import com.ilummc.tlib.nms.ActionBar; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.nms.NMSUtils; import org.bukkit.entity.Player; +import java.lang.reflect.Constructor; + /** * @author Bkm016 * @since 2018-04-26 */ public class ActionUtils { + private static Class Packet = NMSUtils.getNMSClass("Packet"); + private static Class ChatComponentText = NMSUtils.getNMSClass("ChatComponentText"); + private static Class ChatMessageType = NMSUtils.getNMSClass("ChatMessageType"); + private static Class PacketPlayOutChat = NMSUtils.getNMSClass("PacketPlayOutChat"); + private static Class IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent"); + public static void send(Player player, String action) { if (player == null) { return; } try { - ActionBar.sendActionBar(player, action); - } catch (Throwable ignored) { + Object ab = ChatComponentText.getConstructor(String.class).newInstance(action); + Constructor ac; + Object abPacket; + if (TabooLib.getVerint() > 11100) { + ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType); + abPacket = ac.newInstance(ab, ChatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2)); + } else { + ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, Byte.TYPE); + abPacket = ac.newInstance(ab, (byte) 2); + } + sendPacket(player, abPacket); + } catch (Exception ignored) { } } -} + private static void sendPacket(Player player, Object packet) { + try { + Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player); + Object playerConnection = handle.getClass().getField("playerConnection").get(handle); + playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packet); + } catch (Exception ignored) { + } + } +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java b/src/main/java/me/skymc/taboolib/packet/PacketUtils.java index a5aa8e6..1a85164 100644 --- a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java +++ b/src/main/java/me/skymc/taboolib/packet/PacketUtils.java @@ -2,13 +2,31 @@ package me.skymc.taboolib.packet; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.google.common.base.Preconditions; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +/** + * @author sky + */ public class PacketUtils { + public static void checkProtocolLib() { + Preconditions.checkArgument(isProtocolLibEnabled(), "Plugin \"ProtocolLib\" cannot found!"); + } + + public static boolean isProtocolLibEnabled() { + return Bukkit.getPluginManager().getPlugin("ProtocolLib") != null && Bukkit.getPluginManager().getPlugin("ProtocolLib").isEnabled(); + } + + public static ProtocolManager getManager() { + return ProtocolLibrary.getProtocolManager(); + } + public static void sendPacketEntityStatus(Entity entity, EntityStatus status, Player... players) { PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); packet.getIntegers().write(0, entity.getEntityId()); diff --git a/src/main/java/me/skymc/taboolib/string/ArrayUtils.java b/src/main/java/me/skymc/taboolib/string/ArrayUtils.java index 9e67312..561c282 100644 --- a/src/main/java/me/skymc/taboolib/string/ArrayUtils.java +++ b/src/main/java/me/skymc/taboolib/string/ArrayUtils.java @@ -31,7 +31,7 @@ public class ArrayUtils { public static String[] removeFirst(String[] args) { if (args.length <= 1) { - return null; + return new String[0]; } List list = asList(args); list.remove(0); diff --git a/src/main/java/me/skymc/taboolib/team/TagAPI.java b/src/main/java/me/skymc/taboolib/team/TagAPI.java index b5819d0..893c977 100644 --- a/src/main/java/me/skymc/taboolib/team/TagAPI.java +++ b/src/main/java/me/skymc/taboolib/team/TagAPI.java @@ -135,6 +135,7 @@ public class TagAPI implements Listener { AsyncPlayerReceiveNameTagEvent newEvent = new AsyncPlayerReceiveNameTagEvent(destinationPlayer, namedPlayer, getPlayerDisplayName(namedPlayer), UUID.fromString(builtUUID.toString())); Bukkit.getServer().getPluginManager().callEvent(newEvent); + updatePlayerTag(namedPlayer, newEvent); return new WrappedGameProfile(newEvent.getUUID(), newEvent.getTag().substring(0, Math.min(newEvent.getTag().length(), 16))); } @@ -147,4 +148,14 @@ public class TagAPI implements Listener { public void onQuit(PlayerQuitEvent event) { entityIdMap.remove(event.getPlayer().getEntityId()); } + + private static void updatePlayerTag(Player namedPlayer, AsyncPlayerReceiveNameTagEvent newEvent) { + TagManager.PlayerData playerData = TagManager.getInst().getPlayerData(namedPlayer); + if (playerData.isEmpty()) { + return; + } + TagManager.getInst().unloadData(namedPlayer); + playerData.setName(newEvent.getTag()); + TagManager.getInst().uploadData(namedPlayer); + } } diff --git a/src/main/java/me/skymc/taboolib/team/TagManager.java b/src/main/java/me/skymc/taboolib/team/TagManager.java index bf4a779..e34fc4b 100644 --- a/src/main/java/me/skymc/taboolib/team/TagManager.java +++ b/src/main/java/me/skymc/taboolib/team/TagManager.java @@ -1,5 +1,6 @@ package me.skymc.taboolib.team; +import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -11,6 +12,7 @@ import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import java.util.HashMap; +import java.util.UUID; /** * @author sky @@ -20,7 +22,7 @@ public class TagManager implements Listener { private static TagManager inst; - private HashMap playerdata = new HashMap<>(); + private HashMap playerData = new HashMap<>(); private TagManager() { Bukkit.getPluginManager().registerEvents(this, Main.getInst()); @@ -35,8 +37,8 @@ public class TagManager implements Listener { return inst; } - public HashMap getPlayerdata() { - return playerdata; + public HashMap getPlayerData() { + return playerData; } /** @@ -87,52 +89,44 @@ public class TagManager implements Listener { * @param player 玩家 * @return {@link PlayerData} */ - private PlayerData getPlayerData(Player player) { - return playerdata.computeIfAbsent(player.getName(), k -> new PlayerData(player.getName())); + public PlayerData getPlayerData(Player player) { + return playerData.computeIfAbsent(player.getUniqueId(), k -> new PlayerData(player)); } /** - * 删除该玩家的称号数据 + * 注销称号数据 * - * @param player + * @param targetPlayer */ - public void removeData(Player player) { - playerdata.remove(player.getName()); - for (Player _player : Bukkit.getOnlinePlayers()) { - Scoreboard scoreboard = _player.getScoreboard(); - if (scoreboard != null) { - Team team = scoreboard.getTeam(player.getName()); - if (team != null) { - team.unregister(); - } + public void unloadData(Player targetPlayer) { + PlayerData data = getPlayerData(targetPlayer); + for (Player player : Bukkit.getOnlinePlayers()) { + Scoreboard scoreboard = getScoreboard(player); + Team team = scoreboard.getTeam(data.getName()); + if (team != null) { + team.unregister(); } } + data.reset(); } /** * 将该玩家的数据向服务器所有玩家更新 * - * @param player 玩家 + * @param targetPlayer 玩家 */ - public void uploadData(Player player) { - PlayerData data = getPlayerData(player); + public void uploadData(Player targetPlayer) { + PlayerData data = getPlayerData(targetPlayer); String prefix = data.getPrefix().length() > 16 ? data.getPrefix().substring(0, 16) : data.getPrefix(); String suffix = data.getSuffix().length() > 16 ? data.getSuffix().substring(0, 16) : data.getSuffix(); // 如果没有称号数据 if (prefix.isEmpty() && suffix.isEmpty()) { + unloadData(targetPlayer); return; } - - for (Player _player : Bukkit.getOnlinePlayers()) { - Scoreboard scoreboard = _player.getScoreboard(); - if (scoreboard == null) { - _player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); - } - Team team = scoreboard.getTeam(player.getName()); - if (team == null) { - team = scoreboard.registerNewTeam(player.getName()); - team.addEntry(player.getName()); - } + for (Player player : Bukkit.getOnlinePlayers()) { + Scoreboard scoreboard = getScoreboard(player); + Team team = getTeam(scoreboard, data); team.setPrefix(prefix); team.setSuffix(suffix); } @@ -141,28 +135,19 @@ public class TagManager implements Listener { /** * 下载服务器内的称号数据到该玩家 * - * @param player 玩家 + * @param targetPlayer 玩家 */ - public void downloadData(Player player) { - Scoreboard scoreboard = player.getScoreboard(); - if (scoreboard == null) { - player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); - } - - for (Player _player : Bukkit.getOnlinePlayers()) { - PlayerData data = getPlayerData(_player); + public void downloadData(Player targetPlayer) { + Scoreboard scoreboard = getScoreboard(targetPlayer); + for (Player player : Bukkit.getOnlinePlayers()) { + PlayerData data = getPlayerData(player); String prefix = data.getPrefix().length() > 16 ? data.getPrefix().substring(0, 16) : data.getPrefix(); String suffix = data.getSuffix().length() > 16 ? data.getSuffix().substring(0, 16) : data.getSuffix(); // 如果没有称号数据 if (prefix.isEmpty() && suffix.isEmpty()) { continue; } - - Team team = scoreboard.getTeam(_player.getName()); - if (team == null) { - team = scoreboard.registerNewTeam(_player.getName()); - team.addEntry(_player.getName()); - } + Team team = getTeam(scoreboard, data); team.setPrefix(prefix); team.setSuffix(suffix); } @@ -175,25 +160,52 @@ public class TagManager implements Listener { @EventHandler public void onQuit(PlayerQuitEvent e) { - removeData(e.getPlayer()); + unloadData(e.getPlayer()); + } + + private Scoreboard getScoreboard(Player player) { + Scoreboard scoreboard = player.getScoreboard(); + if (scoreboard == null) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + return scoreboard; + } + + private Team getTeam(Scoreboard scoreboard, PlayerData data) { + Team team = scoreboard.getTeam(data.getName()); + if (team == null) { + team = scoreboard.registerNewTeam(data.getName()); + team.addEntry(data.getName()); + } + return team; } static class PlayerData { + private UUID uuid; private String name; private String prefix; private String suffix; - public PlayerData(String name) { - this.name = name; + public PlayerData(Player player) { + this.uuid = player.getUniqueId(); + this.name = player.getName(); this.prefix = ""; this.suffix = ""; } + public UUID getUuid() { + return uuid; + } + public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public String getPrefix() { return prefix; } @@ -209,5 +221,14 @@ public class TagManager implements Listener { public void setSuffix(String suffix) { this.suffix = suffix; } + + public boolean isEmpty() { + return Strings.isEmpty(suffix) && Strings.isEmpty(prefix); + } + + public void reset() { + prefix = ""; + suffix = ""; + } } } diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java index f6f1b06..2c130e1 100644 --- a/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java +++ b/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java @@ -161,7 +161,7 @@ public class TLMInvCommand extends SubCommand { } // 覆盖背包 - moduleInventorySave.pasteInventory(player, args[2], args.length > 4 ? args[3] : "null"); + moduleInventorySave.pasteInventory(player, args[2], args.length > 4 ? args[4] : "null"); // 如果是玩家 if (sender instanceof Player) { diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 955f797..9bff7dd 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -30,8 +30,24 @@ CONFIG: RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载' LISTEN-START: '开始监听 {0} 插件的 {1} 配置文件' +NOTIFY: + ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!' + ERROR-CONNECTION-FALL: '&4数据库连接失败, 请检查配置是否正确!' + SUCCESS-LOADED: + - '§7插件载入完成!' + - '§7插件作者: §f{0}' + - '§7插件版本: §f{1}' + - '§7游戏版本: §f{2}' + SUCCESS-DISABLE: + - '&c插件已卸载, 感谢您使用&4禁忌书库' + - '&c插件作者: &4坏黑' + FALL-DISABLE: + - '&c插件尚未启动完成, 已跳过卸载代码' + - '&c插件作者: &4坏黑' + LOCALE: TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}' + PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}' MISC: FIELD-COPY-FAILED: '拷贝 {0} 对象失败' @@ -137,7 +153,7 @@ COMMANDS: SUCCESS-NORMAL: '&8[&3&lTabooLib&8] &7重载成功' SUCCESS-ELAPSED-TIME: '&8[&3&lTabooLib&8] &7重载成功, 耗时: &f{0} ms' TABOOLIB: - COMMAND-TITLE: '&b&l----- &3&lTabooLib Commands &b&l-----' + COMMAND-TITLE: '&e&l----- &6&lTabooLib Commands &e&l-----' SAVE: DESCRIPTION: '载入插件' ARGUMENTS: @@ -399,7 +415,7 @@ COMMANDS: SUCCESS-SEND: '&8[&3&lTabooLib&8] &7信息已发送, 耗时&f: {0}' HELP: - '' - - '&b&l----- &3&lLanguage2 Commands &b&l-----' + - '&e&l----- &6&lLanguage2 Commands &e&l-----' - '' - '&f /{0} send &8[&7玩家/ALL&8] &8[&7语言&8] &8<&7变量&8> &6- &e发送语言提示' - '&f /{0} reload &6- &e重载语言库' @@ -416,7 +432,7 @@ COMMANDS: - '&f /{0} reload &6- &e重载语言库' - '' TPLUGIN: - COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &b&l-----' + COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &e&l-----' LIST: DESCRIPTION: '列出插件' LIST-PLUGIN: