完善 @TCommand 注解
新增 TCommandHandler 类用于动态命令注册
This commit is contained in:
		@@ -12,6 +12,7 @@ import sun.reflect.Reflection;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.concurrent.ThreadSafe;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,58 +1,37 @@
 | 
			
		||||
package me.skymc.taboolib;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.ilummc.tlib.annotations.Dependency;
 | 
			
		||||
import com.ilummc.tlib.inject.TDependencyInjector;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import com.ilummc.tlib.util.IO;
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
import me.skymc.taboolib.anvil.AnvilContainerAPI;
 | 
			
		||||
import me.skymc.taboolib.bstats.Metrics;
 | 
			
		||||
import me.skymc.taboolib.commands.TabooLibExecuteCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.TabooLibMainCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.TBaseCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.language.Language2Command;
 | 
			
		||||
import me.skymc.taboolib.commands.locale.TabooLibLocaleCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.plugin.TabooLibPluginCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.taboolib.listener.ListenerItemListCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.taboolib.listener.ListenerSoundsCommand;
 | 
			
		||||
import me.skymc.taboolib.database.GlobalDataManager;
 | 
			
		||||
import me.skymc.taboolib.database.PlayerDataManager;
 | 
			
		||||
import me.skymc.taboolib.economy.EcoUtils;
 | 
			
		||||
import me.skymc.taboolib.entity.EntityUtils;
 | 
			
		||||
import me.skymc.taboolib.fileutils.ConfigUtils;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.fileutils.TLogs;
 | 
			
		||||
import me.skymc.taboolib.inventory.ItemUtils;
 | 
			
		||||
import me.skymc.taboolib.inventory.speciaitem.SpecialItem;
 | 
			
		||||
import me.skymc.taboolib.itagapi.TagDataHandler;
 | 
			
		||||
import me.skymc.taboolib.javascript.ScriptHandler;
 | 
			
		||||
import me.skymc.taboolib.javashell.JavaShell;
 | 
			
		||||
import me.skymc.taboolib.listener.*;
 | 
			
		||||
import me.skymc.taboolib.message.ChatCatcher;
 | 
			
		||||
import me.skymc.taboolib.listener.TListenerHandler;
 | 
			
		||||
import me.skymc.taboolib.mysql.hikari.HikariHandler;
 | 
			
		||||
import me.skymc.taboolib.mysql.protect.MySQLConnection;
 | 
			
		||||
import me.skymc.taboolib.nms.item.DabItemUtils;
 | 
			
		||||
import me.skymc.taboolib.other.NumberUtils;
 | 
			
		||||
import me.skymc.taboolib.permission.PermissionUtils;
 | 
			
		||||
import me.skymc.taboolib.playerdata.DataUtils;
 | 
			
		||||
import me.skymc.taboolib.sign.SignUtils;
 | 
			
		||||
import me.skymc.taboolib.skript.SkriptHandler;
 | 
			
		||||
import me.skymc.taboolib.socket.TabooLibClient;
 | 
			
		||||
import me.skymc.taboolib.string.StringUtils;
 | 
			
		||||
import me.skymc.taboolib.string.language2.Language2;
 | 
			
		||||
import me.skymc.taboolib.support.SupportPlaceholder;
 | 
			
		||||
import me.skymc.taboolib.timecycle.TimeCycleManager;
 | 
			
		||||
import me.skymc.taboolib.translateuuid.TranslateUUID;
 | 
			
		||||
import me.skymc.taboolib.translateuuid.TranslateUUIDCommand;
 | 
			
		||||
import me.skymc.taboolib.update.UpdateTask;
 | 
			
		||||
import me.skymc.tlm.TLM;
 | 
			
		||||
import me.skymc.tlm.command.TLMCommands;
 | 
			
		||||
import me.skymc.tlm.module.TabooLibraryModule;
 | 
			
		||||
