# Conflicts:
#	src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java
This commit is contained in:
Izzel_Aliz 2018-05-13 22:45:43 +08:00
commit 737c589c5a
33 changed files with 592 additions and 366 deletions

View File

@ -26,7 +26,6 @@
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-core-asl:1.9.13" level="project" /> <orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-core-asl:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-mapper-asl:1.9.13" level="project" /> <orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-mapper-asl:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.javalite:app-config:2.0" level="project" /> <orderEntry type="library" name="Maven: org.javalite:app-config:2.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
<orderEntry type="library" name="Maven: com.h2database:h2:1.4.197" level="project" /> <orderEntry type="library" name="Maven: com.h2database:h2:1.4.197" level="project" />
<orderEntry type="library" name="Maven: com.ilummc.eagletdl:EagletCore:1.1.2" level="project" /> <orderEntry type="library" name="Maven: com.ilummc.eagletdl:EagletCore:1.1.2" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:6.1.1" level="project" /> <orderEntry type="library" name="Maven: org.ow2.asm:asm:6.1.1" level="project" />

View File

@ -6,7 +6,7 @@
<groupId>me.skymc</groupId> <groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId> <artifactId>TabooLib</artifactId>
<version>4.0</version> <version>4.01</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -1,17 +1,20 @@
package com.ilummc.tlib.resources; package com.ilummc.tlib.resources;
import com.ilummc.tlib.TLib; import com.ilummc.tlib.TLib;
import com.ilummc.tlib.bungee.api.ChatColor;
import com.ilummc.tlib.inject.TLoggerManager; import com.ilummc.tlib.inject.TLoggerManager;
import com.ilummc.tlib.util.Ref; import com.ilummc.tlib.util.Ref;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; 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.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class TLocale { public class TLocale {
@ -20,15 +23,15 @@ public class TLocale {
} }
static String asString(String path, Class<?> callerClass, String... args) { 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<String> asStringList(String path, Class<?> callerClass, String... args) { static List<String> 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) { 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) { public static void sendToConsole(String path, String... args) {
@ -45,7 +48,7 @@ public class TLocale {
public static String asString(String path, String... args) { public static String asString(String path, String... args) {
try { try {
return asString(path, Ref.getCallerClassNotOptional(3), args); return asString(path, Ref.getCallerClass(3).orElse(Main.class), args);
} catch (Exception e) { } 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("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage())); TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage()));
@ -55,7 +58,7 @@ public class TLocale {
public static List<String> asStringList(String path, String... args) { public static List<String> asStringList(String path, String... args) {
try { try {
return asStringList(path, Ref.getCallerClassNotOptional(3), args); return asStringList(path, Ref.getCallerClass(3).orElse(Main.class), args);
} catch (Exception e) { } 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("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage())); 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() { 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) { public static final class Translate extends TLocale {
try {
Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); public static boolean isPlaceholderUseDefault() {
pluginField.setAccessible(true); return Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false);
return (JavaPlugin) pluginField.get(callerClass.getClassLoader()); }
} catch (Exception ignored) {
TLib.getTLib().getLogger().error("无效的语言文件发送形式: &4" + callerClass.getName()); 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<String> setColored(List<String> 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<String> setPlaceholders(CommandSender sender, List<String> 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 final class Logger extends TLocale {
public static void info(String path, String... args) { 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) { 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) { 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) { 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) { 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) { 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) { 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)));
} }
} }

View File

@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import com.ilummc.tlib.TLib; import com.ilummc.tlib.TLib;
import com.ilummc.tlib.resources.type.TLocaleText; import com.ilummc.tlib.resources.type.TLocaleText;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.TabooLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -11,19 +12,17 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import java.util.Collections; import java.util.*;
import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ThreadSafe @ThreadSafe
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
class TLocaleInstance { class TLocaleInstance {
private final Map<String, List<TLocaleSendable>> map = new HashMap<>(); private final Map<String, List<TLocaleSerialize>> map = new HashMap<>();
private final Plugin plugin; private final Plugin plugin;
private final AtomicInteger latestUpdateNodes = new AtomicInteger();
TLocaleInstance(Plugin plugin) { TLocaleInstance(Plugin plugin) {
this.plugin = plugin; this.plugin = plugin;
@ -38,7 +37,7 @@ class TLocaleInstance {
return map.size(); return map.size();
} }
public Map<String, List<TLocaleSendable>> getMap() { public Map<String, List<TLocaleSerialize>> getMap() {
return map; return map;
} }
@ -46,58 +45,71 @@ class TLocaleInstance {
return plugin; return plugin;
} }
public AtomicInteger getLatestUpdateNodes() {
return latestUpdateNodes;
}
public void sendTo(String path, CommandSender sender, String... args) { public void sendTo(String path, CommandSender sender, String... args) {
try { try {
map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).forEach(sendable -> { map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).forEach(tSender -> {
if (Bukkit.isPrimaryThread()) { if (Bukkit.isPrimaryThread()) {
sendable.sendTo(sender, args); tSender.sendTo(sender, args);
} else { } else {
Bukkit.getScheduler().runTask(plugin, () -> sendable.sendTo(sender, args)); Bukkit.getScheduler().runTask(plugin, () -> tSender.sendTo(sender, args));
} }
}); });
} catch (Exception | Error e) { } 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("SEND-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.toString())); TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.toString()));
e.printStackTrace();
} }
} }
public String asString(String path, String... args) { 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<String> asStringList(String path, String... args) { public List<String> 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<Object, TLocaleSendable> 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) { private static boolean isListString(List list) {
for (Object o : list) { for (Object o : list) {
if (!(o instanceof String)) return false; if (!(o instanceof String)) {
return false;
}
} }
return true; return true;
} }
public void load(YamlConfiguration configuration) { public void load(YamlConfiguration configuration) {
configuration.getKeys(true).forEach(s -> { load(configuration, false);
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)));
} }
});
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);
} }
} }

View File

@ -1,25 +1,22 @@
package com.ilummc.tlib.resources; package com.ilummc.tlib.resources;
import com.google.common.io.Files;
import com.ilummc.tlib.TLib; import com.ilummc.tlib.TLib;
import com.ilummc.tlib.annotations.TLocalePlugin; import com.ilummc.tlib.annotations.TLocalePlugin;
import com.ilummc.tlib.logger.TLogger; import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.type.*; import com.ilummc.tlib.resources.type.*;
import com.ilummc.tlib.util.IO; import com.ilummc.tlib.util.IO;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.skymc.taboocode.TabooCodeLang;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.other.NumberUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerialization; 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.Yaml;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.*; import java.util.*;
@ -38,6 +35,7 @@ public class TLocaleLoader {
} }
public static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) { 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()) { if (Bukkit.isPrimaryThread()) {
Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args)); Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args));
} else { } else {
@ -48,6 +46,7 @@ public class TLocaleLoader {
} }
public static String asString(Plugin plugin, String path, String... args) { 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()); TLocaleInstance tLocaleInstance = map.get(plugin.getName());
if (tLocaleInstance != null) { if (tLocaleInstance != null) {
return tLocaleInstance.asString(path, args); return tLocaleInstance.asString(path, args);
@ -57,6 +56,7 @@ public class TLocaleLoader {
} }
public static List<String> asStringList(Plugin plugin, String path, String... args) { public static List<String> 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()); TLocaleInstance tLocaleInstance = map.get(plugin.getName());
if (tLocaleInstance != null) { if (tLocaleInstance != null) {
return tLocaleInstance.asStringList(path, args); return tLocaleInstance.asStringList(path, args);
@ -76,20 +76,23 @@ public class TLocaleLoader {
if (isLoadLocale(plugin, isCover)) { if (isLoadLocale(plugin, isCover)) {
// 获取文件 // 获取文件
File localeFile = getLocaleFile(plugin); File localeFile = getLocaleFile(plugin);
if (localeFile == null) {
return;
}
// 加载文件 // 加载文件
infoLogger("TRY-LOADING-LANG", plugin.getName(), localeFile.getName()); infoLogger("TRY-LOADING-LANG", plugin.getName(), localeFile.getName());
Map<String, Object> originMap = getLocaleAtStream(plugin, localeFile); YamlConfiguration localeConfiguration = ConfigUtils.loadYaml(plugin, localeFile);
YamlConfiguration localeConfigurationAtStream = getLocaleAtStream(plugin, localeFile);
TLib.getTLib().getConfigWatcher().removeListener(localeFile);
// 载入配置 // 载入配置
updateAndLoad(plugin, localeFile, originMap); loadPluginLocale(plugin, localeFile, localeConfiguration, localeConfigurationAtStream);
// 注册监听 // 注册监听
TLib.getTLib().getConfigWatcher().removeListener(localeFile);
TLib.getTLib().getConfigWatcher().addListener(localeFile, null, obj -> { TLib.getTLib().getConfigWatcher().addListener(localeFile, null, obj -> {
infoLogger("RELOADING-LANG", plugin.getName()); infoLogger("RELOADING-LANG", plugin.getName());
updateAndLoad(plugin, localeFile, getLocaleAtStream(plugin, localeFile)); loadPluginLocale(plugin, localeFile, ConfigUtils.loadYaml(plugin, localeFile), getLocaleAtStream(plugin, localeFile));
}); });
} }
} catch (Exception e) { } 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<String> 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) { private static boolean isLoadLocale(Plugin plugin, boolean isCover) {
return (isCover || !isLocaleLoaded(plugin)) && (plugin.equals(Main.getInst()) || isDependWithTabooLib(plugin)); 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)); 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) { private static File getLocaleFile(Plugin plugin) {
releaseLocales(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) { 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)); 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<String> getLocalePriority() {
return Main.getInst().getConfig().contains("LOCALE.PRIORITY") ? Main.getInst().getConfig().getStringList("LOCALE.PRIORITY") : Collections.singletonList("zh_CN");
}
private static TLocaleInstance getLocaleInstance(Plugin plugin) { private static TLocaleInstance getLocaleInstance(Plugin plugin) {
TLocaleInstance instance = new TLocaleInstance(plugin); TLocaleInstance instance = new TLocaleInstance(plugin);
map.put(plugin.getName(), instance); map.put(plugin.getName(), instance);
return instance; return instance;
} }
private static Map<String, Object> getLocaleAtStream(Plugin plugin, File localeFile) { private static YamlConfiguration getLocaleAtStream(Plugin plugin, File localeFile) {
InputStream localeInputSteam = plugin.getClass().getResourceAsStream("/lang/" + localeFile.getName()); InputStream localeInputSteam = plugin.getClass().getResourceAsStream("/lang/" + localeFile.getName());
try { try {
String yamlText = new String(IO.readFully(localeInputSteam), Charset.forName("utf-8")); String yamlText = new String(IO.readFully(localeInputSteam), Charset.forName("utf-8"));
Object load = new Yaml().load(yamlText); YamlConfiguration yaml = new YamlConfiguration();
return load instanceof Map ? (Map<String, Object>) load : new HashMap<>(0); yaml.loadFromString(yamlText);
} catch (Exception e) { return yaml;
return new HashMap<>(0); } catch (Exception ignored) {
return null;
} }
} }
private static Map<String, Object> currentLocaleMap(File localeFile) { private static void loadPluginLocale(Plugin plugin, File localeFile, YamlConfiguration localeConfiguration, YamlConfiguration localeConfigurationAtStream) {
try {
Object load = new Yaml().load(Files.toString(localeFile, Charset.forName("utf-8")));
return load instanceof Map ? (Map<String, Object>) load : new HashMap<>(0);
} catch (Exception e) {
return new HashMap<>(0);
}
}
private static int compareAndSet(Map<String, Object> origin, Map<String, Object> 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<String, Object> origin, Map<String, Object> current) {
int res = 0;
for (Map.Entry<String, Object> 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<String, Object>) entry.getValue(), (Map<String, Object>) current.get(entry.getKey()));
}
} else ++res;
}
return res;
}
private static void updateAndLoad(Plugin plugin, File localeFile, Map<String, Object> originMap) {
Map<String, Object> currentMap = currentLocaleMap(localeFile);
int update = compareAndSet(originMap, currentMap, localeFile);
TLocaleInstance localeInstance = getLocaleInstance(plugin); TLocaleInstance localeInstance = getLocaleInstance(plugin);
YamlConfiguration localeConfiguration = (YamlConfiguration) ConfigUtils.mapToConf(currentMap); if (localeConfigurationAtStream != null) {
localeInstance.load(localeConfigurationAtStream);
}
localeInstance.load(localeConfiguration); 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())); infoLogger("SUCCESS-LOADING-LANG-NORMAL", plugin.getName(), localeFile.getName().split("\\.")[0], String.valueOf(localeInstance.size()));
} else { } 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()));
} }
} }
} }

