+ update
This commit is contained in:
		
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
    <groupId>me.skymc</groupId>
 | 
			
		||||
    <artifactId>TabooLib</artifactId>
 | 
			
		||||
    <version>4.27</version>
 | 
			
		||||
    <version>4.28</version>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,15 +14,16 @@ import com.ilummc.tlib.resources.TLocaleLoader;
 | 
			
		||||
import com.ilummc.tlib.util.IO;
 | 
			
		||||
import me.skymc.taboolib.Main;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.plugin.PluginUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.configuration.InvalidConfigurationException;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25")
 | 
			
		||||
@@ -58,14 +59,6 @@ public class TLib {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static TLib getTLib() {
 | 
			
		||||
        return tLib;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static YamlConfiguration getInternalLanguage() {
 | 
			
		||||
        return internalLanguage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void init() {
 | 
			
		||||
        tLib = new TLib();
 | 
			
		||||
 | 
			
		||||
@@ -94,6 +87,11 @@ public class TLib {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void injectPluginManager() {
 | 
			
		||||
        if (!tLib.isInjectEnabled() || tLib.isBlackListPluginExists()) {
 | 
			
		||||
            TLocale.Logger.fatal("TLIB.INJECTION-DISABLED");
 | 
			
		||||
            Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager");
 | 
			
		||||
            field.setAccessible(true);
 | 
			
		||||
@@ -101,14 +99,18 @@ public class TLib {
 | 
			
		||||
            TLocale.Logger.info("TLIB.INJECTION-SUCCESS");
 | 
			
		||||
        } catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
 | 
			
		||||
            TLocale.Logger.fatal("TLIB.INJECTION-FAILED");
 | 
			
		||||
            for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
 | 
			
		||||
                if (plugin != Main.getInst()) {
 | 
			
		||||
                    TDependencyInjector.inject(plugin, plugin);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static TLib getTLib() {
 | 
			
		||||
        return tLib;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static YamlConfiguration getInternalLanguage() {
 | 
			
		||||
        return internalLanguage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TLogger getLogger() {
 | 
			
		||||
        return logger;
 | 
			
		||||
    }
 | 
			
		||||
@@ -124,4 +126,18 @@ public class TLib {
 | 
			
		||||
    public File getLibsFolder() {
 | 
			
		||||
        return libsFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Private Methods
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
    private boolean isInjectEnabled() {
 | 
			
		||||
        return Main.getInst().getConfig().getBoolean("PLUGIN-INJECTOR.ENABLE", true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isBlackListPluginExists() {
 | 
			
		||||
        return Main.getInst().getConfig().getStringList("PLUGIN-INJECTOR.DISABLE-ON-PLUGIN-EXISTS").stream().anyMatch(PluginUtils::isPluginExists);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -165,6 +165,5 @@ public class TabooLibLoader implements Listener {
 | 
			
		||||
    static void registerMetrics() {
 | 
			
		||||
        Metrics metrics = new Metrics(TabooLib.instance());
 | 
			
		||||
        metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count())));
 | 
			
		||||
        metrics.addCustomChart(new Metrics.AdvancedPie("plugins_using_taboolib_name", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).collect(Collectors.toMap(Plugin::getName, plugin -> 1, (a, b) -> b))));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,13 +17,7 @@ import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Timer;
 | 
			
		||||
import java.util.TimerTask;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.Callable;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.zip.GZIPOutputStream;
 | 
			
		||||
@@ -36,13 +30,22 @@ import java.util.zip.GZIPOutputStream;
 | 
			
		||||
 */
 | 
			
		||||
public class Metrics {
 | 
			
		||||
 | 
			
		||||
    // The version of this bStats class
 | 
			
		||||
    public static final int B_STATS_VERSION = 1;
 | 
			
		||||
    // The url to which the data is sent
 | 
			
		||||
    private static final String URL = "https://bStats.org/submitData/bukkit";
 | 
			
		||||
    // Should failed requests be logged?
 | 
			
		||||
    private static boolean logFailedRequests;
 | 
			
		||||
    // The uuid of the server
 | 
			
		||||
    private static String serverUUID;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        // You can use the property to disable the check in your test environment
 | 
			
		||||
        if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
 | 
			
		||||
            // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
 | 
			
		||||
            final String defaultPackage = new String(
 | 
			
		||||
                    new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
 | 
			
		||||
            final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
 | 
			
		||||
                    new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
 | 
			
		||||
            final String examplePackage = new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
 | 
			
		||||
            // We want to make sure nobody just copy & pastes the example and use the wrong package names
 | 
			
		||||
            if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
 | 
			
		||||
                throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
 | 
			
		||||
@@ -50,18 +53,6 @@ public class Metrics {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The version of this bStats class
 | 
			
		||||
    public static final int B_STATS_VERSION = 1;
 | 
			
		||||
 | 
			
		||||
    // The url to which the data is sent
 | 
			
		||||
    private static final String URL = "https://bStats.org/submitData/bukkit";
 | 
			
		||||
 | 
			
		||||
    // Should failed requests be logged?
 | 
			
		||||
    private static boolean logFailedRequests;
 | 
			
		||||
 | 
			
		||||
    // The uuid of the server
 | 
			
		||||
    private static String serverUUID;
 | 
			
		||||
 | 
			
		||||
    // The plugin
 | 
			
		||||
    private final JavaPlugin plugin;
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +94,8 @@ public class Metrics {
 | 
			
		||||
            ).copyDefaults(true);
 | 
			
		||||
            try {
 | 
			
		||||
                config.save(configFile);
 | 
			
		||||
            } catch (IOException ignored) { }
 | 
			
		||||
            } catch (IOException ignored) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Load the data
 | 
			
		||||
@@ -117,7 +109,8 @@ public class Metrics {
 | 
			
		||||
                    service.getField("B_STATS_VERSION"); // Our identifier :)
 | 
			
		||||
                    found = true; // We aren't the first
 | 
			
		||||
                    break;
 | 
			
		||||
                } catch (NoSuchFieldException ignored) { }
 | 
			
		||||
                } catch (NoSuchFieldException ignored) {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Register our service
 | 
			
		||||
            Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
 | 
			
		||||
@@ -128,6 +121,61 @@ public class Metrics {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends the data to the bStats server.
 | 
			
		||||
     *
 | 
			
		||||
     * @param data The data to send.
 | 
			
		||||
     * @throws Exception If the request failed.
 | 
			
		||||
     */
 | 
			
		||||
    private static void sendData(JSONObject data) throws Exception {
 | 
			
		||||
        if (data == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Data cannot be null!");
 | 
			
		||||
        }
 | 
			
		||||
        if (Bukkit.isPrimaryThread()) {
 | 
			
		||||
            throw new IllegalAccessException("This method must not be called from the main thread!");
 | 
			
		||||
        }
 | 
			
		||||
        HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
 | 
			
		||||
 | 
			
		||||
        // Compress the data to save bandwidth
 | 
			
		||||
        byte[] compressedData = compress(data.toString());
 | 
			
		||||
 | 
			
		||||
        // Add headers
 | 
			
		||||
        connection.setRequestMethod("POST");
 | 
			
		||||
        connection.addRequestProperty("Accept", "application/json");
 | 
			
		||||
        connection.addRequestProperty("Connection", "close");
 | 
			
		||||
        connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
 | 
			
		||||
        connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
 | 
			
		||||
        connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
 | 
			
		||||
        connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
 | 
			
		||||
 | 
			
		||||
        // Send data
 | 
			
		||||
        connection.setDoOutput(true);
 | 
			
		||||
        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
 | 
			
		||||
        outputStream.write(compressedData);
 | 
			
		||||
        outputStream.flush();
 | 
			
		||||
        outputStream.close();
 | 
			
		||||
 | 
			
		||||
        connection.getInputStream().close(); // We don't care about the response - Just send our data :)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gzips the given String.
 | 
			
		||||
     *
 | 
			
		||||
     * @param str The string to gzip.
 | 
			
		||||
     * @return The gzipped String.
 | 
			
		||||
     * @throws IOException If the compression failed.
 | 
			
		||||
     */
 | 
			
		||||
    private static byte[] compress(final String str) throws IOException {
 | 
			
		||||
        if (str == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 | 
			
		||||
        GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
 | 
			
		||||
        gzip.write(str.getBytes("UTF-8"));
 | 
			
		||||
        gzip.close();
 | 
			
		||||
        return outputStream.toByteArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a custom chart.
 | 
			
		||||
     *
 | 
			
		||||
@@ -161,7 +209,7 @@ public class Metrics {
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }, 1000*60*5, 1000*60*30);
 | 
			
		||||
        }, 1000 * 60 * 5, 1000 * 60 * 30);
 | 
			
		||||
        // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
 | 
			
		||||
        // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
 | 
			
		||||
        // WARNING: Just don't do it!
 | 
			
		||||
@@ -256,9 +304,11 @@ public class Metrics {
 | 
			
		||||
                for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
 | 
			
		||||
                    } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
 | 
			
		||||
                    } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (NoSuchFieldException ignored) { }
 | 
			
		||||
            } catch (NoSuchFieldException ignored) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data.put("plugins", pluginData);
 | 
			
		||||
@@ -280,61 +330,6 @@ public class Metrics {
 | 
			
		||||
        }).start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends the data to the bStats server.
 | 
			
		||||
     *
 | 
			
		||||
     * @param data The data to send.
 | 
			
		||||
     * @throws Exception If the request failed.
 | 
			
		||||
     */
 | 
			
		||||
    private static void sendData(JSONObject data) throws Exception {
 | 
			
		||||
        if (data == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Data cannot be null!");
 | 
			
		||||
        }
 | 
			
		||||
        if (Bukkit.isPrimaryThread()) {
 | 
			
		||||
            throw new IllegalAccessException("This method must not be called from the main thread!");
 | 
			
		||||
        }
 | 
			
		||||
        HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
 | 
			
		||||
 | 
			
		||||
        // Compress the data to save bandwidth
 | 
			
		||||
        byte[] compressedData = compress(data.toString());
 | 
			
		||||
 | 
			
		||||
        // Add headers
 | 
			
		||||
        connection.setRequestMethod("POST");
 | 
			
		||||
        connection.addRequestProperty("Accept", "application/json");
 | 
			
		||||
        connection.addRequestProperty("Connection", "close");
 | 
			
		||||
        connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
 | 
			
		||||
        connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
 | 
			
		||||
        connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
 | 
			
		||||
        connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
 | 
			
		||||
 | 
			
		||||
        // Send data
 | 
			
		||||
        connection.setDoOutput(true);
 | 
			
		||||
        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
 | 
			
		||||
        outputStream.write(compressedData);
 | 
			
		||||
        outputStream.flush();
 | 
			
		||||
        outputStream.close();
 | 
			
		||||
 | 
			
		||||
        connection.getInputStream().close(); // We don't care about the response - Just send our data :)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gzips the given String.
 | 
			
		||||
     *
 | 
			
		||||
     * @param str The string to gzip.
 | 
			
		||||
     * @return The gzipped String.
 | 
			
		||||
     * @throws IOException If the compression failed.
 | 
			
		||||
     */
 | 
			
		||||
    private static byte[] compress(final String str) throws IOException {
 | 
			
		||||
        if (str == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 | 
			
		||||
        GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
 | 
			
		||||
        gzip.write(str.getBytes("UTF-8"));
 | 
			
		||||
        gzip.close();
 | 
			
		||||
        return outputStream.toByteArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Represents a custom chart.
 | 
			
		||||
     */
 | 
			
		||||
@@ -388,7 +383,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public SimplePie(String chartId, Callable<String> callable) {
 | 
			
		||||
@@ -419,7 +414,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
 | 
			
		||||
@@ -463,7 +458,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
 | 
			
		||||
@@ -512,7 +507,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public SingleLineChart(String chartId, Callable<Integer> callable) {
 | 
			
		||||
@@ -544,7 +539,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
 | 
			
		||||
@@ -589,7 +584,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
 | 
			
		||||
@@ -627,7 +622,7 @@ public class Metrics {
 | 
			
		||||
        /**
 | 
			
		||||
         * Class constructor.
 | 
			
		||||
         *
 | 
			
		||||
         * @param chartId The id of the chart.
 | 
			
		||||
         * @param chartId  The id of the chart.
 | 
			
		||||
         * @param callable The callable which is used to request the chart data.
 | 
			
		||||
         */
 | 
			
		||||
        public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@ package me.skymc.taboolib.listener;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.Main;
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
import me.skymc.taboolib.mysql.MysqlUtils;
 | 
			
		||||
import me.skymc.taboolib.mysql.hikari.HikariHandler;
 | 
			
		||||
import me.skymc.taboolib.mysql.protect.MySQLConnection;
 | 
			
		||||
import me.skymc.taboolib.timecycle.TimeCycleManager;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
@@ -12,6 +12,7 @@ import org.bukkit.event.server.PluginDisableEvent;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@TListener
 | 
			
		||||
@@ -21,12 +22,14 @@ public class ListenerPluginDisable implements Listener {
 | 
			
		||||
    public void disable(PluginDisableEvent e) {
 | 
			
		||||
        // 注销时间周期
 | 
			
		||||
        TimeCycleManager.cancel(e.getPlugin());
 | 
			
		||||
        // 注销数据库连接
 | 
			
		||||
        new HashSet<>(HikariHandler.getDataSource().keySet()).stream().filter(host -> e.getPlugin().equals(host.getPlugin()) && host.isAutoClose()).forEach(HikariHandler::closeDataSource);
 | 
			
		||||
 | 
			
		||||
        // 获取连接
 | 
			
		||||
        List<MySQLConnection> conns = new ArrayList<>();
 | 
			
		||||
        List<MySQLConnection> connection = new ArrayList<>();
 | 
			
		||||
        for (MySQLConnection conn : MysqlUtils.CONNECTIONS) {
 | 
			
		||||
            if (conn.getPlugin().equals(e.getPlugin())) {
 | 
			
		||||
                conns.add(conn);
 | 
			
		||||
                connection.add(conn);
 | 
			
		||||
                MysqlUtils.CONNECTIONS.remove(conn);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -37,7 +40,7 @@ public class ListenerPluginDisable implements Listener {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                for (MySQLConnection conn : conns) {
 | 
			
		||||
                for (MySQLConnection conn : connection) {
 | 
			
		||||
                    conn.setFallReconnection(false);
 | 
			
		||||
                    conn.closeConnection();
 | 
			
		||||
                    i++;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,18 +18,28 @@ public class SQLHost {
 | 
			
		||||
    private String password;
 | 
			
		||||
    private String database;
 | 
			
		||||
    private Plugin plugin;
 | 
			
		||||
    private boolean autoClose;
 | 
			
		||||
 | 
			
		||||
    public SQLHost(ConfigurationSection section, Plugin plugin) {
 | 
			
		||||
        this(section, plugin, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SQLHost(ConfigurationSection section, Plugin plugin, boolean autoClose) {
 | 
			
		||||
        this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
 | 
			
		||||
        this(host, user, port, password, database, plugin, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SQLHost(String host, String user, String port, String password, String database, Plugin plugin, boolean autoClose) {
 | 
			
		||||
        this.host = host;
 | 
			
		||||
        this.user = user;
 | 
			
		||||
        this.port = port;
 | 
			
		||||
        this.password = password;
 | 
			
		||||
        this.database = database;
 | 
			
		||||
        this.plugin = plugin;
 | 
			
		||||
        this.autoClose = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHost() {
 | 
			
		||||
@@ -56,6 +66,10 @@ public class SQLHost {
 | 
			
		||||
        return plugin;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAutoClose() {
 | 
			
		||||
        return autoClose;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getConnectionUrl() {
 | 
			
		||||
        return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.host, this.port, this.database);
 | 
			
		||||
    }
 | 
			
		||||
@@ -73,16 +87,18 @@ public class SQLHost {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        SQLHost sqlHost = (SQLHost) o;
 | 
			
		||||
        return Objects.equals(getHost(), sqlHost.getHost()) &&
 | 
			
		||||
        return autoClose == sqlHost.autoClose &&
 | 
			
		||||
                Objects.equals(getHost(), sqlHost.getHost()) &&
 | 
			
		||||
                Objects.equals(getUser(), sqlHost.getUser()) &&
 | 
			
		||||
                Objects.equals(getPort(), sqlHost.getPort()) &&
 | 
			
		||||
                Objects.equals(getPassword(), sqlHost.getPassword()) &&
 | 
			
		||||
                Objects.equals(getDatabase(), sqlHost.getDatabase());
 | 
			
		||||
                Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
 | 
			
		||||
                Objects.equals(getPlugin(), sqlHost.getPlugin());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase());
 | 
			
		||||
        return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getPlugin(), autoClose);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -94,6 +110,7 @@ public class SQLHost {
 | 
			
		||||
                ", password='" + password + '\'' +
 | 
			
		||||
                ", database='" + database + '\'' +
 | 
			
		||||
                ", plugin=" + plugin +
 | 
			
		||||
                ", autoClose=" + autoClose +
 | 
			
		||||
                '}';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,11 +26,7 @@ public class SQLTable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SQLTable addColumn(SQLColumn sqlColumn) {
 | 
			
		||||
        if (columns == null) {
 | 
			
		||||
            columns = new SQLColumn[] {sqlColumn};
 | 
			
		||||
        } else {
 | 
			
		||||
            columns = ArrayUtils.arrayAppend(columns, sqlColumn);
 | 
			
		||||
        }
 | 
			
		||||
        columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -89,4 +89,18 @@ public class HikariHandler {
 | 
			
		||||
        }
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
    public static ConcurrentHashMap<SQLHost, MapDataSource> getDataSource() {
 | 
			
		||||
        return dataSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static FileConfiguration getSettings() {
 | 
			
		||||
        return settings;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ public class PluginUtils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getPluginFile(Plugin plugin) {
 | 
			
		||||
        for (File pluginFile : Objects.requireNonNull(new File("plugins").listFiles())) {
 | 
			
		||||
        for (File pluginFile : new File("plugins").listFiles()) {
 | 
			
		||||
            if (pluginFile.getName().endsWith(".jar")) {
 | 
			
		||||
                try {
 | 
			
		||||
                    PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
 | 
			
		||||
@@ -44,6 +44,21 @@ public class PluginUtils {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isPluginExists(String name) {
 | 
			
		||||
        for (File pluginFile : new File("plugins").listFiles()) {
 | 
			
		||||
            if (pluginFile.getName().endsWith(".jar")) {
 | 
			
		||||
                try {
 | 
			
		||||
                    PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
 | 
			
		||||
                    if (desc.getName().equalsIgnoreCase(name)) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception ignored) {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void enable(Plugin plugin) {
 | 
			
		||||
        if (plugin != null && !plugin.isEnabled()) {
 | 
			
		||||
            Bukkit.getPluginManager().enablePlugin(plugin);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package me.skymc.taboolib.string;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.ObjectInputStream;
 | 
			
		||||
@@ -20,15 +19,21 @@ import java.util.stream.IntStream;
 | 
			
		||||
 */
 | 
			
		||||
public class ArrayUtils {
 | 
			
		||||
 | 
			
		||||
    public static String arrayJoin(String[] args, int start) {
 | 
			
		||||
        return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
 | 
			
		||||
    public static <T> int indexOf(T[] array, T obj) {
 | 
			
		||||
        return array == null || array.length == 0 ? -1 : IntStream.range(0, array.length).filter(i -> array[i] != null && array[i].equals(obj)).findFirst().orElse(-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> boolean contains(T[] array, T obj) {
 | 
			
		||||
        return indexOf(array, obj) != -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SafeVarargs
 | 
			
		||||
    public static <T> List<T> asList(T... args) {
 | 
			
		||||
        List<T> list = new ArrayList<>();
 | 
			
		||||
        Collections.addAll(list, args);
 | 
			
		||||
        return list;
 | 
			
		||||
    public static <T> T[] asArray(T... args) {
 | 
			
		||||
        return args;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String arrayJoin(String[] args, int start) {
 | 
			
		||||
        return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T[] arrayAppend(T[] array, T obj) {
 | 
			
		||||
@@ -88,6 +93,13 @@ public class ArrayUtils {
 | 
			
		||||
        return firstElement == null ? def : obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SafeVarargs
 | 
			
		||||
    public static <T> List<T> asList(T... args) {
 | 
			
		||||
        List<T> list = new ArrayList<>();
 | 
			
		||||
        Collections.addAll(list, args);
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //           Deprecated
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ DATAURL:
 | 
			
		||||
  SERVER-DATA: 'plugins/TabooLib/serverdata/'
 | 
			
		||||
  # 物品数据(来自 ItemSave 插件)
 | 
			
		||||
  ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
# 语言文件相关设置
 | 
			
		||||
LOCALE:
 | 
			
		||||
  # 加载语言文件的顺序
 | 
			
		||||
@@ -23,7 +23,14 @@ LOCALE:
 | 
			
		||||
  # 关闭可提升性能
 | 
			
		||||
  # 如果需要开启仍然可以在语言文件中加入 papi: true
 | 
			
		||||
  USE_PAPI: false
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
# 是否注入 PluginManager,关闭后可能会导致部分功能出错。
 | 
			
		||||
PLUGIN-INJECTOR:
 | 
			
		||||
  ENABLE: true
 | 
			
		||||
  # 检测下面的插件并自动关闭注入
 | 
			
		||||
  DISABLE-ON-PLUGIN-EXISTS:
 | 
			
		||||
  - LuckPerms
 | 
			
		||||
 | 
			
		||||
# 是否启用调试模式
 | 
			
		||||
# 启用后将收到来自其他插件的调试信息
 | 
			
		||||
DEBUG: false
 | 
			
		||||
@@ -83,7 +90,7 @@ MYSQL:
 | 
			
		||||
  DATABASE: 'test'
 | 
			
		||||
  # 数据表前缀
 | 
			
		||||
  PREFIX: 'taboolib'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
# 全局变量信息
 | 
			
		||||
PluginData:
 | 
			
		||||
  # 检查更新间隔(单位:秒)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,11 @@
 | 
			
		||||
TLIB:
 | 
			
		||||
  INJECTION-SUCCESS: '注入成功'
 | 
			
		||||
  INJECTION-FAILED:
 | 
			
		||||
    - '注入失败'
 | 
			
		||||
    - '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
 | 
			
		||||
  - '注入失败'
 | 
			
		||||
  - '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
 | 
			
		||||
  INJECTION-DISABLED:
 | 
			
		||||
  - '关闭注入'
 | 
			
		||||
  - '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
 | 
			
		||||
  LOAD-FAIL-OFFLINE:
 | 
			
		||||
  - '**********************************************'
 | 
			
		||||
  - '** TabooLib-{0} 无法在您的服务器上使用'
 | 
			
		||||
@@ -12,15 +15,15 @@ TLIB:
 | 
			
		||||
  - '**'
 | 
			
		||||
  - '** 详情查阅: https://github.com/Bkm016/TabooLib'
 | 
			
		||||
  - '**********************************************'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
DEPENDENCY:
 | 
			
		||||
  DOWNLOAD-OFFLINE: '已启用离线模式, 将不会下载第三方依赖库'
 | 
			
		||||
  DOWNLOAD-CONNECTED: '  正在下载 {0} 大小 {1}'
 | 
			
		||||
  DOWNLOAD-PROGRESS: '    下载速度 {0} 进度 {1}'
 | 
			
		||||
  DOWNLOAD-SUCCESS: '  下载 {0} 完成'
 | 
			
		||||
  DOWNLOAD-FAILED:
 | 
			
		||||
    - '  下载 {0} 失败'
 | 
			
		||||
    - '  请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
 | 
			
		||||
  - '  下载 {0} 失败'
 | 
			
		||||
  - '  请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
 | 
			
		||||
  PLUGIN-AUTOLOAD-FAIL: '{0} 所依赖的插件 {1} 尝试自动加载失败,请尝试手动下载'
 | 
			
		||||
  PLUGIN-LOAD-SUCCESS: '  {0} 请求的插件 {1} 加载成功'
 | 
			
		||||
  PLUGIN-LOAD-FAIL: '  {0} 请求的插件 {1} 加载失败'
 | 
			
		||||
@@ -29,7 +32,7 @@ DEPENDENCY:
 | 
			
		||||
  LIBRARY-LOAD-FAIL: '  {0} 请求的库文件 {1} 加载失败'
 | 
			
		||||
  LOAD-COMPLETE: '依赖加载完成'
 | 
			
		||||
  LOAD-CLASSES: '&7缓存 &f{0} &7插件的 &f{1} &7个类耗时&f {2} &7毫秒.'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
CONFIG:
 | 
			
		||||
  LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
 | 
			
		||||
  LOAD-FAIL: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
 | 
			
		||||
@@ -41,7 +44,7 @@ CONFIG:
 | 
			
		||||
  RELOAD-SUCCESS: '插件 {0} 的配置 {1} 成功重载'
 | 
			
		||||
  RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载'
 | 
			
		||||
  LISTEN-START: '开始监听 {0} 插件的 {1} 配置文件'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
NOTIFY:
 | 
			
		||||
  ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!'
 | 
			
		||||
  ERROR-CONNECTION-FAIL: '&4数据库连接失败, 请检查配置是否正确!'
 | 
			
		||||
@@ -56,7 +59,7 @@ NOTIFY:
 | 
			
		||||
  FAIL-DISABLE:
 | 
			
		||||
  - '&c插件尚未启动完成, 已跳过卸载代码'
 | 
			
		||||
  - '&c插件作者: &4坏黑'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
LOCALE:
 | 
			
		||||
  TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
 | 
			
		||||
  PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}'
 | 
			
		||||
@@ -66,36 +69,36 @@ LOCALE:
 | 
			
		||||
  BAR-PLUGIN-NOT-FOUND: 'TLocaleBossBar 的依赖插件 BossBarAPI 不存在'
 | 
			
		||||
  CALLER-PLUGIN-NOT-FOUND: '{0} 不是一个由插件加载的类'
 | 
			
		||||
  STATIC-CLASS-LOADER: '{0} 由静态类加载器初始化,无法获得其从属的插件'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
MISC:
 | 
			
		||||
  FIELD-COPY-FAILED: '拷贝 {0} 对象失败'
 | 
			
		||||
  FIELD-COPY-ERROR: '拷贝 {0} 对象出错:{1}'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
COOLDOWNPACK:
 | 
			
		||||
  PACK-REGISTER: '注册冷却包: {0}, 时间: {1} 秒 ({2})'
 | 
			
		||||
  PACK-REGISTER-ANONYMOUS: '注册冷却包: {0}, 时间: {1} 秒 (匿名注册)'
 | 
			
		||||
  PACK-UNREGISTER: '注销冷却包: {0} (主动注销)'
 | 
			
		||||
  PACK-UNREGISTER-AUTO: '注销冷却包: {0} (自动注销)'
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
GLOBAL-DATAMANAGER:
 | 
			
		||||
  ERROR-CHECK-VARIABLE: '&4变量 &c{0} &4载入异常: &c{1}'
 | 
			
		||||
  SUCCESS-LOADED-VARIABLE: '&7从数据库中获取 &f{0} &7个变量, 耗时: &f{1} &7(ms)'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
PLAYER-DATAMANAGER:
 | 
			
		||||
  ERROR-STORAGE-SQL: '不允许在储存模式为数据库的情况下获取离线玩家数据'
 | 
			
		||||
  ERROR-PLAYER-DATA: '&4玩家 &c{0} &4的数据载入出现异常: &c{1}'
 | 
			
		||||
  SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条玩家数据, 耗时: &f{1} &7(ms)'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
ENTITY-UTILS:
 | 
			
		||||
  NOTFOUND-PROTOCOLLIB: '缺少前置插件 ProtocolLib'
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
FILE-UTILS:
 | 
			
		||||
  FAIL-LOAD-CONFIGURATION: '&4配置文件载入失败!, 插件: &c{0}&4, 文件: &c{1}'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
DATA-UTILS:
 | 
			
		||||
  SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条插件数据, 耗时: &f{1} &7(ms)'
 | 
			
		||||
  FAIL-SAVE-FILE: '&4文件 &c{0}&4 保存失败, 原因: &c{1}'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
ITEM-UTILS:
 | 
			
		||||
  FAIL-LOAD-ITEMS: '物品库载入失败: &4{0}'
 | 
			
		||||
  FAIL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
 | 
			
		||||
@@ -106,13 +109,13 @@ ITEM-UTILS:
 | 
			
		||||
  SUCCESS-LOAD-CACHES: '&7载入 &f{0} &7项缓存物品'
 | 
			
		||||
  SUCCESS-LOAD-NAMES: '&7载入 &f{0} &7项物品名称'
 | 
			
		||||
  EMPTY-ITEM: '空'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
LANGUAGE2:
 | 
			
		||||
  FAIL-NOTFOUND-FILE: '语言文件 {0} 不存在'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
TIMECYCLE:
 | 
			
		||||
  FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
UPDATETASK:
 | 
			
		||||
  VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
 | 
			
		||||
  VERSION-LATEST: '&7插件已是最新版, 无需更新!'
 | 
			
		||||
@@ -124,7 +127,7 @@ UPDATETASK:
 | 
			
		||||
  - '&7 下载地址: &fhttp://www.mcbbs.net/thread-773065-1-1.html'
 | 
			
		||||
  - '&7 开源地址: &fhttps://github.com/Bkm016/TabooLib/'
 | 
			
		||||
  - '&8####################################################'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
MYSQL-CONNECTION:
 | 
			
		||||
  FAIL-CONNECT: '&4数据库 &c{0} &4连接失败, 原因: &c{0}'
 | 
			
		||||
  FAIL-NOTFOUND-DRIVE: '&7驱动器获取失败, 无法连接到数据库'
 | 
			
		||||
@@ -138,18 +141,18 @@ MYSQL-CONNECTION:
 | 
			
		||||
  SUCCESS-CONNECTION-CANCEL: '已停止插件 &f{0}&7 的 &f{1}&7 条数据库连接'
 | 
			
		||||
  NOTIFY-CONNECTING: '&7正在连接数据库, 地址: &f{0}'
 | 
			
		||||
  NOTIFY-CONNECTED: '&7数据库连接成功 ({0}ms)'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
MYSQL-HIKARI:
 | 
			
		||||
  CREATE-SUCCESS: '&7插件 &f{0}&7 注册新的数据库连接: &f{1}'
 | 
			
		||||
  CREATE-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
 | 
			
		||||
  CLOSE-SUCCESS: '&7插件 &f{0} &7注册的数据库连接 &f{1} &7已被注销!'
 | 
			
		||||
  CLOSE-FAIL: '&7插件 &f{0} &7注册的数据库连接正在被 &f{1} &7个插件使用, 无法注销!'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
TABOOLIB-MODULE:
 | 
			
		||||
  SUCCESS-LOADED: '&7载入 &f{0} &7个 &fTLM &7模块'
 | 
			
		||||
  FAIL-LOADED: '&4模块载入异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
 | 
			
		||||
  FAIL-RUNTIME: '&4模块运行异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
COMMANDS:
 | 
			
		||||
  GLOBAL:
 | 
			
		||||
    ONLY-PLAYER: '&8[&3&lTabooLib&8] &4控制台无法这么做'
 | 
			
		||||
@@ -379,7 +382,7 @@ COMMANDS:
 | 
			
		||||
            hover: '&f点击复制'
 | 
			
		||||
            suggest: '{0}'
 | 
			
		||||
      FOOT:
 | 
			
		||||
      - ''    
 | 
			
		||||
      - ''
 | 
			
		||||
    ENCHANTS:
 | 
			
		||||
      DESCRIPTION: '查看所有附魔'
 | 
			
		||||
      HEAD:
 | 
			
		||||
@@ -424,7 +427,7 @@ COMMANDS:
 | 
			
		||||
            hover: '&f点击复制'
 | 
			
		||||
            suggest: '{0}'
 | 
			
		||||
      FOOT:
 | 
			
		||||
      - ''  
 | 
			
		||||
      - ''
 | 
			
		||||
    SLOTS:
 | 
			
		||||
      DESCRIPTION: '查看所有部位'
 | 
			
		||||
      HEAD:
 | 
			
		||||
@@ -467,7 +470,7 @@ COMMANDS:
 | 
			
		||||
    COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &e&l-----'
 | 
			
		||||
    LIST:
 | 
			
		||||
      DESCRIPTION: '列出插件'
 | 
			
		||||
      LIST-PLUGIN: 
 | 
			
		||||
      LIST-PLUGIN:
 | 
			
		||||
      - '&8[&3&lTabooLib&8] &7插件总数: &f{0}'
 | 
			
		||||
      - '&8[&3&lTabooLib&8] &7插件列表: &f{1}'
 | 
			
		||||
    INFO:
 | 
			
		||||
@@ -562,7 +565,7 @@ COMMANDS:
 | 
			
		||||
DATABASE:
 | 
			
		||||
  CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
 | 
			
		||||
  CONNECTION-ERROR: '连接到数据库错误:{0}'
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
COMMUNICATION:
 | 
			
		||||
  FAILED-LOAD-SETTINGS: '§8[§3§lTabooLibClient§8] &4配置载入失败: {0}'
 | 
			
		||||
  FAILED-CONNECT-SERVER: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接失败.'
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user