import net.milkbowl.vault.economy.Economy;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.configuration.file.FileConfiguration;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
@@ -60,11 +39,9 @@ import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
@@ -118,7 +95,7 @@ public class Main extends JavaPlugin {
 | 
			
		||||
        TLib.init();
 | 
			
		||||
        TLib.injectPluginManager();
 | 
			
		||||
        // 载入插件设置
 | 
			
		||||
        TabooLibSettings.setup();
 | 
			
		||||
        TabooLibLoader.setup();
 | 
			
		||||
        // 载入大饼
 | 
			
		||||
        TLib.initPost();
 | 
			
		||||
        // 载入连接池
 | 
			
		||||
@@ -128,7 +105,7 @@ public class Main extends JavaPlugin {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        // 注册插件配置
 | 
			
		||||
        TabooLibSettings.register();
 | 
			
		||||
        TabooLibLoader.register();
 | 
			
		||||
        // 载入经济
 | 
			
		||||
        EcoUtils.setupEconomy();
 | 
			
		||||
        // 载入权限
 | 
			
		||||
@@ -211,8 +188,6 @@ public class Main extends JavaPlugin {
 | 
			
		||||
        DataUtils.saveAllCaches();
 | 
			
		||||
        // 保存玩家数据
 | 
			
		||||
        PlayerDataManager.saveAllPlayers(false, true);
 | 
			
		||||
        // 结束脚本
 | 
			
		||||
        JavaShell.javaShellCancel();
 | 
			
		||||
        // 注销 SpecialItem 接口
 | 
			
		||||
        SpecialItem.getInst().unloadItems();
 | 
			
		||||
        // 注销 TLM 接口
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ import java.util.stream.Collectors;
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-08-23 17:04
 | 
			
		||||
 */
 | 
			
		||||
class TabooLibSettings {
 | 
			
		||||
class TabooLibLoader {
 | 
			
		||||
 | 
			
		||||
    static void setup() {
 | 
			
		||||
        testInternet();
 | 
			
		||||
@@ -33,8 +33,8 @@ class TabooLibSettings {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void register() {
 | 
			
		||||
        registerCommands();
 | 
			
		||||
        registerListener();
 | 
			
		||||
        registerCommands();
 | 
			
		||||
        registerMetrics();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -19,7 +19,7 @@ public class LogClient extends JFrame {
 | 
			
		||||
		super(title);
 | 
			
		||||
		
 | 
			
		||||
		// DEFAULT CLOSE OPERATION
 | 
			
		||||
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 | 
			
		||||
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 | 
			
		||||
		
 | 
			
		||||
		// SETTINGS
 | 
			
		||||
		final JScrollPane scrollPane = new JScrollPane();
 | 
			
		||||
@@ -37,30 +37,21 @@ public class LogClient extends JFrame {
 | 
			
		||||
		textArea.setBackground(Color.black);
 | 
			
		||||
		textArea.setForeground(Color.LIGHT_GRAY);
 | 
			
		||||
		
 | 
			
		||||
		addstr(title);
 | 
			
		||||
		addstr("");
 | 
			
		||||
		addString(title);
 | 
			
		||||
		addString("");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public void addString(String a) {
 | 
			
		||||
		
 | 
			
		||||
		textArea.append("[" + sdf.format(System.currentTimeMillis()) + " NONE]: " + a + '\n');
 | 
			
		||||
		textArea.setSelectionStart(textArea.getText().length());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addstr(String a) {
 | 
			
		||||
		
 | 
			
		||||
		textArea.append(a + '\n');
 | 
			
		||||
		textArea.setSelectionStart(textArea.getText().length());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void info(String a) {
 | 
			
		||||
		
 | 
			
		||||
		textArea.append("[" + sdf.format(System.currentTimeMillis()) + " INFO]: " + a + '\n');
 | 
			
		||||
		textArea.setSelectionStart(textArea.getText().length());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void warn(String a) {
 | 
			
		||||
		
 | 
			
		||||
		textArea.append("[" + sdf.format(System.currentTimeMillis()) + " WARN]: " + a + '\n');
 | 
			
		||||
		textArea.setSelectionStart(textArea.getText().length());
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,11 @@ import org.bukkit.event.server.ServerCommandEvent;
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-07-04 21:32
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "taboolibexecute")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "taboolibexecute",
 | 
			
		||||
        aliases = {"texecute"},
 | 
			
		||||
        permission = "taboolib.admin"
 | 
			
		||||
)
 | 
			
		||||
public class TabooLibExecuteCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -28,13 +28,18 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-09 21:38
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "taboolib")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "taboolib",
 | 
			
		||||
        permission = "taboolib.admin",
 | 
			
		||||
        aliases = "tlib"
 | 
			
		||||
)
 | 
			
		||||
public class TabooLibMainCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -563,72 +568,7 @@ public class TabooLibMainCommand extends BaseMainCommand {
 | 
			
		||||
    @CommandRegister(priority = 17)
 | 
			
		||||
    BaseSubCommand getEmptyLine4 = null;
 | 
			
		||||
 | 
			
		||||
    @CommandRegister(priority = 18)
 | 
			
		||||
    BaseSubCommand shellLoad = new BaseSubCommand() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getLabel() {
 | 
			
		||||
            return "shellLoad";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getDescription() {
 | 
			
		||||
            return TLocale.asString("COMMANDS.TABOOLIB.JAVASHELL.DESCRIPTION.LOAD");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{
 | 
			
		||||
                    new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.JAVASHELL.ARGUMENTS.LOAD.0"))
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onCommand(CommandSender sender, Command command, String label, String[] args) {
 | 
			
		||||
            new ShellLoadCommand(sender, args);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean ignoredLabel() {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @CommandRegister(priority = 19)
 | 
			
		||||
    BaseSubCommand shellUnload = new BaseSubCommand() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getLabel() {
 | 
			
		||||
            return "shellUnload";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getDescription() {
 | 
			
		||||
            return TLocale.asString("COMMANDS.TABOOLIB.JAVASHELL.DESCRIPTION.UNLOAD");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{
 | 
			
		||||
                    new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.JAVASHELL.ARGUMENTS.UNLOAD.0"))
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onCommand(CommandSender sender, Command command, String label, String[] args) {
 | 
			
		||||
            new ShellUnloadCommand(sender, args);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean ignoredLabel() {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @CommandRegister(priority = 20)
 | 
			
		||||
    BaseSubCommand getEmptyLine5 = null;
 | 
			
		||||
 | 
			
		||||
    @CommandRegister(priority = 20.5)
 | 
			
		||||
    BaseSubCommand tagDisplay = new BaseSubCommand() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,21 @@ import java.util.stream.Collectors;
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 21:38
 | 
			
		||||
 */
 | 
			
		||||
public abstract class BaseMainCommand implements IMainCommand, CommandExecutor, TabExecutor {
 | 
			
		||||
public abstract class BaseMainCommand implements CommandExecutor, TabExecutor {
 | 
			
		||||
 | 
			
		||||
    private PluginCommand registerCommand;
 | 
			
		||||
    private List<Class<?>> linkClasses = new CopyOnWriteArrayList<>();
 | 
			
		||||
    private List<BaseSubCommand> subCommands = new CopyOnWriteArrayList<>();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令标题
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    abstract public String getCommandTitle();
 | 
			
		||||
 | 
			
		||||
    public static BaseMainCommand createCommandExecutor(String command, BaseMainCommand baseMainCommand) {
 | 
			
		||||
        Preconditions.checkArgument(Bukkit.getPluginCommand(command) != null, "PluginCommand \"" + command + "\"not found");
 | 
			
		||||
        Preconditions.checkArgument(Bukkit.getPluginCommand(command) != null, "PluginCommand \"" + command + "\" not found");
 | 
			
		||||
        Preconditions.checkArgument(baseMainCommand != null, "Executor cannot be null");
 | 
			
		||||
        Preconditions.checkArgument(baseMainCommand.getClass() != BaseMainCommand.class, "Executor can not be \"BaseMainCommand.class\"");
 | 
			
		||||
        baseMainCommand.setRegisterCommand(Bukkit.getPluginCommand(command));
 | 
			
		||||
@@ -99,6 +106,11 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
 | 
			
		||||
        subCommands.add(subCommand);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
 | 
			
		||||
        return args.length == 1 ? subCommands.stream().filter(subCommand -> subCommand != null && hasPermission(commandSender, subCommand) && (args[0].isEmpty() || subCommand.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList()) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
@@ -134,11 +146,6 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
 | 
			
		||||
        return args.length == 1 ? subCommands.stream().filter(subCommand -> subCommand != null && hasPermission(commandSender, subCommand) && (args[0].isEmpty() || subCommand.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(ISubCommand::getLabel).collect(Collectors.toList()) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "registerCommand=" + "BaseMainCommand{" + registerCommand + ", linkClasses=" + linkClasses + ", subCommands=" + subCommands + '}';
 | 
			
		||||
@@ -161,6 +168,12 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
 | 
			
		||||
        return Objects.hash(getRegisterCommand(), getLinkClasses(), getSubCommands());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Private Methods
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
    private String getEmptyLine() {
 | 
			
		||||
        return TabooLib.getVerint() < 10800 ? "~" : "";
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,10 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.type.CommandType;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@@ -11,28 +14,91 @@ import java.util.stream.IntStream;
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-17
 | 
			
		||||
 */
 | 
			
		||||
public abstract class BaseSubCommand implements ISubCommand {
 | 
			
		||||
public abstract class BaseSubCommand {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令名
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    abstract public String getLabel();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令描述
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    abstract public String getDescription();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令参数
 | 
			
		||||
     *
 | 
			
		||||
     * @return {@link CommandArgument}
 | 
			
		||||
     */
 | 
			
		||||
    abstract public CommandArgument[] getArguments();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令执行方法
 | 
			
		||||
     *
 | 
			
		||||
     * @param sender  指令使用者
 | 
			
		||||
     * @param command 指令对象
 | 
			
		||||
     * @param label   主命令
 | 
			
		||||
     * @param args    参数(不含主命令及子命令)
 | 
			
		||||
     */
 | 
			
		||||
    abstract public void onCommand(CommandSender sender, Command command, String label, String[] args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令执行者
 | 
			
		||||
     *
 | 
			
		||||
     * @return {@link CommandType}
 | 
			
		||||
     */
 | 
			
		||||
    public CommandType getType() {
 | 
			
		||||
        return CommandType.ALL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 参数是否屏蔽子命令名
 | 
			
		||||
     *
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public boolean ignoredLabel() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否需要玩家在线
 | 
			
		||||
     *
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public boolean requiredPlayer() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 需要权限
 | 
			
		||||
     *
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public String getPermission() {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 参数是否符合
 | 
			
		||||
     *
 | 
			
		||||
     * @param args 参数
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isParameterConform(String[] args) {
 | 
			
		||||
        return IntStream.range(0, getArguments().length).noneMatch(i -> getArguments()[i].isRequired() && (args == null || args.length <= i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取帮助文本
 | 
			
		||||
     *
 | 
			
		||||
     * @param label 子命令标题
 | 
			
		||||
     * @return String
 | 
			
		||||
     */
 | 
			
		||||
    public String getCommandString(String label) {
 | 
			
		||||
        String stringBuilder = Arrays.stream(getArguments()).map(parameter -> parameter.toString() + " ").collect(Collectors.joining());
 | 
			
		||||
        return TLocale.asString("COMMANDS.INTERNAL.COMMAND-HELP", label, getLabel(), stringBuilder.trim(), getDescription());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 21:36
 | 
			
		||||
 */
 | 
			
		||||
public interface IMainCommand {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令标题
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    String getCommandTitle();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-17
 | 
			
		||||
 */
 | 
			
		||||
public interface ISubCommand {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令名
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    String getLabel();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令描述
 | 
			
		||||
     *
 | 
			
		||||
     * @return 文本
 | 
			
		||||
     */
 | 
			
		||||
    String getDescription();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令参数
 | 
			
		||||
     *
 | 
			
		||||
     * @return {@link CommandArgument}
 | 
			
		||||
     */
 | 
			
		||||
    CommandArgument[] getArguments();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 指令执行方法
 | 
			
		||||
     *
 | 
			
		||||
     * @param sender 指令使用者
 | 
			
		||||
     * @param command 指令对象
 | 
			
		||||
     * @param label 主命令
 | 
			
		||||
     * @param args 参数(不含主命令及子命令)
 | 
			
		||||
     */
 | 
			
		||||
    void onCommand(CommandSender sender, Command command, String label, String[] args);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
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.PluginEnableEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-23 2:43
 | 
			
		||||
 */
 | 
			
		||||
@TListener(register = "onLoad")
 | 
			
		||||
public class TBaseCommand implements Listener {
 | 
			
		||||
 | 
			
		||||
    void onLoad() {
 | 
			
		||||
        registerCommands();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 向服务端注册 BaseMainCommand 类
 | 
			
		||||
     *
 | 
			
		||||
     * @param command         命令全称(需在 plugin.yml 内注册)
 | 
			
		||||
     * @param baseMainCommand 命令对象
 | 
			
		||||
     * @return {@link BaseMainCommand}
 | 
			
		||||
     */
 | 
			
		||||
    public static BaseMainCommand registerCommand(String command, BaseMainCommand baseMainCommand) {
 | 
			
		||||
        return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册所有插件的所有 TCommand 命令
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerCommands() {
 | 
			
		||||
        for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
 | 
			
		||||
            try {
 | 
			
		||||
                registerCommand(plugin);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册插件的所有 TCommand 命令
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerCommand(Plugin plugin) {
 | 
			
		||||
        for (Class pluginClass : FileUtils.getClasses(plugin)) {
 | 
			
		||||
            if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
 | 
			
		||||
                TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
 | 
			
		||||
                try {
 | 
			
		||||
                    registerCommand(tCommand.name(), (BaseMainCommand) pluginClass.newInstance());
 | 
			
		||||
                } catch (InstantiationException | IllegalAccessException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onEnable(PluginEnableEvent e) {
 | 
			
		||||
        try {
 | 
			
		||||
            registerCommand(e.getPlugin());
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
@@ -15,4 +16,13 @@ public @interface TCommand {
 | 
			
		||||
 | 
			
		||||
    String name();
 | 
			
		||||
 | 
			
		||||
    String permission() default "";
 | 
			
		||||
 | 
			
		||||
    String permissionMessage() default "";
 | 
			
		||||
 | 
			
		||||
    String description() default "";
 | 
			
		||||
 | 
			
		||||
    String usage() default "";
 | 
			
		||||
 | 
			
		||||
    String[] aliases() default "";
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,181 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.listener.TListener;
 | 
			
		||||
import me.skymc.taboolib.methods.ReflectionUtils;
 | 
			
		||||
import me.skymc.taboolib.string.ArrayUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.command.*;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.server.PluginEnableEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-23 2:43
 | 
			
		||||
 */
 | 
			
		||||
@TListener
 | 
			
		||||
public class TCommandHandler implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static SimpleCommandMap commandMap;
 | 
			
		||||
 | 
			
		||||
    public TCommandHandler() {
 | 
			
		||||
        try {
 | 
			
		||||
            Field commandMap = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
 | 
			
		||||
            commandMap.setAccessible(true);
 | 
			
		||||
            TCommandHandler.commandMap = (SimpleCommandMap) commandMap.get(Bukkit.getPluginManager());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            registerCommands();
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onEnable(PluginEnableEvent e) {
 | 
			
		||||
        try {
 | 
			
		||||
            registerCommand(e.getPlugin());
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor) {
 | 
			
		||||
        return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
 | 
			
		||||
        return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, String description, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
 | 
			
		||||
        return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
 | 
			
		||||
        return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
 | 
			
		||||
        return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 向服务端动态注册命令
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin            所属插件
 | 
			
		||||
     * @param command           命令名称
 | 
			
		||||
     * @param description       命令描述
 | 
			
		||||
     * @param usage             命令用法
 | 
			
		||||
     * @param aliases           别名
 | 
			
		||||
     * @param permission        权限
 | 
			
		||||
     * @param permissionMessage 权限提示
 | 
			
		||||
     * @param commandExecutor   命令执行器
 | 
			
		||||
     * @param tabExecutor       补全执行器
 | 
			
		||||
     * @return 注册结果(boolean)
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
 | 
			
		||||
        try {
 | 
			
		||||
            Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
 | 
			
		||||
            constructor.setAccessible(true);
 | 
			
		||||
            PluginCommand pluginCommand = constructor.newInstance(command, plugin);
 | 
			
		||||
            pluginCommand.setExecutor(commandExecutor);
 | 
			
		||||
            pluginCommand.setTabCompleter(tabExecutor);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "description", description);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "activeAliases", aliases);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission);
 | 
			
		||||
            ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
 | 
			
		||||
            commandMap.register(command, pluginCommand);
 | 
			
		||||
            TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage());
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 向服务端注册 BaseMainCommand 类
 | 
			
		||||
     *
 | 
			
		||||
     * @param command         命令全称(需在 plugin.yml 内注册)
 | 
			
		||||
     * @param baseMainCommand 命令对象
 | 
			
		||||
     * @return {@link BaseMainCommand}
 | 
			
		||||
     */
 | 
			
		||||
    public static BaseMainCommand registerCommand(TCommand tCommand, String command, BaseMainCommand baseMainCommand, Plugin plugin) {
 | 
			
		||||
        if (Bukkit.getPluginCommand(command) == null) {
 | 
			
		||||
            registerPluginCommand(
 | 
			
		||||
                    plugin,
 | 
			
		||||
                    command,
 | 
			
		||||
                    ArrayUtils.skipEmpty(tCommand.description(), "Registered by TabooLib."),
 | 
			
		||||
                    ArrayUtils.skipEmpty(tCommand.usage(), "/" + command),
 | 
			
		||||
                    ArrayUtils.skipEmpty(ArrayUtils.asList(tCommand.aliases()), new ArrayList<>()),
 | 
			
		||||
                    ArrayUtils.skipEmpty(tCommand.permission()),
 | 
			
		||||
                    ArrayUtils.skipEmpty(tCommand.permissionMessage()),
 | 
			
		||||
                    baseMainCommand,
 | 
			
		||||
                    baseMainCommand);
 | 
			
		||||
        }
 | 
			
		||||
        return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册所有插件的所有 TCommand 命令
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerCommands() {
 | 
			
		||||
        for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
 | 
			
		||||
            try {
 | 
			
		||||
                registerCommand(plugin);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册插件的所有 TCommand 命令
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin 插件
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerCommand(Plugin plugin) {
 | 
			
		||||
        for (Class pluginClass : FileUtils.getClasses(plugin)) {
 | 
			
		||||
            if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
 | 
			
		||||
                TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
 | 
			
		||||
                try {
 | 
			
		||||
                    registerCommand(tCommand, tCommand.name(), (BaseMainCommand) pluginClass.newInstance(), plugin);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取插件注册的命令
 | 
			
		||||
     *
 | 
			
		||||
     * @param command 命令名称
 | 
			
		||||
     * @return {@link Command}
 | 
			
		||||
     */
 | 
			
		||||
    public static Command getPluginCommand(String command) {
 | 
			
		||||
        return commandMap.getCommand(command);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
    public static SimpleCommandMap getCommandMap() {
 | 
			
		||||
        return commandMap;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,7 +22,11 @@ import java.util.stream.IntStream;
 | 
			
		||||
 * @author sky
 | 
			
		||||
 * @since 2018-04-22 14:36:28
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "tabooliblocale")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "tabooliblocale",
 | 
			
		||||
        aliases = {"taboolocale", "tlocale"},
 | 
			
		||||
        permission = "taboolib.admin"
 | 
			
		||||
)
 | 
			
		||||
public class TabooLibLocaleCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import com.google.common.base.Joiner;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.ISubCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.TCommand;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
 | 
			
		||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
 | 
			
		||||
@@ -26,7 +25,11 @@ import java.util.stream.Collectors;
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 20:14
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "taboolibplugin")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "taboolibplugin",
 | 
			
		||||
        aliases = {"tabooplugin", "tplugin"},
 | 
			
		||||
        permission = "taboolib.admin"
 | 
			
		||||
)
 | 
			
		||||
public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -37,7 +40,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
 | 
			
		||||
        if (args.length == 1) {
 | 
			
		||||
            return getSubCommands().stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(ISubCommand::getLabel).collect(Collectors.toList());
 | 
			
		||||
            return getSubCommands().stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList());
 | 
			
		||||
        } else if (args.length > 1 && isPluginCommand(args[0])) {
 | 
			
		||||
            return Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(x -> !PluginUtils.isIgnored(x)).collect(Collectors.toList()).stream().filter(plugin -> args[1].isEmpty() || plugin.getName().toLowerCase().startsWith(args[1].toLowerCase())).map(Plugin::getName).collect(Collectors.toList());
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -60,7 +63,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.LOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
            return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.LOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@@ -110,7 +113,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
            return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@@ -152,7 +155,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.RELOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
            return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.RELOAD.ARGUMENTS.0"), true)};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@@ -185,7 +188,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CommandArgument[] getArguments() {
 | 
			
		||||
            return new CommandArgument[]{new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.INFO.ARGUMENTS.0"), true)};
 | 
			
		||||
            return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.INFO.ARGUMENTS.0"), true)};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.commands.taboolib;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.commands.SubCommand;
 | 
			
		||||
import me.skymc.taboolib.javashell.JavaShell;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
public class ShellLoadCommand extends SubCommand {
 | 
			
		||||
 | 
			
		||||
	public ShellLoadCommand(CommandSender sender, String[] args) {
 | 
			
		||||
		super(sender, args);
 | 
			
		||||
		if (args.length < 2) {
 | 
			
		||||
			TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.INVALID-NAME");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		File file = new File(JavaShell.getScriptFolder(), args[2].contains(".java") ? args[2] : args[2] + ".java");
 | 
			
		||||
		if (!file.exists()) {
 | 
			
		||||
			TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.INVALID-SHELL", args[2]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (JavaShell.reloadShell(args[2])) {
 | 
			
		||||
            TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.SUCCESS-LOAD", args[2]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean command() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.commands.taboolib;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.commands.SubCommand;
 | 
			
		||||
import me.skymc.taboolib.javashell.JavaShell;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
public class ShellUnloadCommand extends SubCommand {
 | 
			
		||||
 | 
			
		||||
	public ShellUnloadCommand(CommandSender sender, String[] args) {
 | 
			
		||||
		super(sender, args);
 | 
			
		||||
		if (args.length < 2) {
 | 
			
		||||
            TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.INVALID-NAME");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		File file = new File(JavaShell.getScriptFolder(), args[2].contains(".java") ? args[2] : args[2] + ".java");
 | 
			
		||||
		if (!file.exists()) {
 | 
			
		||||
            TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.INVALID-SHELL", args[2]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		JavaShell.unloadShell(args[2]);
 | 
			
		||||
        TLocale.sendTo(sender, "COMMANDS.TABOOLIB.JAVASHELL.SUCCESS-UNLOAD", args[2]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean command() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -20,7 +20,11 @@ import java.text.SimpleDateFormat;
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "tabooliblogs")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "tabooliblogs",
 | 
			
		||||
        aliases = {"tlog", "tlogs"},
 | 
			
		||||
        permission = "taboolib.admin"
 | 
			
		||||
)
 | 
			
		||||
public class TLogs extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,215 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.javashell;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.dependency.TDependencyLoader;
 | 
			
		||||
import me.skymc.taboolib.Main;
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
import org.apache.commons.lang.ArrayUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.event.HandlerList;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.plugin.RegisteredListener;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLClassLoader;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
@Deprecated
 | 
			
		||||
public class JavaShell {
 | 
			
		||||
 | 
			
		||||
    private static String paths = "";
 | 
			
		||||
    private static File javaShellFolder;
 | 
			
		||||
    private static File scriptFolder;
 | 
			
		||||
    private static File cacheFolder;
 | 
			
		||||
    private static File libFolder;
 | 
			
		||||
    private static HashMap<String, Class<?>> shells = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public static String getPaths() {
 | 
			
		||||
        return paths;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setPaths(String paths) {
 | 
			
		||||
        JavaShell.paths = paths;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getJavaShellFolder() {
 | 
			
		||||
        return javaShellFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setJavaShellFolder(File javaShellFolder) {
 | 
			
		||||
        JavaShell.javaShellFolder = javaShellFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getScriptFolder() {
 | 
			
		||||
        return scriptFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setScriptFolder(File scriptFolder) {
 | 
			
		||||
        JavaShell.scriptFolder = scriptFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getCacheFolder() {
 | 
			
		||||
        return cacheFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setCacheFolder(File cacheFolder) {
 | 
			
		||||
        JavaShell.cacheFolder = cacheFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getLibFolder() {
 | 
			
		||||
        return libFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setLibFolder(File libFolder) {
 | 
			
		||||
        JavaShell.libFolder = libFolder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static HashMap<String, Class<?>> getShells() {
 | 
			
		||||
        return shells;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setShells(HashMap<String, Class<?>> shells) {
 | 
			
		||||
        JavaShell.shells = shells;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void javaShellSetup() {
 | 
			
		||||
        File dataFolder = Main.getInst().getDataFolder();
 | 
			
		||||
        File pluginsFolder = dataFolder.getParentFile();
 | 
			
		||||
        File serverRoot = Bukkit.getWorldContainer();
 | 
			
		||||
 | 
			
		||||
        File[] rootJars = serverRoot.listFiles((dir, name) -> name.toLowerCase().endsWith("jar"));
 | 
			
		||||
        File[] pluginJars = pluginsFolder.listFiles((dir, name) -> name.toLowerCase().endsWith("jar"));
 | 
			
		||||
 | 
			
		||||
        for (File file : (File[]) ArrayUtils.addAll(rootJars, pluginJars)) {
 | 
			
		||||
            String path = file.getAbsolutePath();
 | 
			
		||||
            paths += File.pathSeparator + path;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        javaShellFolder = new File(Main.getInst().getDataFolder(), "JavaShells");
 | 
			
		||||
        if (!javaShellFolder.exists()) {
 | 
			
		||||
            Main.getInst().saveResource("JavaShells/scripts/-testshell.java", true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        scriptFolder = new File(javaShellFolder, "scripts");
 | 
			
		||||
        if (!scriptFolder.exists()) {
 | 
			
		||||
            scriptFolder.mkdir();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cacheFolder = new File(javaShellFolder, "cache");
 | 
			
		||||
        if (!cacheFolder.exists()) {
 | 
			
		||||
            cacheFolder.mkdir();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        libFolder = new File(javaShellFolder, "lib");
 | 
			
		||||
        if (!libFolder.exists()) {
 | 
			
		||||
            libFolder.mkdir();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        File tools = new File(Main.getInst().getDataFolder(), "JavaShells/lib/com.sun.tools.jar");
 | 
			
		||||
        if (!tools.exists()) {
 | 
			
		||||
            MsgUtils.warn("&4JavaShell &c工具的必要依赖 &4com.sun.tools.jar &c不存在, 功能关闭!");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loadLibrary();
 | 
			
		||||
 | 
			
		||||
        new BukkitRunnable() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                long time = System.currentTimeMillis();
 | 
			
		||||
                Arrays.stream(Objects.requireNonNull(scriptFolder.listFiles())).filter(file -> !file.getName().startsWith("-")).map(File::getName).forEach(JavaShell::reloadShell);
 | 
			
		||||
                MsgUtils.send("载入 " + shells.size() + " 个脚本, 耗时 &f" + (System.currentTimeMillis() - time) + "ms");
 | 
			
		||||
            }
 | 
			
		||||
        }.runTask(Main.getInst());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void javaShellCancel() {
 | 
			
		||||
        try {
 | 
			
		||||
            Arrays.stream(Objects.requireNonNull(cacheFolder.listFiles())).forEach(File::delete);
 | 
			
		||||
            shells.keySet().forEach(name -> invokeMethod(name, "onDisable"));
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void invokeMethod(String name, String method) {
 | 
			
		||||
        if (shells.containsKey(name)) {
 | 
			
		||||
            Class<?> clazz = shells.get(name);
 | 
			
		||||
            try {
 | 
			
		||||
                Method disableMethod = clazz.getMethod(method);
 | 
			
		||||
                if (disableMethod != null) {
 | 
			
		||||
                    disableMethod.invoke(clazz.newInstance());
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception ignored) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void unloadShell(String shell) {
 | 
			
		||||
        invokeMethod(shell, "onDisable");
 | 
			
		||||
        Class<?> clazz = shells.remove(shell);
 | 
			
		||||
        try {
 | 
			
		||||
            if (clazz.newInstance() instanceof Listener) {
 | 
			
		||||
                HandlerList.getRegisteredListeners(Main.getInst()).stream().filter(listener -> listener.getListener().getClass().getName().equals(clazz.getName())).map(RegisteredListener::getListener).forEach(HandlerList::unregisterAll);
 | 
			
		||||
                MsgUtils.send("已为脚本 &f" + shell + " &7注销监听器");
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean reloadShell(String shell) {
 | 
			
		||||
        unloadShell(shell = shell.replace(".java", ""));
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            Class.forName("com.sun.tools.javac.main.Main");
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            MsgUtils.warn("&4JavaShell &c工具的必要依赖 &4com.sun.tools.jar &c丢失, 无法载入!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        File javaFile = new File(scriptFolder, shell + ".java");
 | 
			
		||||
        if (!javaFile.exists()) {
 | 
			
		||||
            MsgUtils.send("&c脚本 &4" + shell + "&c 不存在");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String[] args = {
 | 
			
		||||
                "-nowarn",
 | 
			
		||||
                "-classpath", "." + File.pathSeparator + JavaShell.getPaths(),
 | 
			
		||||
                "-d", cacheFolder.getAbsolutePath() + File.separator,
 | 
			
		||||
                javaFile.getAbsolutePath()
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        int code = new com.sun.tools.javac.main.Main("javac").compile(args).exitCode;
 | 
			
		||||
        if (code == 0) {
 | 
			
		||||
            MsgUtils.send("&f" + shell + "&7 载入成功");
 | 
			
		||||
            try {
 | 
			
		||||
                URL[] urls = {cacheFolder.toURI().toURL()};
 | 
			
		||||
                URLClassLoader sysloader = new URLClassLoader(urls, Main.class.getClassLoader());
 | 
			
		||||
                Class<?> clazz = sysloader.loadClass(shell);
 | 
			
		||||
                shells.put(shell, clazz);
 | 
			
		||||
                sysloader.close();
 | 
			
		||||
 | 
			
		||||
                invokeMethod(shell, "onEnable");
 | 
			
		||||
                if (clazz.newInstance() instanceof Listener) {
 | 
			
		||||
                    Bukkit.getPluginManager().registerEvents((Listener) clazz.newInstance(), Main.getInst());
 | 
			
		||||
                    MsgUtils.send("已为脚本 &f" + shell + " &7注册监听器");
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                //
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            MsgUtils.send("&4" + shell + "&c 载入失败");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void loadLibrary() {
 | 
			
		||||
        Arrays.stream(Objects.requireNonNull(libFolder.listFiles())).forEach(jar -> TDependencyLoader.addToPath(Main.getInst(), jar));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
package me.skymc.taboolib.javashell.utils;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLClassLoader;
 | 
			
		||||
import java.net.URLDecoder;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.jar.JarEntry;
 | 
			
		||||
import java.util.jar.JarFile;
 | 
			
		||||
 | 
			
		||||
public class JarUtils {
 | 
			
		||||
 | 
			
		||||
    public static boolean extractFromJar(final String fileName, final String dest) throws IOException {
 | 
			
		||||
        if (getRunningJar() == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final File file = new File(dest);
 | 
			
		||||
        if (file.isDirectory()) {
 | 
			
		||||
            file.mkdir();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
            file.getParentFile().mkdirs();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final JarFile jar = getRunningJar();
 | 
			
		||||
        final Enumeration<JarEntry> e = jar.entries();
 | 
			
		||||
        while (e.hasMoreElements()) {
 | 
			
		||||
            final JarEntry je = e.nextElement();
 | 
			
		||||
            if (!je.getName().contains(fileName)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            final InputStream in = new BufferedInputStream(jar.getInputStream(je));
 | 
			
		||||
            final OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
 | 
			
		||||
            copyInputStream(in, out);
 | 
			
		||||
            jar.close();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        jar.close();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void copyInputStream(final InputStream in, final OutputStream out) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            final byte[] buff = new byte[4096];
 | 
			
		||||
            int n;
 | 
			
		||||
            while ((n = in.read(buff)) > 0) {
 | 
			
		||||
                out.write(buff, 0, n);
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            out.flush();
 | 
			
		||||
            out.close();
 | 
			
		||||
            in.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static URL getJarUrl(final File file) throws IOException {
 | 
			
		||||
        return new URL("jar:" + file.toURI().toURL().toExternalForm() + "!/");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static JarFile getRunningJar() throws IOException {
 | 
			
		||||
        if (!RUNNING_FROM_JAR) {
 | 
			
		||||
            // null if not running from jar
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        String path = new File(JarUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath())
 | 
			
		||||
                .getAbsolutePath();
 | 
			
		||||
        path = URLDecoder.decode(path, "UTF-8");
 | 
			
		||||
        return new JarFile(path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean RUNNING_FROM_JAR = false;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        final URL resource = JarUtils.class.getClassLoader().getResource("plugin.yml");
 | 
			
		||||
        if (resource != null) {
 | 
			
		||||
            RUNNING_FROM_JAR = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static void addClassPath(final URL url) {
 | 
			
		||||
        final URLClassLoader sysloader = (URLClassLoader) Bukkit.class.getClassLoader();
 | 
			
		||||
        final Class<URLClassLoader> sysclass = URLClassLoader.class;
 | 
			
		||||
        try {
 | 
			
		||||
            final Method method = sysclass.getDeclaredMethod("addURL", URL.class);
 | 
			
		||||
            method.setAccessible(true);
 | 
			
		||||
            method.invoke(sysloader, url);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            MsgUtils.warn("无法添加添加 &4" + url + "&c 到运行库");
 | 
			
		||||
            MsgUtils.warn(t.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.listener;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-08-25 10:16
 | 
			
		||||
 */
 | 
			
		||||
public class TListenerCommand {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package me.skymc.taboolib.listener;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.util.Ref;
 | 
			
		||||
import com.ilummc.tlib.util.Strings;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
@@ -10,6 +11,7 @@ import org.bukkit.event.server.PluginDisableEvent;
 | 
			
		||||
import org.bukkit.event.server.PluginEnableEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +58,7 @@ public class TListenerHandler implements Listener {
 | 
			
		||||
                    // 实例化监听器
 | 
			
		||||
                    Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance();
 | 
			
		||||
                    listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
 | 
			
		||||
                } catch (InstantiationException | IllegalAccessException e) {
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@ import net.milkbowl.vault.permission.Permission;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.plugin.RegisteredServiceProvider;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
public class PermissionUtils {
 | 
			
		||||
	
 | 
			
		||||
	private static Permission perms;
 | 
			
		||||
@@ -27,14 +29,6 @@ public class PermissionUtils {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean hasPermission(Player player, String perm) {
 | 
			
		||||
		if (perms.playerHas(player, perm)) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		for (String group : perms.getPlayerGroups(player)) {
 | 
			
		||||
			if (perms.groupHas(player.getWorld(), group, perm)) {
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
		return perms.playerHas(player, perm) || Arrays.stream(perms.getPlayerGroups(player)).anyMatch(group -> perms.groupHas(player.getWorld(), group, perm));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,11 @@ import com.google.common.collect.ImmutableList;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.entity.HumanEntity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -88,4 +90,50 @@ public class PlayerUtils {
 | 
			
		||||
            player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取玩家的鱼钩
 | 
			
		||||
     *
 | 
			
		||||
     * @param player 玩家
 | 
			
		||||
     * @return net.minecraft.server.{version}.EntityFishingHook
 | 
			
		||||
     */
 | 
			
		||||
    public static Object getPlayerHookedFish(HumanEntity player) {
 | 
			
		||||
        try {
 | 
			
		||||
            Object entityHuman = player.getClass().getMethod("getHandle").invoke(player);
 | 
			
		||||
            return entityHuman.getClass().getField("hookedFish").get(entityHuman);
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取鱼钩的钓鱼时间
 | 
			
		||||
     *
 | 
			
		||||
     * @param fishHook 鱼钩
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    public static int getFishingTicks(Object fishHook) {
 | 
			
		||||
        try {
 | 
			
		||||
            Field fishingTicks = fishHook.getClass().getDeclaredField("h");
 | 
			
		||||
            fishingTicks.setAccessible(true);
 | 
			
		||||
            return (int) fishingTicks.get(fishHook);
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 设置鱼钩的钓鱼时间
 | 
			
		||||
     *
 | 
			
		||||
     * @param fishHook 鱼钩
 | 
			
		||||
     * @param ticks    时间
 | 
			
		||||
     */
 | 
			
		||||
    public static void setFishingTicks(Object fishHook, int ticks) {
 | 
			
		||||
        try {
 | 
			
		||||
            Field fishingTicks = fishHook.getClass().getDeclaredField("h");
 | 
			
		||||
            fishingTicks.setAccessible(true);
 | 
			
		||||
            fishingTicks.set(fishHook, ticks);
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package me.skymc.taboolib.scoreboard;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Charsets;
 | 
			
		||||
import com.google.common.base.Splitter;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
@@ -14,7 +13,6 @@ import java.lang.reflect.Constructor;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class SimpleScoreboard {
 | 
			
		||||
 | 
			
		||||
    private static Map<String, OfflinePlayer> cache = new HashMap<>();
 | 
			
		||||
@@ -38,11 +36,9 @@ public class SimpleScoreboard {
 | 
			
		||||
 | 
			
		||||
    public void add(String text, Integer score) {
 | 
			
		||||
        text = ChatColor.translateAlternateColorCodes('&', text);
 | 
			
		||||
 | 
			
		||||
        if (remove(score, text, false) || !scores.containsValue(score)) {
 | 
			
		||||
            updated.add(text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        scores.put(text, score);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -52,28 +48,23 @@ public class SimpleScoreboard {
 | 
			
		||||
 | 
			
		||||
    public boolean remove(Integer score, String n, boolean b) {
 | 
			
		||||
        String toRemove = get(score, n);
 | 
			
		||||
 | 
			
		||||
        if (toRemove == null)
 | 
			
		||||
        if (toRemove == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        scores.remove(toRemove);
 | 
			
		||||
 | 
			
		||||
        if(b)
 | 
			
		||||
        if (b) {
 | 
			
		||||
            removed.add(score);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String get(int score, String n) {
 | 
			
		||||
        String str = null;
 | 
			
		||||
 | 
			
		||||
        for (Map.Entry<String, Integer> entry : scores.entrySet()) {
 | 
			
		||||
            if (entry.getValue().equals(score) &&
 | 
			
		||||
                    !entry.getKey().equals(n)) {
 | 
			
		||||
            if (entry.getValue().equals(score) && !entry.getKey().equals(n)) {
 | 
			
		||||
                str = entry.getKey();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return str;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -81,18 +72,15 @@ public class SimpleScoreboard {
 | 
			
		||||
        Team team;
 | 
			
		||||
        ChatColor color = ChatColor.values()[pos];
 | 
			
		||||
        OfflinePlayer result;
 | 
			
		||||
 | 
			
		||||
        if (!cache.containsKey(color.toString()))
 | 
			
		||||
        if (!cache.containsKey(color.toString())) {
 | 
			
		||||
            cache.put(color.toString(), getOfflinePlayerSkipLookup(color.toString()));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        result = cache.get(color.toString());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            team = scoreboard.registerNewTeam("text-" + (teams.size() + 1));
 | 
			
		||||
        } catch (IllegalArgumentException e) {
 | 
			
		||||
            team = scoreboard.getTeam("text-" + (teams.size()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        applyText(team, text, result);
 | 
			
		||||
 | 
			
		||||
        teams.add(team);
 | 
			
		||||
@@ -102,30 +90,26 @@ public class SimpleScoreboard {
 | 
			
		||||
    private void applyText(Team team, String text, OfflinePlayer result) {
 | 
			
		||||
        Iterator<String> iterator = Splitter.fixedLength(16).split(text).iterator();
 | 
			
		||||
        String prefix = iterator.next();
 | 
			
		||||
 | 
			
		||||
        team.setPrefix(prefix);
 | 
			
		||||
 | 
			
		||||
        if(!team.hasPlayer(result))
 | 
			
		||||
        if (!team.hasPlayer(result)) {
 | 
			
		||||
            team.addPlayer(result);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        if (text.length() > 16) {
 | 
			
		||||
            String prefixColor = ChatColor.getLastColors(prefix);
 | 
			
		||||
            String suffix = iterator.next();
 | 
			
		||||
 | 
			
		||||
            if (prefix.endsWith(String.valueOf(ChatColor.COLOR_CHAR))) {
 | 
			
		||||
                prefix = prefix.substring(0, prefix.length() - 1);
 | 
			
		||||
                team.setPrefix(prefix);
 | 
			
		||||
                prefixColor = ChatColor.getByChar(suffix.charAt(0)).toString();
 | 
			
		||||
                suffix = suffix.substring(1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (prefixColor == null)
 | 
			
		||||
            if (prefixColor == null) {
 | 
			
		||||
                prefixColor = "";
 | 
			
		||||
 | 
			
		||||
            if (suffix.length() > 16) {
 | 
			
		||||
                suffix = suffix.substring(0, (13 - prefixColor.length())); // cut off suffix, done if text is over 30 characters
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (suffix.length() > 16) {
 | 
			
		||||
                // cut off suffix, done if text is over 30 characters
 | 
			
		||||
                suffix = suffix.substring(0, (13 - prefixColor.length()));
 | 
			
		||||
            }
 | 
			
		||||
            team.setSuffix((prefixColor.equals("") ? ChatColor.RESET : prefixColor) + suffix);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -134,74 +118,59 @@ public class SimpleScoreboard {
 | 
			
		||||
        if (updated.isEmpty()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (obj == null) {
 | 
			
		||||
            obj = scoreboard.registerNewObjective((title.length() > 16 ? title.substring(0, 15) : title), "dummy");
 | 
			
		||||
            obj.setDisplayName(title);
 | 
			
		||||
            obj.setDisplaySlot(DisplaySlot.SIDEBAR);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        removed.stream().forEach((remove) -> {
 | 
			
		||||
        removed.forEach((remove) -> {
 | 
			
		||||
            for (String s : scoreboard.getEntries()) {
 | 
			
		||||
                Score score = obj.getScore(s);
 | 
			
		||||
 | 
			
		||||
                if (score == null)
 | 
			
		||||
                if (score == null) {
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                if (score.getScore() != remove)
 | 
			
		||||
                }
 | 
			
		||||
                if (score.getScore() != remove) {
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                scoreboard.resetScores(s);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        removed.clear();
 | 
			
		||||
 | 
			
		||||
        int index = scores.size();
 | 
			
		||||
 | 
			
		||||
        for (Map.Entry<String, Integer> text : scores.entrySet()) {
 | 
			
		||||
            Team t = scoreboard.getTeam(ChatColor.values()[text.getValue()].toString());
 | 
			
		||||
            Map.Entry<Team, OfflinePlayer> team;
 | 
			
		||||
 | 
			
		||||
            if(!updated.contains(text.getKey())) {
 | 
			
		||||
            if (!updated.contains(text.getKey())) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(t != null) {
 | 
			
		||||
            if (t != null) {
 | 
			
		||||
                String color = ChatColor.values()[text.getValue()].toString();
 | 
			
		||||
 | 
			
		||||
                if (!cache.containsKey(color)) {
 | 
			
		||||
                    cache.put(color, getOfflinePlayerSkipLookup(color));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                team = new AbstractMap.SimpleEntry<>(t, cache.get(color));
 | 
			
		||||
                applyText(team.getKey(), text.getKey(), team.getValue());
 | 
			
		||||
                index -= 1;
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            } else {
 | 
			
		||||
                team = createTeam(text.getKey(), text.getValue());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Integer score = text.getValue() != null ? text.getValue() : index;
 | 
			
		||||
 | 
			
		||||
            obj.getScore(team.getValue()).setScore(score);
 | 
			
		||||
            index -= 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updated.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTitle(String title) {
 | 
			
		||||
        this.title = ChatColor.translateAlternateColorCodes('&', title);
 | 
			
		||||
 | 
			
		||||
        if(obj != null)
 | 
			
		||||
        if (obj != null) {
 | 
			
		||||
            obj.setDisplayName(this.title);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void reset() {
 | 
			
		||||
        for (Team t : teams)
 | 
			
		||||
            t.unregister();
 | 
			
		||||
        teams.forEach(Team::unregister);
 | 
			
		||||
        teams.clear();
 | 
			
		||||
        scores.clear();
 | 
			
		||||
    }
 | 
			
		||||
@@ -211,8 +180,7 @@ public class SimpleScoreboard {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void send(Player... players) {
 | 
			
		||||
        for (Player p : players)
 | 
			
		||||
            p.setScoreboard(scoreboard);
 | 
			
		||||
        Arrays.stream(players).forEach(p -> p.setScoreboard(scoreboard));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final UUID invalidUserUUID = UUID.nameUUIDFromBytes("InvalidUsername".getBytes(Charsets.UTF_8));
 | 
			
		||||
@@ -234,17 +202,14 @@ public class SimpleScoreboard {
 | 
			
		||||
            }
 | 
			
		||||
            if (craftOfflinePlayerConstructor == null) {
 | 
			
		||||
                Class<?> serverClass = Bukkit.getServer().getClass();
 | 
			
		||||
                Class<?> craftOfflinePlayerClass = Class.forName(serverClass.getName()
 | 
			
		||||
                        .replace("CraftServer", "CraftOfflinePlayer"));
 | 
			
		||||
                craftOfflinePlayerConstructor = craftOfflinePlayerClass.getDeclaredConstructor(
 | 
			
		||||
                        serverClass, gameProfileClass
 | 
			
		||||
                );
 | 
			
		||||
                Class<?> craftOfflinePlayerClass = Class.forName(serverClass.getName().replace("CraftServer", "CraftOfflinePlayer"));
 | 
			
		||||
                craftOfflinePlayerConstructor = craftOfflinePlayerClass.getDeclaredConstructor(serverClass, gameProfileClass);
 | 
			
		||||
                craftOfflinePlayerConstructor.setAccessible(true);
 | 
			
		||||
            }
 | 
			
		||||
            Object gameProfile = gameProfileConstructor.newInstance(invalidUserUUID, name);
 | 
			
		||||
            Object craftOfflinePlayer = craftOfflinePlayerConstructor.newInstance(Bukkit.getServer(), gameProfile);
 | 
			
		||||
            return (OfflinePlayer) craftOfflinePlayer;
 | 
			
		||||
        } catch (Throwable t) { // Fallback if fail
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            return Bukkit.getOfflinePlayer(name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ public class TabooLibClient {
 | 
			
		||||
    public static void init() {
 | 
			
		||||
        if (TabooLibSettings.load()) {
 | 
			
		||||
            connect();
 | 
			
		||||
            Bukkit.getScheduler().runTaskTimerAsynchronously(TabooLib.instance(), TabooLibClient::reconnect, 0, 20);
 | 
			
		||||
            Bukkit.getScheduler().runTaskTimerAsynchronously(TabooLib.instance(), TabooLibClient::reconnect, 0, 100);
 | 
			
		||||
        } else {
 | 
			
		||||
            TLocale.sendToConsole("COMMUNICATION.FAILED-LOAD-SETTINGS", TabooLibSettings.getThrowable().toString());
 | 
			
		||||
        }
 | 
			
		||||
@@ -70,7 +70,7 @@ public class TabooLibClient {
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            TLocale.sendToConsole("COMMUNICATION.FAILED-CONNECT-CLIENT", e.toString());
 | 
			
		||||
            TLocale.sendToConsole("COMMUNICATION.FAILED-CONNECT-CLIENT", e.getMessage());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +80,7 @@ public class TabooLibClient {
 | 
			
		||||
                    packet.readOnClient();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.toString());
 | 
			
		||||
                TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,8 @@
 | 
			
		||||
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;
 | 
			
		||||
@@ -65,6 +68,26 @@ public class ArrayUtils {
 | 
			
		||||
        return (T) objectInputStream.readObject();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T skipEmpty(T obj) {
 | 
			
		||||
        return skipEmpty(obj, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T[] skipEmpty(T[] obj) {
 | 
			
		||||
        return skipEmpty(obj, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T skipEmpty(T obj, T def) {
 | 
			
		||||
        return Strings.isEmpty(String.valueOf(obj)) ? def : obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T[] skipEmpty(T[] obj, T[] def) {
 | 
			
		||||
        if (obj.length == 0) {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        T firstElement = skipEmpty(obj[0]);
 | 
			
		||||
        return firstElement == null ? def : obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //           Deprecated
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package me.skymc.taboolib.string.obfuscated;
 | 
			
		||||
 | 
			
		||||
import javax.xml.bind.DatatypeConverter;
 | 
			
		||||
 | 
			
		||||
@Deprecated
 | 
			
		||||
public class CT {
 | 
			
		||||
 | 
			
		||||
    public static String decode(CodeType type, String string) {
 | 
			
		||||
@@ -16,34 +17,36 @@ public class CT {
 | 
			
		||||
                }
 | 
			
		||||
                return text.toString();
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String encode(CodeType type, String string) {
 | 
			
		||||
		switch (type) {
 | 
			
		||||
			case BASE64: {
 | 
			
		||||
				return DatatypeConverter.printBase64Binary(string.getBytes());
 | 
			
		||||
			}
 | 
			
		||||
			case BINARY: {
 | 
			
		||||
				StringBuilder binary = new StringBuilder();
 | 
			
		||||
				for (byte b: string.getBytes()) {
 | 
			
		||||
					int value = b;
 | 
			
		||||
					for (int i = 0; i < 8; i++) {
 | 
			
		||||
						binary.append((value & 128) == 0 ? 0: 1);
 | 
			
		||||
						value <<= 1;
 | 
			
		||||
					}
 | 
			
		||||
					binary.append(" ");
 | 
			
		||||
				}
 | 
			
		||||
				return binary.toString();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return "";
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String encode(CodeType type, String string) {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case BASE64: {
 | 
			
		||||
                return DatatypeConverter.printBase64Binary(string.getBytes());
 | 
			
		||||
            }
 | 
			
		||||
            case BINARY: {
 | 
			
		||||
                StringBuilder binary = new StringBuilder();
 | 
			
		||||
                for (byte b : string.getBytes()) {
 | 
			
		||||
                    int value = b;
 | 
			
		||||
                    for (int i = 0; i < 8; i++) {
 | 
			
		||||
                        binary.append((value & 128) == 0 ? 0 : 1);
 | 
			
		||||
                        value <<= 1;
 | 
			
		||||
                    }
 | 
			
		||||
                    binary.append(" ");
 | 
			
		||||
                }
 | 
			
		||||
                return binary.toString();
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum CodeType {
 | 
			
		||||
        BASE64,
 | 
			
		||||
        BINARY
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.LinkedList;
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
 */
 | 
			
		||||
@Deprecated
 | 
			
		||||
public class ThreadUtils {
 | 
			
		||||
 | 
			
		||||
    private static final LinkedList<Runnable> queue = new LinkedList<>();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,11 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-06-22 17:09
 | 
			
		||||
 */
 | 
			
		||||
@TCommand(name = "translateuuid")
 | 
			
		||||
@TCommand(
 | 
			
		||||
        name = "translateuuid",
 | 
			
		||||
        aliases = "tuuid",
 | 
			
		||||
        permission = "taboolib.admin"
 | 
			
		||||
)
 | 
			
		||||
public class TranslateUUIDCommand extends BaseMainCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
 | 
			
		||||
public class testshell {
 | 
			
		||||
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        Bukkit.broadcastMessage("testshell enable!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onDisable() {
 | 
			
		||||
        Bukkit.broadcastMessage("testshell disable!");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -172,7 +172,9 @@ COMMANDS:
 | 
			
		||||
    - '&8[&3&lTabooLib&8] &7指令 &f{0} &7不存在'
 | 
			
		||||
    - '&8[&3&lTabooLib&8] &7你可能想要:'
 | 
			
		||||
    - '&8[&3&lTabooLib&8] &7{1}'
 | 
			
		||||
    COMMAND-REGISTER: '&7自动为插件 &f{0} &7的命令 &f{1} &7注册 &f{2} &7条子命令'
 | 
			
		||||
    COMMAND-CREATE: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册到服务器'
 | 
			
		||||
    COMMAND-CREATE-FAILED: '&7插件 &f{0} &7的 &f{1} &7命令注册失败: &c{2}'
 | 
			
		||||
    COMMAND-REGISTER: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册 &f{2} &7条子命令'
 | 
			
		||||
    COMMAND-HELP: ' §f/{0} {1} {2} §6- §e{3}'
 | 
			
		||||
    COMMAND-ARGUMENT: '§7<§8{0}§7>'
 | 
			
		||||
    COMMAND-ARGUMENT-REQUIRE: '§7[§8{0}§7]'
 | 
			
		||||
@@ -242,19 +244,6 @@ COMMANDS:
 | 
			
		||||
      PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.'
 | 
			
		||||
      UPDATE-START: '&8[&3&lTabooLib&8] &7开始下载:&f {0}'
 | 
			
		||||
      UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
 | 
			
		||||
    JAVASHELL:
 | 
			
		||||
      DESCRIPTION:
 | 
			
		||||
        LOAD: '载入脚本'
 | 
			
		||||
        UNLOAD: '卸载脚本'
 | 
			
		||||
      ARGUMENTS:
 | 
			
		||||
        LOAD:
 | 
			
		||||
          0: '名称'
 | 
			
		||||
        UNLOAD:
 | 
			
		||||
          0: '名称'
 | 
			
		||||
      INVALID-NAME: '&8[&3&lTabooLib&8] &4请输入正确的名称'
 | 
			
		||||
      INVALID-SHELL: '&8[&3&lTabooLib&8] &4脚本 &c{0} &4不存在'
 | 
			
		||||
      SUCCESS-LOAD: '&8[&3&lTabooLib&8] &7脚本 &f{0} &7已载入'
 | 
			
		||||
      SUCCESS-UNLOAD: '&8[&3&lTabooLib&8] &7脚本 &f{0} &7已卸载'
 | 
			
		||||
    PLAYERTAG:
 | 
			
		||||
      DESCRIPTION:
 | 
			
		||||
        DISPLAY: '设置玩家展示名称'
 | 
			
		||||
@@ -582,4 +571,4 @@ COMMUNICATION:
 | 
			
		||||
  SUCCESS-CONNECTED: '§8[§3§lTabooLibClient§8] &7本地通讯网络连接成功.'
 | 
			
		||||
  CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7加入本地通讯网络.'
 | 
			
		||||
  CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7退出本地通讯网络.'
 | 
			
		||||
  CLIENT-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}'
 | 
			
		||||
  PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}'
 | 
			
		||||
@@ -6,27 +6,10 @@ author: [lzzelAliz, 坏黑]
 | 
			
		||||
depend: [Vault]
 | 
			
		||||
softdepend: [PlaceholderAPI, Skript, MassiveLag]
 | 
			
		||||
 | 
			
		||||
# 两个命令删除预定
 | 
			
		||||
commands:
 | 
			
		||||
  taboolib:
 | 
			
		||||
    aliases: [tlib]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  language2:
 | 
			
		||||
    aliases: [lang2]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  tabooliblocale:
 | 
			
		||||
    aliases: [taboolocale, tlocale]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  taboolibplugin:
 | 
			
		||||
    aliases: [tabooplugin, tplugin]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  taboolibexecute:
 | 
			
		||||
    aliases: [texecute]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  taboolibrarymodule:
 | 
			
		||||
    aliases: [tlm]
 | 
			
		||||
  translateuuid:
 | 
			
		||||
    aliases: [tuuid]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
  tabooliblogs:
 | 
			
		||||
    aliases: [tlog, tlogs]
 | 
			
		||||
    permission: taboolib.admin
 | 
			
		||||
    aliases: [tlm]
 | 
			
		||||
		Reference in New Issue
	
	Block a user