View File

@ -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<String> asStringList(String... args) {
return Collections.singletonList("§4<" + path + "§4>");
}
};
}
void sendTo(CommandSender sender, String... args);
default String asString(String... args) {
return "";
}
default List<String> asStringList(String... args) {
return Collections.emptyList();
}
}

View File

@ -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<String> asStringList(String... args);
}

View File

@ -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<String, Object> 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<String, Object> map, String path, String def) {
Object var = map.getOrDefault(path, def);
return var instanceof String ? (String) var : def;
}
public static Integer getIntegerOrDefault(Map<String, Object> map, String path, Integer def) {
Object var = map.getOrDefault(path, def);
return var instanceof Integer ? (Integer) var : def;
}
public static Double getDoubleOrDefault(Map<String, Object> 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<String, Object> serialize() {
return null;
}
};
}
static TLocaleSerialize getEmpty(String path) {
return new TLocaleSerialize() {
@Override
public Map<String, Object> 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<String> asStringList(String... args) {
return Collections.singletonList("§4<" + path + "§4>");
}
};
}
@Override
public String asString(String... args) {
return "";
}
@Override
public List<String> asStringList(String... args) {
return Collections.emptyList();
}
}

View File

@ -3,12 +3,11 @@ package com.ilummc.tlib.resources.type;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.ilummc.tlib.compat.PlaceholderHook; import com.ilummc.tlib.compat.PlaceholderHook;
import com.ilummc.tlib.nms.ActionBar; 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 com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -17,7 +16,7 @@ import java.util.Map;
@Immutable @Immutable
@SerializableAs("ACTION") @SerializableAs("ACTION")
public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializable { public class TLocaleActionBar extends TLocaleSerialize {
private final String text; private final String text;
private final boolean papi; private final boolean papi;
@ -29,8 +28,7 @@ public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializa
public static TLocaleActionBar valueOf(Map<String, Object> map) { public static TLocaleActionBar valueOf(Map<String, Object> map) {
String text = ChatColor.translateAlternateColorCodes('&', String.valueOf(map.getOrDefault("text", "Empty Action bar message."))); 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, isPlaceholderEnabled(map));
return new TLocaleActionBar(text, papi);
} }
@Override @Override

View File

@ -7,13 +7,11 @@ import com.ilummc.tlib.TLib;
import com.ilummc.tlib.bungee.api.chat.*; import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer; import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.compat.PlaceholderHook; 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 com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.jsonformatter.JSONFormatter;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -25,7 +23,7 @@ import java.util.stream.Collectors;
@ThreadSafe @ThreadSafe
@SerializableAs("JSON") @SerializableAs("JSON")
public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { public class TLocaleJson extends TLocaleSerialize {
private static final Pattern pattern = Pattern.compile("<([^<>]*)?@([^<>]*)>"); private static final Pattern pattern = Pattern.compile("<([^<>]*)?@([^<>]*)>");
private final List<BaseComponent[]> components; private final List<BaseComponent[]> components;
@ -39,9 +37,6 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
} }
public static TLocaleJson valueOf(Map<String, Object> map) { public static TLocaleJson valueOf(Map<String, Object> map) {
boolean papi = (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false));
// text 里面的东西
List<String> textList = getTextList(map.getOrDefault("text", "Empty Node")); List<String> textList = getTextList(map.getOrDefault("text", "Empty Node"));
// 分析 args 并替换 // 分析 args 并替换
@ -73,7 +68,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
// 如果 args 有这个 xxx // 如果 args 有这个 xxx
if (section.containsKey(node)) { if (section.containsKey(node)) {
Map<String, Object> arg = (Map<String, Object>) section.get(node); Map<String, Object> arg = (Map<String, Object>) 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 单独设置各种事件
BaseComponent[] component = TextComponent.fromLegacyText(text); BaseComponent[] component = TextComponent.fromLegacyText(text);
arg.forEach((key, value) -> { arg.forEach((key, value) -> {
@ -82,7 +77,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
} else if ("command".equalsIgnoreCase(key) || "commands".equalsIgnoreCase(key)) { } else if ("command".equalsIgnoreCase(key) || "commands".equalsIgnoreCase(key)) {
Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.valueOf(value)))); Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.valueOf(value))));
} else if ("hover".equalsIgnoreCase(key)) { } 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 里面 // 添加到原来的 list 里面
@ -99,16 +94,16 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
} }
return builder.toArray(new BaseComponent[0]); return builder.toArray(new BaseComponent[0]);
}).collect(Collectors.toList()); }).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<String> getTextList(Object textObj) { private static List<String> getTextList(Object textObj) {
if (textObj instanceof List) { 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) { } else if (textObj instanceof String) {
return Lists.newArrayList(ChatColor.translateAlternateColorCodes('&', (String) textObj)); return Lists.newArrayList(TLocale.Translate.setColored((String) textObj));
} else { } else {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -1,10 +1,9 @@
package com.ilummc.tlib.resources.type; package com.ilummc.tlib.resources.type;
import com.google.common.collect.Maps; 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 me.skymc.taboolib.sound.SoundPack;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -20,7 +19,7 @@ import java.util.stream.Collectors;
*/ */
@Immutable @Immutable
@SerializableAs("ACTION") @SerializableAs("ACTION")
public class TLocaleSound implements TLocaleSendable, ConfigurationSerializable { public class TLocaleSound extends TLocaleSerialize {
private final List<SoundPack> soundPacks; private final List<SoundPack> soundPacks;

View File

@ -4,12 +4,11 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.ilummc.tlib.compat.PlaceholderHook; 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 com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
@ -19,7 +18,7 @@ import java.util.stream.Collectors;
@Immutable @Immutable
@SerializableAs("TEXT") @SerializableAs("TEXT")
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public class TLocaleText implements TLocaleSendable, ConfigurationSerializable { public class TLocaleText extends TLocaleSerialize {
private final Object text; private final Object text;
private final boolean usePlaceholder; 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<String, Object> 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<String>) 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) { 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) { public static TLocaleText of(Object o) {
return o instanceof String ? of(((String) o)) : new TLocaleText(o, false); return o instanceof String ? of(((String) o)) : new TLocaleText(o, false);
} }
public static TLocaleText valueOf(Map<String, Object> 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 @Override
public void sendTo(CommandSender sender, String... args) { public void sendTo(CommandSender sender, String... args) {
if (text instanceof String) { 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) { } 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 @Override
public String asString(String... args) { public String asString(String... args) {
return Strings.replaceWithOrder(objectToString(text), args); return Strings.replaceWithOrder(TLocale.Translate.setColored(objectToString(text)), args);
} }
@Override @Override
public List<String> asStringList(String... args) { public List<String> asStringList(String... args) {
if (text instanceof String) { if (text instanceof List) {
return Collections.singletonList(((String) text)); return ((List<String>) text).stream().map(x -> Strings.replaceWithOrder(TLocale.Translate.setColored(x), args)).collect(Collectors.toList());
} else { } else {
return ((List<String>) text); return Collections.singletonList(asString(args));
}
}
private String objectToString(Object text) {
if (text instanceof String) {
return ((String) text);
} else {
StringJoiner joiner = new StringJoiner("\n");
((List<String>) text).forEach(joiner::add);
return joiner.toString();
} }
} }
@ -111,9 +88,20 @@ public class TLocaleText implements TLocaleSendable, ConfigurationSerializable {
@Override @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {
if (usePlaceholder) { return usePlaceholder ? Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)) : Maps.newHashMap(ImmutableMap.of("text", text));
return Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)); }
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<String>) text).forEach(joiner::add);
return joiner.toString();
} }
return Maps.newHashMap(ImmutableMap.of("text", text));
} }
} }

