TabooLib v4.25
+ 新增 TConfiguration 工具,与 TConfigWatcher 联动创建能够自动重载的配置文件。(尚未测试) + 新增 TFunction 注解,自动执行载入与卸载方法。(变懒第一步,放弃注册步骤) + 调整 TLogger 工具,允许以自定义名称创建,并支持在 BungeeCord 下使用。 + 调整 TListener 与 Instantiable 注解,不会再重复读取插件类了。 + 调整 ReflectionUtils 工具,对部分语法进行了修改。 + 调整 TabooLib 类下的 isSpigot 与 getVersion 算法。 + 重做 AnvilContainerAPI 工具,现在可以正常使用了。(丢人玩意儿终于重写了) + InstanceHandler 类更名为 InstantiableLoader + MsgUtils 类被赋予尊贵的 @Deprecated
This commit is contained in:
		
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
    <groupId>me.skymc</groupId>
 | 
			
		||||
    <artifactId>TabooLib</artifactId>
 | 
			
		||||
    <version>4.23</version>
 | 
			
		||||
    <version>4.25</version>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,12 @@
 | 
			
		||||
package com.ilummc.tlib.logger;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
import me.skymc.taboolib.Main;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import net.md_5.bungee.BungeeCord;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
public class TLogger {
 | 
			
		||||
@@ -12,7 +15,7 @@ public class TLogger {
 | 
			
		||||
 | 
			
		||||
    private static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE);
 | 
			
		||||
    private final String pattern;
 | 
			
		||||
    private Plugin plugin;
 | 
			
		||||
    private String name;
 | 
			
		||||
    private int level;
 | 
			
		||||
 | 
			
