更新
This commit is contained in:
		@@ -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" />
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							@@ -72,12 +72,6 @@
 | 
				
			|||||||
            <artifactId>activejdbc</artifactId>
 | 
					            <artifactId>activejdbc</artifactId>
 | 
				
			||||||
            <version>2.0</version>
 | 
					            <version>2.0</version>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
        <dependency>
 | 
					 | 
				
			||||||
            <groupId>javax.servlet</groupId>
 | 
					 | 
				
			||||||
            <artifactId>servlet-api</artifactId>
 | 
					 | 
				
			||||||
            <version>2.5</version>
 | 
					 | 
				
			||||||
            <scope>provided</scope>
 | 
					 | 
				
			||||||
        </dependency>
 | 
					 | 
				
			||||||
        <dependency>
 | 
					        <dependency>
 | 
				
			||||||
            <groupId>com.h2database</groupId>
 | 
					            <groupId>com.h2database</groupId>
 | 
				
			||||||
            <artifactId>h2</artifactId>
 | 
					            <artifactId>h2</artifactId>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,8 @@ import java.util.function.Consumer;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class TConfigWatcher {
 | 
					public class TConfigWatcher {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("tconfig-watcher-schedule-pool-%d").daemon(true).build());
 | 
					    private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1,
 | 
				
			||||||
 | 
					            new BasicThreadFactory.Builder().namingPattern("TConfigWatcherService-%d").build());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final Map<WatchService, Triple<File, Object, Consumer<Object>>> map = new HashMap<>();
 | 
					    private final Map<WatchService, Triple<File, Object, Consumer<Object>>> map = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,7 +55,16 @@ public class TConfigWatcher {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public void removeListener(File file) {
 | 
					    public void removeListener(File file) {
 | 
				
			||||||
        synchronized (map) {
 | 
					        synchronized (map) {
 | 
				
			||||||
            map.entrySet().removeIf(entry -> entry.getValue().getLeft().equals(file));
 | 
					            map.entrySet().removeIf(entry -> {
 | 
				
			||||||
 | 
					                if (entry.getValue().getLeft().equals(file)) {
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        entry.getKey().close();
 | 
				
			||||||
 | 
					                    } catch (IOException ignored) {
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,6 @@ import java.util.Collections;
 | 
				
			|||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.concurrent.ConcurrentHashMap;
 | 
					 | 
				
			||||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
					 | 
				
			||||||
import java.util.function.Function;
 | 
					import java.util.function.Function;
 | 
				
			||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,9 +22,8 @@ import java.util.stream.Collectors;
 | 
				
			|||||||
@SuppressWarnings("rawtypes")
 | 
					@SuppressWarnings("rawtypes")
 | 
				
			||||||
class TLocaleInstance {
 | 
					class TLocaleInstance {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final Map<String, List<TLocaleSerialize>> map = new ConcurrentHashMap<>();
 | 
					    private final Map<String, List<TLocaleSerialize>> map = new HashMap<>();
 | 
				
			||||||
    private final Plugin plugin;
 | 
					    private final Plugin plugin;
 | 
				
			||||||
    private final AtomicInteger updateNodes = new AtomicInteger();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TLocaleInstance(Plugin plugin) {
 | 
					    TLocaleInstance(Plugin plugin) {
 | 
				
			||||||
        this.plugin = plugin;
 | 
					        this.plugin = plugin;
 | 
				
			||||||
@@ -49,10 +46,6 @@ class TLocaleInstance {
 | 
				
			|||||||
        return plugin;
 | 
					        return plugin;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int getUpdateNodes() {
 | 
					 | 
				
			||||||
        return updateNodes.get();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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(TLocaleSerialize.getEmpty(path))).forEach(tSender -> {
 | 
					            map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).forEach(tSender -> {
 | 
				
			||||||
@@ -77,34 +70,30 @@ class TLocaleInstance {
 | 
				
			|||||||
        return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asStringList(args);
 | 
					        return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asStringList(args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isListString(List list) {
 | 
				
			||||||
 | 
					        for (Object o : list) {
 | 
				
			||||||
 | 
					            if (!(o instanceof String)) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void load(YamlConfiguration configuration) {
 | 
					    public void load(YamlConfiguration configuration) {
 | 
				
			||||||
        updateNodes.set(0);
 | 
					 | 
				
			||||||
        configuration.getKeys(true).forEach(s -> {
 | 
					        configuration.getKeys(true).forEach(s -> {
 | 
				
			||||||
            boolean isCover = false;
 | 
					 | 
				
			||||||
            Object object = configuration.get(s);
 | 
					            Object object = configuration.get(s);
 | 
				
			||||||
            if (object instanceof TLocaleSerialize) {
 | 
					            if (object instanceof TLocaleSerialize) {
 | 
				
			||||||
                isCover = map.put(s, Collections.singletonList((TLocaleSerialize) object)) != null;
 | 
					                map.put(s, Collections.singletonList((TLocaleSerialize) object));
 | 
				
			||||||
            } else if (object instanceof List && !((List) object).isEmpty()) {
 | 
					            } else if (object instanceof List && !((List) object).isEmpty()) {
 | 
				
			||||||
                isCover = map.put(s, ((List<?>) object).stream().map(TO_SERIALIZE).collect(Collectors.toList())) != null;
 | 
					                if (isListString((List) object)) {
 | 
				
			||||||
 | 
					                    map.put(s, Collections.singletonList(TLocaleText.of(object)));
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    map.put(s, ((List<?>) object).stream().map(o -> o instanceof TLocaleSerialize ? (TLocaleSerialize) o : TLocaleText.of(String.valueOf(o))).collect(Collectors.toList()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else if (!(object instanceof ConfigurationSection)) {
 | 
					            } else if (!(object instanceof ConfigurationSection)) {
 | 
				
			||||||
                String str = String.valueOf(object);
 | 
					                String str = String.valueOf(object);
 | 
				
			||||||
                isCover = map.put(s, Collections.singletonList(str.length() == 0 ? TLocaleSerialize.getEmpty() : TLocaleText.of(str))) != null;
 | 
					                map.put(s, Collections.singletonList(str.length() == 0 ? TLocaleSerialize.getEmpty() : TLocaleText.of(str)));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (isCover) {
 | 
					 | 
				
			||||||
                updateNodes.getAndIncrement();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static final Function<Object, TLocaleSerialize> TO_SERIALIZE = o -> {
 | 
					 | 
				
			||||||
        if (o instanceof TLocaleSerialize) {
 | 
					 | 
				
			||||||
            return ((TLocaleSerialize) o);
 | 
					 | 
				
			||||||
        } else if (o instanceof List) {
 | 
					 | 
				
			||||||
            return TLocaleText.of(((List) o));
 | 
					 | 
				
			||||||
        } else if (o instanceof String) {
 | 
					 | 
				
			||||||
            return TLocaleText.of(((String) o));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return TLocaleText.of(String.valueOf(o));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
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;
 | 
				
			||||||
@@ -8,20 +9,18 @@ import com.ilummc.tlib.util.IO;
 | 
				
			|||||||
import com.ilummc.tlib.util.Strings;
 | 
					import com.ilummc.tlib.util.Strings;
 | 
				
			||||||
import me.skymc.taboolib.Main;
 | 
					import me.skymc.taboolib.Main;
 | 
				
			||||||
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.Yaml;
 | 
				
			||||||
 | 
					import sun.security.krb5.Config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.nio.charset.Charset;
 | 
					import java.nio.charset.Charset;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
import java.util.Optional;
 | 
					 | 
				
			||||||
import java.util.concurrent.ConcurrentHashMap;
 | 
					import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class TLocaleLoader {
 | 
					public class TLocaleLoader {
 | 
				
			||||||
@@ -75,23 +74,20 @@ 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());
 | 
				
			||||||
                YamlConfiguration localeConfiguration = ConfigUtils.loadYaml(plugin, localeFile);
 | 
					                Map<String, Object> originMap = getLocaleAtStream(plugin, localeFile);
 | 
				
			||||||
                YamlConfiguration localeConfigurationAtStream = getLocaleAtStream(plugin, localeFile);
 | 
					
 | 
				
			||||||
 | 
					                TLib.getTLib().getConfigWatcher().removeListener(localeFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // 载入配置
 | 
					                // 载入配置
 | 
				
			||||||
                loadPluginLocale(plugin, localeFile, localeConfiguration, localeConfigurationAtStream);
 | 
					                updateAndLoad(plugin, localeFile, originMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // 注册监听
 | 
					                // 注册监听
 | 
				
			||||||
                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());
 | 
				
			||||||
                    loadPluginLocale(plugin, localeFile, ConfigUtils.loadYaml(plugin, localeFile), getLocaleAtStream(plugin, localeFile));
 | 
					                    updateAndLoad(plugin, localeFile, getLocaleAtStream(plugin, localeFile));
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
@@ -117,22 +113,22 @@ public class TLocaleLoader {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    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().orElse(null);
 | 
					        return getLocalePriority().stream().map(localeName -> new File(plugin.getDataFolder(), "lang/" + localeName + ".yml")).filter(File::exists).findFirst().orElseThrow(NullPointerException::new);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean isLocaleLoaded(Plugin plugin) {
 | 
					    private static boolean isLocaleLoaded(Plugin plugin) {
 | 
				
			||||||
        return map.containsKey(plugin.getName());
 | 
					        return map.containsKey(plugin.getName());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean isDependWithTabooLib(Plugin plugin) {
 | 
					    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());
 | 
					        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() {
 | 
					    private static List<String> getLocalePriority() {
 | 
				
			||||||
        return Main.getInst().getConfig().contains("LOCALE.PRIORITY") ? Main.getInst().getConfig().getStringList("LOCALE.PRIORITY") : Collections.singletonList("zh_CN");
 | 
					        return Main.getInst().getConfig().contains("LOCALE.PRIORITY") ? Main.getInst().getConfig().getStringList("LOCALE.PRIORITY") : Collections.singletonList("zh_CN");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -142,29 +138,65 @@ public class TLocaleLoader {
 | 
				
			|||||||
        return instance;
 | 
					        return instance;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static YamlConfiguration getLocaleAtStream(Plugin plugin, File localeFile) {
 | 
					    private static Map<String, Object> 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"));
 | 
				
			||||||
            YamlConfiguration yaml = new YamlConfiguration();
 | 
					            Object load = new Yaml().load(yamlText);
 | 
				
			||||||
            yaml.loadFromString(yamlText);
 | 
					            return load instanceof Map ? (Map<String, Object>) load : new HashMap<>(0);
 | 
				
			||||||
            return yaml;
 | 
					        } catch (Exception e) {
 | 
				
			||||||
        } catch (Exception ignored) {
 | 
					            return new HashMap<>(0);
 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static void loadPluginLocale(Plugin plugin, File localeFile, YamlConfiguration localeConfiguration, YamlConfiguration localeConfigurationAtStream) {
 | 
					    private static Map<String, Object> currentLocaleMap(File localeFile) {
 | 
				
			||||||
        TLocaleInstance localeInstance = getLocaleInstance(plugin);
 | 
					        try {
 | 
				
			||||||
        boolean versionOutOfDate = isVersionOutOfDate(localeConfiguration, localeConfigurationAtStream);
 | 
					            Object load = new Yaml().load(Files.toString(localeFile, Charset.forName("utf-8")));
 | 
				
			||||||
        if (versionOutOfDate) {
 | 
					            return load instanceof Map ? (Map<String, Object>) load : new HashMap<>(0);
 | 
				
			||||||
            localeInstance.load(localeConfigurationAtStream);
 | 
					        } 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);
 | 
				
			||||||
 | 
					//        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);
 | 
				
			||||||
 | 
					        YamlConfiguration localeConfiguration = (YamlConfiguration) ConfigUtils.mapToConf(currentMap);
 | 
				
			||||||
        localeInstance.load(localeConfiguration);
 | 
					        localeInstance.load(localeConfiguration);
 | 
				
			||||||
        if (!versionOutOfDate || localeInstance.size() - localeInstance.getUpdateNodes() == 0) {
 | 
					        if (update == 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(localeInstance.size() - localeInstance.getUpdateNodes()));
 | 
					            infoLogger("SUCCESS-LOADING-LANG-UPDATE", plugin.getName(), localeFile.getName().split("\\.")[0], String.valueOf(localeInstance.size()), String.valueOf(update));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,27 +38,38 @@ public class TLocaleJson extends TLocaleSerialize {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static TLocaleJson valueOf(Map<String, Object> map) {
 | 
					    public static TLocaleJson valueOf(Map<String, Object> map) {
 | 
				
			||||||
        List<String> textList = getTextList(map.getOrDefault("text", "Empty Node"));
 | 
					        List<String> textList = getTextList(map.getOrDefault("text", "Empty Node"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 分析 args 并替换
 | 
				
			||||||
        Object argsObj = map.get("args");
 | 
					        Object argsObj = map.get("args");
 | 
				
			||||||
        if (argsObj instanceof Map) {
 | 
					        if (argsObj instanceof Map) {
 | 
				
			||||||
            Map<String, Object> section = new HashMap<>(((Map<?, ?>) argsObj).size());
 | 
					            Map<String, Object> section = new HashMap<>(((Map<?, ?>) argsObj).size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // valueOf(k) 是因为这个键可能加载为一个 Integer 导致 contains(String) 返回 false
 | 
				
			||||||
            ((Map<?, ?>) argsObj).forEach((k, v) -> section.put(String.valueOf(k), v));
 | 
					            ((Map<?, ?>) argsObj).forEach((k, v) -> section.put(String.valueOf(k), v));
 | 
				
			||||||
            List<BaseComponent[]> collect = textList.stream().map(s -> {
 | 
					            List<BaseComponent[]> collect = textList.stream().map(s -> {
 | 
				
			||||||
                int index = 0;
 | 
					                int index = 0;
 | 
				
			||||||
                String[] template = pattern.split(s);
 | 
					                String[] template = pattern.split(s);
 | 
				
			||||||
                Matcher matcher = pattern.matcher(s);
 | 
					                Matcher matcher = pattern.matcher(s);
 | 
				
			||||||
 | 
					                // 有可能开头和结尾是替换文本,所以做个特判
 | 
				
			||||||
                List<BaseComponent> builder = template.length > index ? new ArrayList<>(Arrays.asList(TextComponent.fromLegacyText(template[index++]))) : new ArrayList<>();
 | 
					                List<BaseComponent> builder = template.length > index ? new ArrayList<>(Arrays.asList(TextComponent.fromLegacyText(template[index++]))) : new ArrayList<>();
 | 
				
			||||||
                while (matcher.find()) {
 | 
					                while (matcher.find()) {
 | 
				
			||||||
                    String replace = matcher.group();
 | 
					                    String replace = matcher.group();
 | 
				
			||||||
 | 
					                    // 假的 <@>
 | 
				
			||||||
                    if (replace.length() <= 2) {
 | 
					                    if (replace.length() <= 2) {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    // 真的 <@xxx>
 | 
				
			||||||
                    replace = replace.substring(1, replace.length() - 1);
 | 
					                    replace = replace.substring(1, replace.length() - 1);
 | 
				
			||||||
                    String[] split = replace.split("@");
 | 
					                    String[] split = replace.split("@");
 | 
				
			||||||
 | 
					                    // @ 前面的字符串
 | 
				
			||||||
                    String text = split.length > 1 ? split[0] : "";
 | 
					                    String text = split.length > 1 ? split[0] : "";
 | 
				
			||||||
 | 
					                    // @ 后面的节点名
 | 
				
			||||||
                    String node = split.length > 1 ? split[1] : split[0];
 | 
					                    String node = split.length > 1 ? split[1] : split[0];
 | 
				
			||||||
 | 
					                    // 如果 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 = TLocale.Translate.setColored(String.valueOf(arg.getOrDefault("text", text)));
 | 
					                        text = TLocale.Translate.setColored(String.valueOf(arg.getOrDefault("text", text)));
 | 
				
			||||||
 | 
					                        // 可能有很多个 BaseComponent,于是为每个 component 单独设置各种事件
 | 
				
			||||||
                        BaseComponent[] component = TextComponent.fromLegacyText(text);
 | 
					                        BaseComponent[] component = TextComponent.fromLegacyText(text);
 | 
				
			||||||
                        arg.forEach((key, value) -> {
 | 
					                        arg.forEach((key, value) -> {
 | 
				
			||||||
                            if ("suggest".equalsIgnoreCase(key)) {
 | 
					                            if ("suggest".equalsIgnoreCase(key)) {
 | 
				
			||||||
@@ -69,11 +80,14 @@ public class TLocaleJson extends TLocaleSerialize {
 | 
				
			|||||||
                                Arrays.stream(component).forEach(baseComponent -> baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(TLocale.Translate.setColored(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 里面
 | 
				
			||||||
                        builder.addAll(Arrays.asList(component));
 | 
					                        builder.addAll(Arrays.asList(component));
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        // 这个参数节点并没有找到,于是随便放点字符串进去
 | 
				
			||||||
                        builder.addAll(Arrays.asList(TextComponent.fromLegacyText(text)));
 | 
					                        builder.addAll(Arrays.asList(TextComponent.fromLegacyText(text)));
 | 
				
			||||||
                        TLib.getTLib().getLogger().warn(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("MISSING-ARGUMENT"), node));
 | 
					                        TLib.getTLib().getLogger().warn(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("MISSING-ARGUMENT"), node));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    // 有可能一开头就是 <@xxx>,然后 split 出来就少了一些,于是直接加上
 | 
				
			||||||
                    if (index < template.length) {
 | 
					                    if (index < template.length) {
 | 
				
			||||||
                        builder.addAll(Arrays.asList(TextComponent.fromLegacyText(template[index++])));
 | 
					                        builder.addAll(Arrays.asList(TextComponent.fromLegacyText(template[index++])));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,8 +38,8 @@ public class TLocaleText extends TLocaleSerialize {
 | 
				
			|||||||
        return new TLocaleText(TLocale.Translate.setColored(s), TLocale.Translate.isPlaceholderUseDefault());
 | 
					        return new TLocaleText(TLocale.Translate.setColored(s), TLocale.Translate.isPlaceholderUseDefault());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static TLocaleText of(List<String> s) {
 | 
					    public static TLocaleText of(Object o) {
 | 
				
			||||||
        return new TLocaleText(TLocale.Translate.setColored(s), TLocale.Translate.isPlaceholderUseDefault());
 | 
					        return o instanceof String ? of(((String) o)) : new TLocaleText(o, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static TLocaleText valueOf(Map<String, Object> map) {
 | 
					    public static TLocaleText valueOf(Map<String, Object> map) {
 | 
				
			||||||
@@ -71,7 +71,7 @@ public class TLocaleText extends TLocaleSerialize {
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public List<String> asStringList(String... args) {
 | 
					    public List<String> asStringList(String... args) {
 | 
				
			||||||
        if (text instanceof List) {
 | 
					        if (text instanceof List) {
 | 
				
			||||||
            return ((List<String>) text).stream().map(x -> "list: " + Strings.replaceWithOrder(TLocale.Translate.setColored(x), args)).collect(Collectors.toList());
 | 
					            return ((List<String>) text).stream().map(x -> Strings.replaceWithOrder(TLocale.Translate.setColored(x), args)).collect(Collectors.toList());
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return Collections.singletonList(asString(args));
 | 
					            return Collections.singletonList(asString(args));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,18 @@ 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    System.out.println("lore: " + TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name));
 | 
				
			||||||
 | 
					                    System.out.println("lore: " + TLocale.asStringList("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    TLocale.sendTo(player, "COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name);
 | 
				
			||||||
                    holder.ITEMS_DATA.put(slot, name);
 | 
					                    holder.ITEMS_DATA.put(slot, name);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
@@ -62,16 +73,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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -464,5 +464,3 @@ COMMANDS:
 | 
				
			|||||||
DATABASE:
 | 
					DATABASE:
 | 
				
			||||||
  CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
 | 
					  CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
 | 
				
			||||||
  CONNECTION-ERROR: '连接到数据库错误:{0}'
 | 
					  CONNECTION-ERROR: '连接到数据库错误:{0}'
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
VERSION: 4.0
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user