View File

@ -1,15 +1,11 @@
package com.ilummc.tlib.resources.type; package com.ilummc.tlib.resources.type;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.ilummc.tlib.compat.PlaceholderHook;
import com.ilummc.tlib.resources.TLocale; 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 com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.display.TitleUtils; import me.skymc.taboolib.display.TitleUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -24,7 +20,7 @@ import java.util.Map;
@Immutable @Immutable
@SerializableAs("TITLE") @SerializableAs("TITLE")
public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable { public class TLocaleTitle extends TLocaleSerialize {
private final String title; private final String title;
private final String subtitle; private final String subtitle;
@ -47,12 +43,12 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable
TLocaleTitle title; TLocaleTitle title;
try { try {
title = new TLocaleTitle( title = new TLocaleTitle(
(String) map.getOrDefault("title", ""), getStringOrDefault(map, "title", ""),
(String) map.getOrDefault("subtitle", ""), getStringOrDefault(map, "subtitle", ""),
(int) map.getOrDefault("fadein", 10), getIntegerOrDefault(map, "fadein", 10),
(int) map.getOrDefault("fadeout", 10), getIntegerOrDefault(map, "fadeout", 10),
(int) map.getOrDefault("stay", 20), getIntegerOrDefault(map, "stay", 10),
(boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false))); isPlaceholderEnabled(map));
} catch (Exception e) { } catch (Exception e) {
title = new TLocaleTitle("Empty Title message.", e.getMessage(), 10, 20, 10, false); title = new TLocaleTitle("Empty Title message.", e.getMessage(), 10, 20, 10, false);
} }
@ -70,7 +66,7 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable
@Override @Override
public String asString(String... args) { 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 @Override
@ -90,7 +86,7 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable
return map; return map;
} }
private String replaceText(CommandSender sender, String s) { private String replaceText(CommandSender sender, String args) {
return ChatColor.translateAlternateColorCodes('&', usePlaceholder ? PlaceholderHook.replace(sender, s) : s); return usePlaceholder ? TLocale.Translate.setPlaceholders(sender, args) : TLocale.Translate.setColored(args);
} }
} }