		||||
    public static TLogger getGlobalLogger() {
 | 
			
		||||
@@ -23,8 +26,8 @@ public class TLogger {
 | 
			
		||||
        return pattern;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Plugin getPlugin() {
 | 
			
		||||
        return plugin;
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLevel() {
 | 
			
		||||
@@ -37,49 +40,83 @@ public class TLogger {
 | 
			
		||||
 | 
			
		||||
    public TLogger(String pattern, Plugin plugin, int level) {
 | 
			
		||||
        this.pattern = pattern;
 | 
			
		||||
        this.plugin = plugin;
 | 
			
		||||
        this.name = plugin.getName();
 | 
			
		||||
        this.level = level;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TLogger(String pattern, String name, int level) {
 | 
			
		||||
        this.pattern = pattern;
 | 
			
		||||
        this.name = name;
 | 
			
		||||
        this.level = level;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void verbose(String msg) {
 | 
			
		||||
        if (level <= VERBOSE) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void finest(String msg) {
 | 
			
		||||
        if (level <= FINEST) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void fine(String msg) {
 | 
			
		||||
        if (level <= FINE) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void info(String msg) {
 | 
			
		||||
        if (level <= INFO) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void warn(String msg) {
 | 
			
		||||
        if (level <= WARN) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void error(String msg) {
 | 
			
		||||
        if (level <= ERROR) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void fatal(String msg) {
 | 
			
		||||
        if (level <= FATAL) {
 | 
			
		||||
            Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg)));
 | 
			
		||||
            if (TabooLib.isSpigot()) {
 | 
			
		||||
                Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg)));
 | 
			
		||||
            } else {
 | 
			
		||||
                BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -87,4 +124,7 @@ public class TLogger {
 | 
			
		||||
        return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.FINE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static TLogger getUnformatted(String name) {
 | 
			
		||||
        return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.FINE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -40,10 +40,8 @@ public abstract class ActionBar {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void send(Player player, String text) {
 | 
			
		||||
            net.minecraft.server.v1_12_R1.ChatComponentText component = new net.minecraft.server.v1_12_R1.ChatComponentText(text);
 | 
			
		||||
            net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component,
 | 
			
		||||
                    net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
 | 
			
		||||
            net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component, net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
 | 
			
		||||
            ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,16 +13,15 @@ import java.util.Map;
 | 
			
		||||
public class AsmClassTransformer extends ClassVisitor implements Opcodes {
 | 
			
		||||
 | 
			
		||||
    private final Class<?> from;
 | 
			
		||||
 | 
			
		||||
    private final String fromVer, toVer;
 | 
			
		||||
 | 
			
		||||
    private final String fromVer;
 | 
			
		||||
    private final String toVer;
 | 
			
		||||
    private final ClassWriter writer;
 | 
			
		||||
 | 
			
		||||
    private String newClassName, prevName;
 | 
			
		||||
    private String newClassName;
 | 
			
		||||
    private String prevName;
 | 
			
		||||
 | 
			
		||||
    private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) {
 | 
			
		||||
        super(Opcodes.ASM6, classWriter);
 | 
			
		||||
        writer = classWriter;
 | 
			
		||||
        this.writer = classWriter;
 | 
			
		||||
        this.from = from;
 | 
			
		||||
        this.fromVer = fromVer;
 | 
			
		||||
        this.toVer = toVer;
 | 
			
		||||
@@ -67,9 +66,15 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
 | 
			
		||||
        super.visitInnerClass(replace(name), outerName, replace(name).substring(outerName.length() + 1), access);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
 | 
			
		||||
        super.visit(version, access, newClassName.replace('.', '/'), replace(signature), replace(superName), replace(interfaces));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String replace(String text) {
 | 
			
		||||
        if (text != null) {
 | 
			
		||||
            return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
 | 
			
		||||
            return text
 | 
			
		||||
                    .replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
 | 
			
		||||
                    .replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
 | 
			
		||||
                    .replace(prevName, newClassName.replace('.', '/'));
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -88,12 +93,6 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
 | 
			
		||||
        super.visit(version, access, newClassName.replace('.', '/'), replace(signature),
 | 
			
		||||
                replace(superName), replace(interfaces));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class AsmMethodTransformer extends MethodVisitor {
 | 
			
		||||
 | 
			
		||||
        AsmMethodTransformer(MethodVisitor visitor) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import com.ilummc.tlib.util.IO;
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
import me.skymc.taboolib.common.function.TFunctionLoader;
 | 
			
		||||
import me.skymc.taboolib.database.GlobalDataManager;
 | 
			
		||||
import me.skymc.taboolib.database.PlayerDataManager;
 | 
			
		||||
import me.skymc.taboolib.economy.EcoUtils;
 | 
			
		||||
@@ -198,6 +199,8 @@ public class Main extends JavaPlugin {
 | 
			
		||||
        HikariHandler.closeDataSourceForce();
 | 
			
		||||
        // 注销监听器
 | 
			
		||||
        TListenerHandler.cancelListeners();
 | 
			
		||||
        // 注销子模块
 | 
			
		||||
        TFunctionLoader.unloadFunction();
 | 
			
		||||
        // 结束数据库储存方法
 | 
			
		||||
        if (getStorageType() == StorageType.SQL) {
 | 
			
		||||
            GlobalDataManager.SQLMethod.cancelSQLMethod();
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,8 @@ public class TabooLib {
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        try {
 | 
			
		||||
            spigot = Bukkit.getConsoleSender() != null;
 | 
			
		||||
            Class.forName("org.bukkit.Bukkit");
 | 
			
		||||
            spigot = true;
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -32,6 +33,16 @@ public class TabooLib {
 | 
			
		||||
        return (Main) Main.getInst();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 插件是否为 TabooLib(沙雕方法)
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isTabooLib(Plugin plugin) {
 | 
			
		||||
        return plugin.equals(instance()) || plugin.getName().equals("TabooLib");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 插件是否依赖于 TabooLib(依赖或软兼容)
 | 
			
		||||
     *
 | 
			
		||||
@@ -66,7 +77,7 @@ public class TabooLib {
 | 
			
		||||
     * @return String
 | 
			
		||||
     */
 | 
			
		||||
    public static String getVersion() {
 | 
			
		||||
        return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
 | 
			
		||||
        return Bukkit.getServer().getClass().getName().split("\\.")[3];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -5,25 +5,45 @@ import com.ilummc.tlib.annotations.Dependency;
 | 
			
		||||
import com.ilummc.tlib.inject.TDependencyInjector;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.bstats.Metrics;
 | 
			
		||||
import me.skymc.taboolib.commands.language.Language2Command;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.listener.TListener;
 | 
			
		||||
import me.skymc.taboolib.listener.TListenerHandler;
 | 
			
		||||
import me.skymc.taboolib.playerdata.DataUtils;
 | 
			
		||||
import me.skymc.tlm.command.TLMCommands;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.EventPriority;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.server.PluginDisableEvent;
 | 
			
		||||
import org.bukkit.event.server.PluginEnableEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-08-23 17:04
 | 
			
		||||
 */
 | 
			
		||||
class TabooLibLoader {
 | 
			
		||||
@TListener
 | 
			
		||||
public class TabooLibLoader implements Listener {
 | 
			
		||||
 | 
			
		||||
    static HashMap<String, List<Class>> pluginClasses = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @EventHandler (priority = EventPriority.LOWEST)
 | 
			
		||||
    public void onEnable(PluginEnableEvent e) {
 | 
			
		||||
        pluginClasses.remove(e.getPlugin().getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler (priority = EventPriority.MONITOR)
 | 
			
		||||
    public void onDisable(PluginDisableEvent e) {
 | 
			
		||||
        setupClasses(e.getPlugin());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void setup() {
 | 
			
		||||
        testInternet();
 | 
			
		||||
@@ -33,10 +53,21 @@ class TabooLibLoader {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void register() {
 | 
			
		||||
        setupClasses();
 | 
			
		||||
        registerListener();
 | 
			
		||||
        registerMetrics();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取插件所有被读取到的类
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     * @return List
 | 
			
		||||
     */
 | 
			
		||||
    public static Optional<List<Class>> getPluginClasses(Plugin plugin) {
 | 
			
		||||
        return Optional.ofNullable(pluginClasses.get(plugin.getName()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化插件文件夹
 | 
			
		||||
     */
 | 
			
		||||
@@ -45,6 +76,40 @@ class TabooLibLoader {
 | 
			
		||||
        Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA")));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 载入插件数据库
 | 
			
		||||
     */
 | 
			
		||||
    static void setupDatabase() {
 | 
			
		||||
        DataUtils.addPluginData("TabooLibrary", null);
 | 
			
		||||
        // 检查是否启用数据库
 | 
			
		||||
        Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL);
 | 
			
		||||
        // 初始化数据库
 | 
			
		||||
        TabooLibDatabase.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 读取插件类
 | 
			
		||||
     */
 | 
			
		||||
    static void setupClasses() {
 | 
			
		||||
        Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TabooLibLoader::setupClasses);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 读取插件类
 | 
			
		||||
     */
 | 
			
		||||
    static void setupClasses(Plugin plugin) {
 | 
			
		||||
        if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            long time = System.currentTimeMillis();
 | 
			
		||||
            List<Class> classes = FileUtils.getClasses(plugin);
 | 
			
		||||
            TLocale.Logger.info("DEPENDENCY.LOAD-CLASSES", plugin.getName(), String.valueOf(classes.size()), String.valueOf(System.currentTimeMillis() - time));
 | 
			
		||||
            pluginClasses.put(plugin.getName(), classes);
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化插件依赖库
 | 
			
		||||
     */
 | 
			
		||||
@@ -84,17 +149,6 @@ class TabooLibLoader {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 载入插件数据库
 | 
			
		||||
     */
 | 
			
		||||
    static void setupDatabase() {
 | 
			
		||||
        DataUtils.addPluginData("TabooLibrary", null);
 | 
			
		||||
        // 检查是否启用数据库
 | 
			
		||||
        Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL);
 | 
			
		||||
        // 初始化数据库
 | 
			
		||||
        TabooLibDatabase.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 载入插件监听
 | 
			
		||||
     */
 | 
			
		||||
@@ -113,5 +167,4 @@ class TabooLibLoader {
 | 
			
		||||
        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))));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,78 +1,29 @@
 | 
			
		||||
package me.skymc.taboolib.anvil;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.nms.NMSUtils;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-09-08 15:47
 | 
			
		||||
 */
 | 
			
		||||
public class AnvilContainer {
 | 
			
		||||
public class AnvilContainer extends net.minecraft.server.v1_12_R1.ContainerAnvil {
 | 
			
		||||
 | 
			
		||||
//    private static IAnvilContainer instance;
 | 
			
		||||
    public AnvilContainer(net.minecraft.server.v1_12_R1.EntityHuman player) {
 | 
			
		||||
        super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Class<?> ChatMessage = NMSUtils.getNMSClass("ChatMessage");
 | 
			
		||||
    private static Class<?> PacketPlayOutOpenWindow = NMSUtils.getNMSClass("PacketPlayOutOpenWindow");
 | 
			
		||||
    private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
 | 
			
		||||
    private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
 | 
			
		||||
 | 
			
		||||
//    public static IAnvilContainer getInstance() {
 | 
			
		||||
//        return instance;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    static {
 | 
			
		||||
//        /*
 | 
			
		||||
//         * 玩不懂玩不懂... 似乎不会更改父类的包名?
 | 
			
		||||
//         */
 | 
			
		||||
//        instance = (IAnvilContainer) AsmClassTransformer.builder()
 | 
			
		||||
//                .from(AnvilContainerImpl.class)
 | 
			
		||||
//                .fromVersion("v1_12_R1")
 | 
			
		||||
//                .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3])
 | 
			
		||||
//                .build()
 | 
			
		||||
//                .transform();
 | 
			
		||||
//    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void openAnvil(Player p) {
 | 
			
		||||
        try {
 | 
			
		||||
            Object player = p.getClass().getMethod("getHandle").invoke(p);
 | 
			
		||||
            int c = (int) player.getClass().getMethod("nextContainerCounter").invoke(player);
 | 
			
		||||
            Object chatMessage = ChatMessage.getConstructor(String.class, Object[].class).newInstance("Repairing", new Object[0]);
 | 
			
		||||
            Object packetPlayOutOpenWindow = PacketPlayOutOpenWindow.getConstructor(Integer.TYPE, String.class, IChatBaseComponent, Integer.TYPE).newInstance(c, "minecraft:anvil", chatMessage, 0);
 | 
			
		||||
            Object playerConnection = player.getClass().getDeclaredField("playerConnection").get(player);
 | 
			
		||||
            playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packetPlayOutOpenWindow);
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
        net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
 | 
			
		||||
        AnvilContainer container = new AnvilContainer(player);
 | 
			
		||||
        int c = player.nextContainerCounter();
 | 
			
		||||
        player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
 | 
			
		||||
        player.activeContainer = container;
 | 
			
		||||
        player.activeContainer.windowId = c;
 | 
			
		||||
        player.activeContainer.addSlotListener(player);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//interface IAnvilContainer {
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * 打开铁砧界面
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param player 玩家
 | 
			
		||||
//     */
 | 
			
		||||
//    void openAnvil(Player player);
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//class AnvilContainerImpl extends net.minecraft.server.v1_12_R1.ContainerAnvil implements IAnvilContainer {
 | 
			
		||||
//
 | 
			
		||||
//    public AnvilContainerImpl(net.minecraft.server.v1_12_R1.EntityHuman player) {
 | 
			
		||||
//        super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public void openAnvil(Player p) {
 | 
			
		||||
//        net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
 | 
			
		||||
//        AnvilContainerImpl container = new AnvilContainerImpl(player);
 | 
			
		||||
//        int c = player.nextContainerCounter();
 | 
			
		||||
//        player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
 | 
			
		||||
//        player.activeContainer = container;
 | 
			
		||||
//        player.activeContainer.windowId = c;
 | 
			
		||||
//        player.activeContainer.addSlotListener(player);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
 | 
			
		||||
//        return true;
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +1,42 @@
 | 
			
		||||
package me.skymc.taboolib.anvil;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import com.ilummc.tlib.util.asm.AsmClassLoader;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.listener.TListener;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Sound;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryCloseEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryType;
 | 
			
		||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.meta.ItemMeta;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
 */
 | 
			
		||||
@TListener
 | 
			
		||||
public class AnvilContainerAPI implements Listener {
 | 
			
		||||
 | 
			
		||||
    public static List<String> list = new ArrayList<>();
 | 
			
		||||
    public static ItemStack item = new ItemStack(Material.NAME_TAG);
 | 
			
		||||
    public static HashMap<String, String> isOpen = new HashMap<>();
 | 
			
		||||
    public static AnvilContainerAPIEvent event;
 | 
			
		||||
    private static Class<?> impl;
 | 
			
		||||
 | 
			
		||||
    public static void send(Player p, String type, String str, List<String> lorelist) {
 | 
			
		||||
        isOpen.put(p.getName(), type);
 | 
			
		||||
 | 
			
		||||
        AnvilContainer.openAnvil(p);
 | 
			
		||||
        ItemMeta meta = item.getItemMeta();
 | 
			
		||||
 | 
			
		||||
        list.clear();
 | 
			
		||||
        if (lorelist == null) {
 | 
			
		||||
            list.addAll(TLocale.asStringList("ANVIL-CONTAINER.LORE-NORMAL"));
 | 
			
		||||
        } else {
 | 
			
		||||
            list = lorelist;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        meta.setLore(list);
 | 
			
		||||
        meta.setDisplayName(str);
 | 
			
		||||
        item.setItemMeta(meta);
 | 
			
		||||
 | 
			
		||||
        p.getOpenInventory().getTopInventory().setItem(0, item);
 | 
			
		||||
        p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void close(InventoryCloseEvent e) {
 | 
			
		||||
        if (isOpen.containsKey(e.getPlayer().getName())) {
 | 
			
		||||
            isOpen.remove(e.getPlayer().getName());
 | 
			
		||||
            if (e.getInventory().getType() == InventoryType.ANVIL) {
 | 
			
		||||
                e.getInventory().clear();
 | 
			
		||||
            }
 | 
			
		||||
    public AnvilContainerAPI() {
 | 
			
		||||
        try {
 | 
			
		||||
            impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerAsm.create(TabooLib.getVersion()));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void click(InventoryClickEvent e) {
 | 
			
		||||
        if (!isOpen.containsKey(e.getWhoClicked().getName())) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (e.getInventory().getType() != InventoryType.ANVIL) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        e.setCancelled(true);
 | 
			
		||||
 | 
			
		||||
        int slot = e.getRawSlot();
 | 
			
		||||
        if (slot != 2) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Inventory inv = e.getInventory();
 | 
			
		||||
        if (inv.getItem(2) == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (inv.getItem(2).getItemMeta().hasDisplayName()) {
 | 
			
		||||
            event = new AnvilContainerAPIEvent(e, isOpen.get(e.getWhoClicked().getName()), inv.getItem(2).getItemMeta().getDisplayName());
 | 
			
		||||
            e.getWhoClicked().closeInventory();
 | 
			
		||||
            Bukkit.getPluginManager().callEvent(event);
 | 
			
		||||
    public static void openAnvil(Player player) {
 | 
			
		||||
        try {
 | 
			
		||||
            impl.getMethod("openAnvil", Player.class).invoke(impl, player);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void example(PlayerCommandPreprocessEvent e) {
 | 
			
		||||
        if ("/anvilexample".equals(e.getMessage())) {
 | 
			
		||||
            if (e.getPlayer().hasPermission("taboolib.admin")) {
 | 
			
		||||
                e.setCancelled(true);
 | 
			
		||||
                AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", TLocale.asString("ANVIL-CONTAINER.NAME-EXAMPLE"), null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void example2(AnvilContainerAPIEvent e) {
 | 
			
		||||
        if ("EXAMPLE".equals(e.type)) {
 | 
			
		||||
            e.event.getWhoClicked().sendMessage(e.string);
 | 
			
		||||
        if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) {
 | 
			
		||||
            e.setCancelled(true);
 | 
			
		||||
            openAnvil(e.getPlayer());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.anvil;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.event.Event;
 | 
			
		||||
import org.bukkit.event.HandlerList;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
 | 
			
		||||
public class AnvilContainerAPIEvent extends Event {
 | 
			
		||||
 | 
			
		||||
    public static final HandlerList handlers = new HandlerList();
 | 
			
		||||
    public InventoryClickEvent event;
 | 
			
		||||
    public String string;
 | 
			
		||||
    public String type;
 | 
			
		||||
 | 
			
		||||
    public AnvilContainerAPIEvent(InventoryClickEvent e, String t, String s) {
 | 
			
		||||
        event = e;
 | 
			
		||||
        string = s;
 | 
			
		||||
        type = t;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static HandlerList getHandlerList() {
 | 
			
		||||
        return handlers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public HandlerList getHandlers() {
 | 
			
		||||
        return handlers;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
package me.skymc.taboolib.anvil;
 | 
			
		||||
 | 
			
		||||
import org.objectweb.asm.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
 */
 | 
			
		||||
public class AnvilContainerAsm {
 | 
			
		||||
 | 
			
		||||
    public static byte[] create(String version) {
 | 
			
		||||
 | 
			
		||||
        ClassWriter cw = new ClassWriter(0);
 | 
			
		||||
        FieldVisitor fv;
 | 
			
		||||
        MethodVisitor mv;
 | 
			
		||||
        AnnotationVisitor av0;
 | 
			
		||||
 | 
			
		||||
        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "me/skymc/taboolib/anvil/AnvilContainer", null, "net/minecraft/server/" + version + "/ContainerAnvil", null);
 | 
			
		||||
 | 
			
		||||
        cw.visitSource("AnvilContainer.java", null);
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", null, null);
 | 
			
		||||
            mv.visitCode();
 | 
			
		||||
            Label l0 = new Label();
 | 
			
		||||
            mv.visitLabel(l0);
 | 
			
		||||
            mv.visitLineNumber(12, l0);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 0);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "inventory", "Lnet/minecraft/server/" + version + "/PlayerInventory;");
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "world", "Lnet/minecraft/server/" + version + "/World;");
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/BlockPosition");
 | 
			
		||||
            mv.visitInsn(Opcodes.DUP);
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_0);
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_0);
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_0);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/BlockPosition", "<init>", "(III)V", false);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ContainerAnvil", "<init>", "(Lnet/minecraft/server/" + version + "/PlayerInventory;Lnet/minecraft/server/" + version + "/World;Lnet/minecraft/server/" + version + "/BlockPosition;Lnet/minecraft/server/" + version + "/EntityHuman;)V", false);
 | 
			
		||||
            Label l1 = new Label();
 | 
			
		||||
            mv.visitLabel(l1);
 | 
			
		||||
            mv.visitLineNumber(13, l1);
 | 
			
		||||
            mv.visitInsn(Opcodes.RETURN);
 | 
			
		||||
            Label l2 = new Label();
 | 
			
		||||
            mv.visitLabel(l2);
 | 
			
		||||
            mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l2, 0);
 | 
			
		||||
            mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l2, 1);
 | 
			
		||||
            mv.visitMaxs(8, 2);
 | 
			
		||||
            mv.visitEnd();
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "a", "(Lnet/minecraft/server/" + version + "/EntityHuman;)Z", null, null);
 | 
			
		||||
            mv.visitCode();
 | 
			
		||||
            Label l0 = new Label();
 | 
			
		||||
            mv.visitLabel(l0);
 | 
			
		||||
            mv.visitLineNumber(17, l0);
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_1);
 | 
			
		||||
            mv.visitInsn(Opcodes.IRETURN);
 | 
			
		||||
            Label l1 = new Label();
 | 
			
		||||
            mv.visitLabel(l1);
 | 
			
		||||
            mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l1, 0);
 | 
			
		||||
            mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l1, 1);
 | 
			
		||||
            mv.visitMaxs(1, 2);
 | 
			
		||||
            mv.visitEnd();
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "openAnvil", "(Lorg/bukkit/entity/Player;)V", null, null);
 | 
			
		||||
            mv.visitCode();
 | 
			
		||||
            Label l0 = new Label();
 | 
			
		||||
            mv.visitLabel(l0);
 | 
			
		||||
            mv.visitLineNumber(21, l0);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 0);
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.CHECKCAST, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer");
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer", "getHandle", "()Lnet/minecraft/server/" + version + "/EntityPlayer;", false);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ASTORE, 1);
 | 
			
		||||
            Label l1 = new Label();
 | 
			
		||||
            mv.visitLabel(l1);
 | 
			
		||||
            mv.visitLineNumber(22, l1);
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.NEW, "me/skymc/taboolib/anvil/AnvilContainer");
 | 
			
		||||
            mv.visitInsn(Opcodes.DUP);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "me/skymc/taboolib/anvil/AnvilContainer", "<init>", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", false);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ASTORE, 2);
 | 
			
		||||
            Label l2 = new Label();
 | 
			
		||||
            mv.visitLabel(l2);
 | 
			
		||||
            mv.visitLineNumber(23, l2);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/EntityPlayer", "nextContainerCounter", "()I", false);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ISTORE, 3);
 | 
			
		||||
            Label l3 = new Label();
 | 
			
		||||
            mv.visitLabel(l3);
 | 
			
		||||
            mv.visitLineNumber(24, l3);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "playerConnection", "Lnet/minecraft/server/" + version + "/PlayerConnection;");
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow");
 | 
			
		||||
            mv.visitInsn(Opcodes.DUP);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ILOAD, 3);
 | 
			
		||||
            mv.visitLdcInsn("minecraft:anvil");
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/ChatMessage");
 | 
			
		||||
            mv.visitInsn(Opcodes.DUP);
 | 
			
		||||
            mv.visitLdcInsn("Repairing");
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_0);
 | 
			
		||||
            mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ChatMessage", "<init>", "(Ljava/lang/String;[Ljava/lang/Object;)V", false);
 | 
			
		||||
            mv.visitInsn(Opcodes.ICONST_0);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow", "<init>", "(ILjava/lang/String;Lnet/minecraft/server/" + version + "/IChatBaseComponent;I)V", false);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/PlayerConnection", "sendPacket", "(Lnet/minecraft/server/" + version + "/Packet;)V", false);
 | 
			
		||||
            Label l4 = new Label();
 | 
			
		||||
            mv.visitLabel(l4);
 | 
			
		||||
            mv.visitLineNumber(25, l4);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 2);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
 | 
			
		||||
            Label l5 = new Label();
 | 
			
		||||
            mv.visitLabel(l5);
 | 
			
		||||
            mv.visitLineNumber(26, l5);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ILOAD, 3);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/Container", "windowId", "I");
 | 
			
		||||
            Label l6 = new Label();
 | 
			
		||||
            mv.visitLabel(l6);
 | 
			
		||||
            mv.visitLineNumber(27, l6);
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
 | 
			
		||||
            mv.visitVarInsn(Opcodes.ALOAD, 1);
 | 
			
		||||
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/Container", "addSlotListener", "(Lnet/minecraft/server/" + version + "/ICrafting;)V", false);
 | 
			
		||||
            Label l7 = new Label();
 | 
			
		||||
            mv.visitLabel(l7);
 | 
			
		||||
            mv.visitLineNumber(28, l7);
 | 
			
		||||
            mv.visitInsn(Opcodes.RETURN);
 | 
			
		||||
            Label l8 = new Label();
 | 
			
		||||
            mv.visitLabel(l8);
 | 
			
		||||
            mv.visitLocalVariable("p", "Lorg/bukkit/entity/Player;", null, l0, l8, 0);
 | 
			
		||||
            mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityPlayer;", null, l1, l8, 1);
 | 
			
		||||
            mv.visitLocalVariable("container", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l2, l8, 2);
 | 
			
		||||
            mv.visitLocalVariable("c", "I", null, l3, l8, 3);
 | 
			
		||||
            mv.visitMaxs(9, 4);
 | 
			
		||||
            mv.visitEnd();
 | 
			
		||||
        }
 | 
			
		||||
        cw.visitEnd();
 | 
			
		||||
 | 
			
		||||
        return cw.toByteArray();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,86 @@
 | 
			
		||||
package me.skymc.taboolib.common.configuration;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.ilummc.tlib.logger.TLogger;
 | 
			
		||||
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.util.Optional;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-09-08 15:00
 | 
			
		||||
 */
 | 
			
		||||
public class TConfiguration extends YamlConfiguration {
 | 
			
		||||
 | 
			
		||||
    private File file;
 | 
			
		||||
    private Runnable runnable;
 | 
			
		||||
 | 
			
		||||
    private TConfiguration(File file) {
 | 
			
		||||
        this.file = file;
 | 
			
		||||
        reload();
 | 
			
		||||
        TLib.getTLib().getConfigWatcher().addSimpleListener(this.file, this::reload);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 释放文件监听
 | 
			
		||||
     */
 | 
			
		||||
    public void release() {
 | 
			
		||||
        TLib.getTLib().getConfigWatcher().removeListener(file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 重新载入配置
 | 
			
		||||
     */
 | 
			
		||||
    public void reload() {
 | 
			
		||||
        try {
 | 
			
		||||
            load(file);
 | 
			
		||||
            Optional.ofNullable(runnable).ifPresent(Runnable::run);
 | 
			
		||||
        } catch (IOException | InvalidConfigurationException e) {
 | 
			
		||||
            TLogger.getGlobalLogger().warn("Cannot load configuration from stream: " + e.toString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建配置文件
 | 
			
		||||
     *
 | 
			
		||||
     * @param file 文件
 | 
			
		||||
     * @return {@link TConfiguration}
 | 
			
		||||
     */
 | 
			
		||||
    public static TConfiguration create(File file) {
 | 
			
		||||
        return new TConfiguration(file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 从插件里释放文件并创建
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     * @param path   目录
 | 
			
		||||
     * @return {@link TConfiguration}
 | 
			
		||||
     */
 | 
			
		||||
    public static TConfiguration createInResource(Plugin plugin, String path) {
 | 
			
		||||
        File file = new File(plugin.getDataFolder(), path);
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
            plugin.saveResource(path, true);
 | 
			
		||||
        }
 | 
			
		||||
        return create(file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
    public File getFile() {
 | 
			
		||||
        return file;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TConfiguration listener(Runnable runnable) {
 | 
			
		||||
        this.runnable = runnable;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
package me.skymc.taboolib.common.function;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-09-08 14:01
 | 
			
		||||
 */
 | 
			
		||||
@Target(ElementType.TYPE)
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
public @interface TFunction {
 | 
			
		||||
 | 
			
		||||
    String enable() default "onEnable";
 | 
			
		||||
    String disable() default "onDisable";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,90 @@
 | 
			
		||||
package me.skymc.taboolib.common.function;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.TabooLibLoader;
 | 
			
		||||
import me.skymc.taboolib.listener.TListener;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.server.PluginDisableEvent;
 | 
			
		||||
import org.bukkit.event.server.PluginEnableEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-09-08 14:00
 | 
			
		||||
 */
 | 
			
		||||
@TListener
 | 
			
		||||
public class TFunctionLoader implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static HashMap<String, List<Class>> pluginFunction = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    TFunctionLoader() {
 | 
			
		||||
        loadFunction();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void loadFunction() {
 | 
			
		||||
        Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::loadFunction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void loadFunction(Plugin plugin) {
 | 
			
		||||
        if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
 | 
			
		||||
            for (Class pluginClass : classes) {
 | 
			
		||||
                if (pluginClass.isAnnotationPresent(TFunction.class)) {
 | 
			
		||||
                    TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class);
 | 
			
		||||
                    try {
 | 
			
		||||
                        Method method = pluginClass.getDeclaredMethod(function.enable());
 | 
			
		||||
                        if (method == null) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        method.setAccessible(true);
 | 
			
		||||
                        method.invoke(pluginClass.newInstance());
 | 
			
		||||
                        pluginFunction.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(pluginClass);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void unloadFunction() {
 | 
			
		||||
        Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::unloadFunction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void unloadFunction(Plugin plugin) {
 | 
			
		||||
        Optional.ofNullable(pluginFunction.remove(plugin.getName())).ifPresent(classes -> {
 | 
			
		||||
            for (Class pluginClass : classes) {
 | 
			
		||||
                if (pluginClass.isAnnotationPresent(TFunction.class)) {
 | 
			
		||||
                    TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class);
 | 
			
		||||
                    try {
 | 
			
		||||
                        Method method = pluginClass.getDeclaredMethod(function.disable());
 | 
			
		||||
                        if (method == null) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        method.setAccessible(true);
 | 
			
		||||
                        method.invoke(pluginClass.newInstance());
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onEnable(PluginEnableEvent e) {
 | 
			
		||||
        loadFunction(e.getPlugin());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onDisable(PluginDisableEvent e) {
 | 
			
		||||
        unloadFunction(e.getPlugin());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,9 @@ package me.skymc.taboolib.listener;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.TabooLibLoader;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.methods.ReflectionUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.HandlerList;
 | 
			
		||||
@@ -43,28 +45,26 @@ public class TListenerHandler implements Listener {
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     */
 | 
			
		||||
    public static void setupListener(Plugin plugin) {
 | 
			
		||||
        if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        List<Class> classes = FileUtils.getClasses(plugin);
 | 
			
		||||
        for (Class<?> pluginClass : classes) {
 | 
			
		||||
            if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
 | 
			
		||||
                try {
 | 
			
		||||
                    TListener tListener = pluginClass.getAnnotation(TListener.class);
 | 
			
		||||
                    // 检查注册条件
 | 
			
		||||
                    if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
 | 
			
		||||
                        if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
 | 
			
		||||
                            continue;
 | 
			
		||||
        TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
 | 
			
		||||
            for (Class<?> pluginClass : classes) {
 | 
			
		||||
                if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        TListener tListener = pluginClass.getAnnotation(TListener.class);
 | 
			
		||||
                        // 检查注册条件
 | 
			
		||||
                        if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
 | 
			
		||||
                            if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        // 实例化监听器
 | 
			
		||||
                        Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) ReflectionUtils.instantiateObject(pluginClass);
 | 
			
		||||
                        listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                    // 实例化监听器
 | 
			
		||||
                    Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance();
 | 
			
		||||
                    listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
@Deprecated
 | 
			
		||||
public class MsgUtils {
 | 
			
		||||
 | 
			
		||||
    public static void send(CommandSender sender, String s) {
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,9 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.object;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.util.Ref;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.TabooLibLoader;
 | 
			
		||||
import me.skymc.taboolib.listener.TListener;
 | 
			
		||||
import me.skymc.taboolib.methods.ReflectionUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
@@ -19,11 +19,11 @@ import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 * @Since 2018-08-27 10:04
 | 
			
		||||
 */
 | 
			
		||||
@TListener
 | 
			
		||||
public class InstanceHandler implements Listener {
 | 
			
		||||
public class InstantiableLoader implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static ConcurrentHashMap<String, Object> instance = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
    public InstanceHandler() {
 | 
			
		||||
    public InstantiableLoader() {
 | 
			
		||||
        loadInstantiable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -52,19 +52,18 @@ public class InstanceHandler implements Listener {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void loadInstantiable(Plugin plugin) {
 | 
			
		||||
        if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        for (Class pluginClass : FileUtils.getClasses(plugin)) {
 | 
			
		||||
            if (pluginClass.isAnnotationPresent(Instantiable.class)) {
 | 
			
		||||
                Instantiable instantiable = (Instantiable) pluginClass.getAnnotation(Instantiable.class);
 | 
			
		||||
                try {
 | 
			
		||||
                    instance.put(instantiable.value(), pluginClass.newInstance());
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
        TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
 | 
			
		||||
            for (Class pluginClass : classes) {
 | 
			
		||||
                if (pluginClass.isAnnotationPresent(Instantiable.class)) {
 | 
			
		||||
                    Instantiable instantiable = (Instantiable) pluginClass.getAnnotation(Instantiable.class);
 | 
			
		||||
                    try {
 | 
			
		||||
                        instance.put(instantiable.value(), ReflectionUtils.instantiateObject(pluginClass));
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
@@ -28,6 +28,7 @@ DEPENDENCY:
 | 
			
		||||
  LIBRARY-LOAD-SUCCESS: '  {0} 请求的库文件 {1} 加载成功'
 | 
			
		||||
  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 注解'
 | 
			
		||||
@@ -112,13 +113,6 @@ LANGUAGE2:
 | 
			
		||||
TIMECYCLE:
 | 
			
		||||
  FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
 | 
			
		||||
  
 | 
			
		||||
ANVIL-CONTAINER:
 | 
			
		||||
  NAME-EXAMPLE: '在这里输入文本'
 | 
			
		||||
  LORE-NORMAL:
 | 
			
		||||
  - ''
 | 
			
		||||
  - '&7在上方文本框内输入信息'
 | 
			
		||||
  - '&7随后点击右侧输出物品'
 | 
			
		||||
  
 | 
			
		||||
UPDATETASK:
 | 
			
		||||
  VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
 | 
			
		||||
  VERSION-LATEST: '&7插件已是最新版, 无需更新!'
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user