View File

@ -2,7 +2,10 @@ package com.ilummc.tlib.util;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.ilummc.tlib.TLib; import com.ilummc.tlib.TLib;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.util.asm.AsmAnalyser; 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.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import sun.reflect.Reflection; import sun.reflect.Reflection;
@ -96,6 +99,17 @@ public class Ref {
return Optional.empty(); 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 abstract class CallerClass {
private static CallerClass impl; private static CallerClass impl;

View File

@ -27,4 +27,16 @@ public class Strings {
} }
return stringBuilder.toString(); 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;
}
} }

View File

@ -1,6 +1,8 @@
package me.skymc.taboolib; package me.skymc.taboolib;
import com.ilummc.tlib.TLib; 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.anvil.AnvilContainerAPI;
import me.skymc.taboolib.bstats.Metrics; import me.skymc.taboolib.bstats.Metrics;
import me.skymc.taboolib.commands.TabooLibMainCommand; 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.mysql.protect.MySQLConnection;
import me.skymc.taboolib.nms.item.DabItemUtils; import me.skymc.taboolib.nms.item.DabItemUtils;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.packet.PacketUtils;
import me.skymc.taboolib.permission.PermissionUtils; import me.skymc.taboolib.permission.PermissionUtils;
import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.playerdata.DataUtils;
import me.skymc.taboolib.sign.SignUtils; 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(); String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString();
// 如果这个值和我的值不同 // 如果这个值和我的值不同
if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) { if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) {
MsgUtils.warn("检测到本服序列号与其他服务器相同, 已重新生成!"); TLocale.Logger.error("NOTIFY.ERROR-SERVER-KEY");
// 重新生成序列号 // 重新生成序列号
TabooLib.resetServerUID(); TabooLib.resetServerUID();
// 关服 // 关服
@ -188,7 +191,7 @@ public class Main extends JavaPlugin implements Listener {
} }
} else { } else {
// 提示 // 提示
MsgUtils.warn("数据库连接失败, 请检查配置是否正确!"); TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FALL");
// 关服 // 关服
Bukkit.shutdown(); Bukkit.shutdown();
} }
@ -223,12 +226,10 @@ public class Main extends JavaPlugin implements Listener {
TimeCycleManager.load(); TimeCycleManager.load();
// 启动脚本 // 启动脚本
JavaShell.javaShellSetup(); JavaShell.javaShellSetup();
// 载入语言文件
exampleLanguage2 = new Language2("Language2", this);
// 注册脚本 // 注册脚本
SkriptHandler.getInst(); SkriptHandler.getInst();
// 注册昵称 // 载入语言文件
TagAPI.inst(); exampleLanguage2 = new Language2("Language2", this);
// 启动数据库储存方法 // 启动数据库储存方法
if (getStorageType() == StorageType.SQL) { if (getStorageType() == StorageType.SQL) {
@ -236,14 +237,16 @@ public class Main extends JavaPlugin implements Listener {
} }
// 载入完成 // 载入完成
MsgUtils.send("§7插件载入完成!"); TLocale.Logger.info("NOTIFY.SUCCESS-LOADED", getDescription().getAuthors().toString(), getDescription().getVersion(), String.valueOf(TabooLib.getVersion()));
MsgUtils.send("§7插件版本: §f" + getDescription().getVersion());
MsgUtils.send("§7插件作者: §f" + getDescription().getAuthors());
MsgUtils.send("§7游戏版本: §f" + TabooLib.getVerint());
// 文件保存 // 文件保存
Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120); Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120);
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60); 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() { new BukkitRunnable() {
@ -253,6 +256,9 @@ public class Main extends JavaPlugin implements Listener {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new SupportPlaceholder(getInst(), "taboolib").hook(); new SupportPlaceholder(getInst(), "taboolib").hook();
} }
if (PacketUtils.isProtocolLibEnabled()) {
TagAPI.inst();
}
// 载入 SpecialItem 接口 // 载入 SpecialItem 接口
SpecialItem.getInst().loadItems(); SpecialItem.getInst().loadItems();
// 载入 TLM 接口 // 载入 TLM 接口
@ -275,8 +281,7 @@ public class Main extends JavaPlugin implements Listener {
// 如果插件尚未启动完成 // 如果插件尚未启动完成
if (!started) { if (!started) {
MsgUtils.send("&c插件尚未启动完成, 已跳过卸载代码"); TLocale.Logger.error("NOTIFY.FALL-DISABLE");
MsgUtils.send("&c插件作者: &4坏黑");
return; return;
} }
@ -310,8 +315,7 @@ public class Main extends JavaPlugin implements Listener {
} }
// 提示信息 // 提示信息
MsgUtils.send("&c插件已卸载, 感谢您使用&4禁忌书库"); TLocale.Logger.error("NOTIFY.SUCCESS-DISABLE");
MsgUtils.send("&c插件作者: &4坏黑");
// 清理头衔 // 清理头衔
TagUtils.delete(); TagUtils.delete();

View File

@ -10,6 +10,10 @@ import java.util.UUID;
public class TabooLib { public class TabooLib {
public static boolean isDebug() {
return Main.getInst().getConfig().getBoolean("DEBUG");
}
public static void debug(Plugin plugin, String... args) { public static void debug(Plugin plugin, String... args) {
if (Main.getInst().getConfig().getBoolean("DEBUG")) { if (Main.getInst().getConfig().getBoolean("DEBUG")) {
Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var)); Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var));

View File

@ -1,8 +1,6 @@
package me.skymc.taboolib.anvil; package me.skymc.taboolib.anvil;
import com.ilummc.tlib.util.asm.AsmClassTransformer;
import me.skymc.taboolib.nms.NMSUtils; import me.skymc.taboolib.nms.NMSUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**

View File

@ -46,7 +46,7 @@ public class AnvilContainerAPI implements Listener {
meta.setDisplayName(str); meta.setDisplayName(str);
item.setItemMeta(meta); item.setItemMeta(meta);
p.getOpenInventory().setItem(0, item); p.getOpenInventory().getTopInventory().setItem(0, item);
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1); p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1);
} }

View File

@ -106,10 +106,41 @@ public class TabooLibMainCommand extends BaseMainCommand {
return new CommandArgument[0]; 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 @Override
public void onCommand(CommandSender sender, Command command, String label, String[] args) { public void onCommand(CommandSender sender, Command command, String label, String[] args) {
new ItemListCommand(sender, args); new ItemListCommand(sender, args);
} }
@Override
public boolean ignoredLabel() {
return false;
}
}); });
} }

View File

@ -2,6 +2,8 @@ package me.skymc.taboolib.commands.internal;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.ilummc.tlib.resources.TLocale; 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.Main;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.internal.type.CommandRegister; 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 me.skymc.taboolib.string.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.*; import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -35,6 +40,7 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
baseMainCommand.getRegisterCommand().setExecutor(baseMainCommand); baseMainCommand.getRegisterCommand().setExecutor(baseMainCommand);
baseMainCommand.getRegisterCommand().setTabCompleter(baseMainCommand); baseMainCommand.getRegisterCommand().setTabCompleter(baseMainCommand);
baseMainCommand.getLinkClasses().add(baseMainCommand.getClass()); baseMainCommand.getLinkClasses().add(baseMainCommand.getClass());
baseMainCommand.disguisedPlugin();
loadCommandRegister(baseMainCommand); loadCommandRegister(baseMainCommand);
return baseMainCommand; return baseMainCommand;
} }
@ -149,7 +155,7 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
} }
private boolean isConfirmType(CommandSender sender, CommandType commandType) { 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) { 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); subCommands.stream().map(subCommand -> subCommand == null ? getEmptyLine() : subCommand.getCommandString(label)).forEach(sender::sendMessage);
sender.sendMessage(getEmptyLine()); 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) {
}
}
} }

View File

@ -4,6 +4,7 @@ import com.google.common.base.Joiner;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseMainCommand;
import me.skymc.taboolib.commands.internal.BaseSubCommand; 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.commands.internal.type.CommandArgument;
import me.skymc.taboolib.plugin.PluginUtils; import me.skymc.taboolib.plugin.PluginUtils;
import me.skymc.taboolib.string.ArrayUtils; import me.skymc.taboolib.string.ArrayUtils;
@ -12,6 +13,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,6 +32,21 @@ public class TabooLibPluginMainCommand extends BaseMainCommand {
reloadCommand(); reloadCommand();
} }
@Override
public List<String> 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 @Override
public String getCommandTitle() { public String getCommandTitle() {
return TLocale.asString("COMMANDS.TPLUGIN.COMMAND-TITLE"); return TLocale.asString("COMMANDS.TPLUGIN.COMMAND-TITLE");

View File

@ -19,7 +19,7 @@ public class InfoCommand extends SubCommand {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.INVALID-ITEM"); TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.INVALID-ITEM");
} else { } else {
NBTItem nbt = new NBTItem(player.getItemInHand()); 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(), player.getItemInHand().getType().name(),
ItemUtils.getCustomName(player.getItemInHand()), ItemUtils.getCustomName(player.getItemInHand()),
player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(), player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(),

View File

@ -27,12 +27,11 @@ public class TagDeleteCommand extends SubCommand {
return; return;
} }
TagManager.getInst().removeData(player); TagManager.getInst().unloadData(player);
TagAPI.removePlayerDisplayName(player); TagAPI.removePlayerDisplayName(player);
if (sender instanceof Player) { if (sender instanceof Player) {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DELETE", args[1]); TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DELETE", args[1]);
} }
} }
} }

View File

@ -44,7 +44,13 @@ public class ListenerItemListCommand implements Listener {
if (loop >= (page - 1) * 28) { if (loop >= (page - 1) * 28) {
if (loop < page * 28) { if (loop < page * 28) {
int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 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<String> 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); holder.ITEMS_DATA.put(slot, name);
} else { } else {
break; break;
@ -62,16 +68,6 @@ public class ListenerItemListCommand implements Listener {
player.openInventory(inventory); player.openInventory(inventory);
} }
private static ItemStack getItem(HashMap<String, ItemStack> map, String name) {
ItemStack item = map.get(name).clone();
ItemMeta meta = item.getItemMeta();
List<String> 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 @EventHandler
public void inventoryClick(InventoryClickEvent e) { public void inventoryClick(InventoryClickEvent e) {
if (e.getInventory().getHolder() instanceof ItemLibraryHolder) { if (e.getInventory().getHolder() instanceof ItemLibraryHolder) {

View File

@ -34,13 +34,19 @@ public class ListenerSoundsCommand implements Listener {
SoundLibraryHolder holder = new SoundLibraryHolder(page, search); SoundLibraryHolder holder = new SoundLibraryHolder(page, search);
Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.TITLE", String.valueOf(page))); Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.TITLE", String.valueOf(page)));
List<Sound> soundFilter = Arrays.stream(Sound.values()).filter(sound -> search == null || sound.name().contains(search.toUpperCase())).collect(Collectors.toList()); List<Sound> soundFilter = Arrays.stream(Sound.values()).filter(sound -> search == null || sound.name().contains(search.toUpperCase())).collect(Collectors.toList());
List<String> soundLore = TLocale.asStringList("COMMANDS.TABOOLIB.SOUNDS.MENU.LORE");
int loop = 0; int loop = 0;
for (Sound sound : soundFilter) { for (Sound sound : soundFilter) {
if (loop >= (page - 1) * 28) { if (loop >= (page - 1) * 28) {
if (loop < page * 28) { if (loop < page * 28) {
int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 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); holder.SOUNDS_DATA.put(slot, sound);
} else { } else {
break; break;
@ -62,15 +68,6 @@ public class ListenerSoundsCommand implements Listener {
player.openInventory(inventory); 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 @EventHandler
public void inventoryClick(InventoryClickEvent e) { public void inventoryClick(InventoryClickEvent e) {
if (e.getInventory().getHolder() instanceof SoundLibraryHolder) { if (e.getInventory().getHolder() instanceof SoundLibraryHolder) {

View File

@ -1,22 +1,49 @@
package me.skymc.taboolib.display; 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 org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
/** /**
* @author Bkm016 * @author Bkm016
* @since 2018-04-26 * @since 2018-04-26
*/ */
public class ActionUtils { 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) { public static void send(Player player, String action) {
if (player == null) { if (player == null) {
return; return;
} }
try { try {
ActionBar.sendActionBar(player, action); Object ab = ChatComponentText.getConstructor(String.class).newInstance(action);
} catch (Throwable ignored) { 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) {
} }
} }
} }

View File

@ -2,13 +2,31 @@ package me.skymc.taboolib.packet;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher; 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.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/**
* @author sky
*/
public class PacketUtils { 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) { public static void sendPacketEntityStatus(Entity entity, EntityStatus status, Player... players) {
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
packet.getIntegers().write(0, entity.getEntityId()); packet.getIntegers().write(0, entity.getEntityId());

View File

@ -31,7 +31,7 @@ public class ArrayUtils {
public static String[] removeFirst(String[] args) { public static String[] removeFirst(String[] args) {
if (args.length <= 1) { if (args.length <= 1) {
return null; return new String[0];
} }
List<String> list = asList(args); List<String> list = asList(args);
list.remove(0); list.remove(0);

View File

@ -135,6 +135,7 @@ public class TagAPI implements Listener {
AsyncPlayerReceiveNameTagEvent newEvent = new AsyncPlayerReceiveNameTagEvent(destinationPlayer, namedPlayer, getPlayerDisplayName(namedPlayer), UUID.fromString(builtUUID.toString())); AsyncPlayerReceiveNameTagEvent newEvent = new AsyncPlayerReceiveNameTagEvent(destinationPlayer, namedPlayer, getPlayerDisplayName(namedPlayer), UUID.fromString(builtUUID.toString()));
Bukkit.getServer().getPluginManager().callEvent(newEvent); Bukkit.getServer().getPluginManager().callEvent(newEvent);
updatePlayerTag(namedPlayer, newEvent);
return new WrappedGameProfile(newEvent.getUUID(), newEvent.getTag().substring(0, Math.min(newEvent.getTag().length(), 16))); 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) { public void onQuit(PlayerQuitEvent event) {
entityIdMap.remove(event.getPlayer().getEntityId()); 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);
}
} }

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib.team; package me.skymc.taboolib.team;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -11,6 +12,7 @@ import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID;
/** /**
* @author sky * @author sky
@ -20,7 +22,7 @@ public class TagManager implements Listener {
private static TagManager inst; private static TagManager inst;
private HashMap<String, PlayerData> playerdata = new HashMap<>(); private HashMap<UUID, PlayerData> playerData = new HashMap<>();
private TagManager() { private TagManager() {
Bukkit.getPluginManager().registerEvents(this, Main.getInst()); Bukkit.getPluginManager().registerEvents(this, Main.getInst());
@ -35,8 +37,8 @@ public class TagManager implements Listener {
return inst; return inst;
} }
public HashMap<String, PlayerData> getPlayerdata() { public HashMap<UUID, PlayerData> getPlayerData() {
return playerdata; return playerData;
} }
/** /**
@ -87,52 +89,44 @@ public class TagManager implements Listener {
* @param player 玩家 * @param player 玩家
* @return {@link PlayerData} * @return {@link PlayerData}
*/ */
private PlayerData getPlayerData(Player player) { public PlayerData getPlayerData(Player player) {
return playerdata.computeIfAbsent(player.getName(), k -> new PlayerData(player.getName())); return playerData.computeIfAbsent(player.getUniqueId(), k -> new PlayerData(player));
} }
/** /**
* 删除该玩家的称号数据 * 注销称号数据
* *
* @param player * @param targetPlayer
*/ */
public void removeData(Player player) { public void unloadData(Player targetPlayer) {
playerdata.remove(player.getName()); PlayerData data = getPlayerData(targetPlayer);
for (Player _player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
Scoreboard scoreboard = _player.getScoreboard(); Scoreboard scoreboard = getScoreboard(player);
if (scoreboard != null) { Team team = scoreboard.getTeam(data.getName());
Team team = scoreboard.getTeam(player.getName());
if (team != null) { if (team != null) {
team.unregister(); team.unregister();
} }
} }
} data.reset();
} }
/** /**
* 将该玩家的数据向服务器所有玩家更新 * 将该玩家的数据向服务器所有玩家更新
* *
* @param player 玩家 * @param targetPlayer 玩家
*/ */
public void uploadData(Player player) { public void uploadData(Player targetPlayer) {
PlayerData data = getPlayerData(player); PlayerData data = getPlayerData(targetPlayer);
String prefix = data.getPrefix().length() > 16 ? data.getPrefix().substring(0, 16) : data.getPrefix(); 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(); String suffix = data.getSuffix().length() > 16 ? data.getSuffix().substring(0, 16) : data.getSuffix();
// 如果没有称号数据 // 如果没有称号数据
if (prefix.isEmpty() && suffix.isEmpty()) { if (prefix.isEmpty() && suffix.isEmpty()) {
unloadData(targetPlayer);
return; return;
} }
for (Player player : Bukkit.getOnlinePlayers()) {
for (Player _player : Bukkit.getOnlinePlayers()) { Scoreboard scoreboard = getScoreboard(player);
Scoreboard scoreboard = _player.getScoreboard(); Team team = getTeam(scoreboard, data);
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());
}
team.setPrefix(prefix); team.setPrefix(prefix);
team.setSuffix(suffix); team.setSuffix(suffix);
} }
@ -141,28 +135,19 @@ public class TagManager implements Listener {
/** /**
* 下载服务器内的称号数据到该玩家 * 下载服务器内的称号数据到该玩家
* *
* @param player 玩家 * @param targetPlayer 玩家
*/ */
public void downloadData(Player player) { public void downloadData(Player targetPlayer) {
Scoreboard scoreboard = player.getScoreboard(); Scoreboard scoreboard = getScoreboard(targetPlayer);
if (scoreboard == null) { for (Player player : Bukkit.getOnlinePlayers()) {
player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); PlayerData data = getPlayerData(player);
}
for (Player _player : Bukkit.getOnlinePlayers()) {
PlayerData data = getPlayerData(_player);
String prefix = data.getPrefix().length() > 16 ? data.getPrefix().substring(0, 16) : data.getPrefix(); 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(); String suffix = data.getSuffix().length() > 16 ? data.getSuffix().substring(0, 16) : data.getSuffix();
// 如果没有称号数据 // 如果没有称号数据
if (prefix.isEmpty() && suffix.isEmpty()) { if (prefix.isEmpty() && suffix.isEmpty()) {
continue; continue;
} }
Team team = getTeam(scoreboard, data);
Team team = scoreboard.getTeam(_player.getName());
if (team == null) {
team = scoreboard.registerNewTeam(_player.getName());
team.addEntry(_player.getName());
}
team.setPrefix(prefix); team.setPrefix(prefix);
team.setSuffix(suffix); team.setSuffix(suffix);
} }
@ -175,25 +160,52 @@ public class TagManager implements Listener {
@EventHandler @EventHandler
public void onQuit(PlayerQuitEvent e) { 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 { static class PlayerData {
private UUID uuid;
private String name; private String name;
private String prefix; private String prefix;
private String suffix; private String suffix;
public PlayerData(String name) { public PlayerData(Player player) {
this.name = name; this.uuid = player.getUniqueId();
this.name = player.getName();
this.prefix = ""; this.prefix = "";
this.suffix = ""; this.suffix = "";
} }
public UUID getUuid() {
return uuid;
}
public String getName() { public String getName() {
return name; return name;
} }
public void setName(String name) {
this.name = name;
}
public String getPrefix() { public String getPrefix() {
return prefix; return prefix;
} }
@ -209,5 +221,14 @@ public class TagManager implements Listener {
public void setSuffix(String suffix) { public void setSuffix(String suffix) {
this.suffix = suffix; this.suffix = suffix;
} }
public boolean isEmpty() {
return Strings.isEmpty(suffix) && Strings.isEmpty(prefix);
}
public void reset() {
prefix = "";
suffix = "";
}
} }
} }

View File

@ -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) { if (sender instanceof Player) {

View File

@ -30,8 +30,24 @@ CONFIG:
RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载' RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载'
LISTEN-START: '开始监听 {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: LOCALE:
TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}' TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}'
MISC: MISC:
FIELD-COPY-FAILED: '拷贝 {0} 对象失败' FIELD-COPY-FAILED: '拷贝 {0} 对象失败'
@ -137,7 +153,7 @@ COMMANDS:
SUCCESS-NORMAL: '&8[&3&lTabooLib&8] &7重载成功' SUCCESS-NORMAL: '&8[&3&lTabooLib&8] &7重载成功'
SUCCESS-ELAPSED-TIME: '&8[&3&lTabooLib&8] &7重载成功, 耗时: &f{0} ms' SUCCESS-ELAPSED-TIME: '&8[&3&lTabooLib&8] &7重载成功, 耗时: &f{0} ms'
TABOOLIB: TABOOLIB:
COMMAND-TITLE: '&b&l----- &3&lTabooLib Commands &b&l-----' COMMAND-TITLE: '&e&l----- &6&lTabooLib Commands &e&l-----'
SAVE: SAVE:
DESCRIPTION: '载入插件' DESCRIPTION: '载入插件'
ARGUMENTS: ARGUMENTS:
@ -399,7 +415,7 @@ COMMANDS:
SUCCESS-SEND: '&8[&3&lTabooLib&8] &7信息已发送, 耗时&f: {0}' SUCCESS-SEND: '&8[&3&lTabooLib&8] &7信息已发送, 耗时&f: {0}'
HELP: 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} send &8[&7玩家/ALL&8] &8[&7语言&8] &8<&7变量&8> &6- &e发送语言提示'
- '&f /{0} reload &6- &e重载语言库' - '&f /{0} reload &6- &e重载语言库'
@ -416,7 +432,7 @@ COMMANDS:
- '&f /{0} reload &6- &e重载语言库' - '&f /{0} reload &6- &e重载语言库'
- '' - ''
TPLUGIN: TPLUGIN:
COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &b&l-----' COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &e&l-----'
LIST: LIST:
DESCRIPTION: '列出插件' DESCRIPTION: '列出插件'
LIST-PLUGIN: LIST-PLUGIN: