diff --git a/pom.xml b/pom.xml index 38e5229..9c53f9a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.14 + 4.2 UTF-8 @@ -51,6 +51,7 @@ com.ilummc.eagletdl org.ow2.asm + com.google.code.gson false @@ -58,6 +59,17 @@ + + org.apache.maven.plugins + maven-jar-plugin + + + + me.skymc.taboolib.socket.TabooLibServer + + + + @@ -82,6 +94,11 @@ + + com.google.code.gson + gson + 2.7 + com.zaxxer HikariCP @@ -126,6 +143,13 @@ system ${basedir}/libs/1_8_R3.jar + + bungeecord + bungeecord + 1 + system + ${basedir}/libs/BungeeCord.jar + com.sun.tools jshell diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java index b520d7d..95ef971 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java @@ -19,9 +19,7 @@ import java.util.function.Consumer; */ public class TConfigWatcher { - private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, - new BasicThreadFactory.Builder().namingPattern("TConfigWatcherService-%d").build()); - + private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("TConfigWatcherService-%d").build()); private final Map>> map = new HashMap<>(); public TConfigWatcher() { @@ -42,6 +40,10 @@ public class TConfigWatcher { }, 1000, 100, TimeUnit.MILLISECONDS); } + public void addSimpleListener(File file, Runnable runnable) { + addListener(file, null, obj -> runnable.run()); + } + public void addOnListen(File file, Object obj, Consumer consumer) { try { WatchService service = FileSystems.getDefault().newWatchService(); @@ -82,5 +84,4 @@ public class TConfigWatcher { } }); } - } diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java index bd9c35b..c896491 100644 --- a/src/main/java/com/ilummc/tlib/util/Ref.java +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -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; diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 6185548..8c3a5df 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -1,55 +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.inventory.ItemUtils; import me.skymc.taboolib.inventory.speciaitem.SpecialItem; import me.skymc.taboolib.itagapi.TagDataHandler; -import me.skymc.taboolib.javashell.JavaShell; -import me.skymc.taboolib.listener.*; -import me.skymc.taboolib.message.ChatCatcher; +import me.skymc.taboolib.javascript.ScriptHandler; +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.string.StringUtils; +import me.skymc.taboolib.socket.TabooLibClient; 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; @@ -57,7 +39,6 @@ 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; @@ -65,7 +46,7 @@ import java.util.Random; /** * @author sky */ -public class Main extends JavaPlugin implements Listener { +public class Main extends JavaPlugin { public Main() { inst = this; @@ -80,7 +61,6 @@ public class Main extends JavaPlugin implements Listener { private static File playerDataFolder; private static File serverDataFolder; private static StorageType storageType = StorageType.LOCAL; - private static MySQLConnection connection = null; private static Language2 exampleLanguage2; private static boolean disable = false; private static boolean started = false; @@ -109,32 +89,23 @@ public class Main extends JavaPlugin implements Listener { @Override public void onLoad() { disable = false; - // 载入配置 + // 载入配置文件 saveDefaultConfig(); - // 载入牛逼玩意儿 + // 载入牛逼东西 TLib.init(); TLib.injectPluginManager(); - // 网络检测 - testInternet(); - // 创建文件夹 - setupDataFolder(); - // 创建数据库 - setupDatabase(); - // 载入离线库文件 - setupLibraries(); - // 载入牛逼玩意儿 + // 载入插件设置 + TabooLibLoader.setup(); + // 载入大饼 TLib.initPost(); - // 注册连接池 + // 载入连接池 HikariHandler.init(); } @Override public void onEnable() { - // 注册命令 - registerCommands(); - // 注册监听 - registerListener(); - + // 注册插件配置 + TabooLibLoader.register(); // 载入经济 EcoUtils.setupEconomy(); // 载入权限 @@ -146,32 +117,27 @@ public class Main extends JavaPlugin implements Listener { // 载入周期管理器 TimeCycleManager.load(); // 启动脚本 - JavaShell.javaShellSetup(); + ScriptHandler.inst(); // 注册脚本 - SkriptHandler.getInst(); + SkriptHandler.register(); // 注册头衔 TagDataHandler.init(this); // 载入语言文件 exampleLanguage2 = new Language2("Language2", this); - // 启动数据库储存方法 if (getStorageType() == StorageType.SQL) { GlobalDataManager.SQLMethod.startSQLMethod(); } - // 载入完成 TLocale.Logger.info("NOTIFY.SUCCESS-LOADED", getDescription().getAuthors().toString(), getDescription().getVersion(), String.valueOf(TabooLib.getVersion())); - // 文件保存 Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120); Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60); - // 文件监控 - TLib.getTLib().getConfigWatcher().addListener(new File(getDataFolder(), "config.yml"), null, obj -> { + TLib.getTLib().getConfigWatcher().addSimpleListener(new File(getDataFolder(), "config.yml"), () -> { reloadConfig(); TLocale.Logger.info("CONFIG.RELOAD-SUCCESS", inst.getName(), "config.yml"); }); - // 插件联动 new BukkitRunnable() { @@ -181,14 +147,12 @@ public class Main extends JavaPlugin implements Listener { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { new SupportPlaceholder(getInst(), "taboolib").hook(); } - // 载入 TLM 接口 TLM.getInst(); // 载入 SpecialItem 接口 SpecialItem.getInst().loadItems(); // 载入 TranslateUUID 工具 TranslateUUID.init(); - // 面子工程 InputStream inputStream = FileUtils.getResource("motd.txt"); try { @@ -198,14 +162,12 @@ public class Main extends JavaPlugin implements Listener { } } catch (IOException ignored) { } + // 本地通讯网络 + TabooLibClient.init(); } }.runTask(this); - // 更新检测 new UpdateTask(); - // 启动监控 - new Metrics(this); - // 启动 started = true; } @@ -213,13 +175,11 @@ public class Main extends JavaPlugin implements Listener { @Override public void onDisable() { disable = true; - // 如果插件尚未启动完成 if (!started) { TLocale.Logger.error("NOTIFY.FAIL-DISABLE"); return; } - // 保存数据 Bukkit.getOnlinePlayers().forEach(x -> DataUtils.saveOnline(x.getName())); // 结束线程 @@ -228,8 +188,6 @@ public class Main extends JavaPlugin implements Listener { DataUtils.saveAllCaches(); // 保存玩家数据 PlayerDataManager.saveAllPlayers(false, true); - // 结束脚本 - JavaShell.javaShellCancel(); // 注销 SpecialItem 接口 SpecialItem.getInst().unloadItems(); // 注销 TLM 接口 @@ -238,12 +196,12 @@ public class Main extends JavaPlugin implements Listener { TranslateUUID.cancel(); // 注销连接池 HikariHandler.closeDataSourceForce(); - + // 注销监听器 + TListenerHandler.cancelListeners(); // 结束数据库储存方法 if (getStorageType() == StorageType.SQL) { GlobalDataManager.SQLMethod.cancelSQLMethod(); } - // 清理数据 if (getStorageType() == StorageType.LOCAL && getConfig().getBoolean("DELETE-DATA")) { getPlayerDataFolder().delete(); @@ -252,124 +210,14 @@ public class Main extends JavaPlugin implements Listener { if (getStorageType() == StorageType.SQL && getConfig().getBoolean("DELETE-VARIABLE")) { GlobalDataManager.clearInvalidVariables(); } - // 提示信息 TLocale.Logger.info("NOTIFY.SUCCESS-DISABLE"); - - // 结束连接 - if (connection != null && connection.isConnection()) { - connection.closeConnection(); - } - // 卸载牛逼玩意儿 TLib.unload(); - // 关闭服务器 Bukkit.shutdown(); } - private void testInternet() { - try { - InetAddress inetAddress = InetAddress.getByName(getConfig().getString("TEST-URL", "aliyun.com")); - isInternetOnline = inetAddress.isReachable(10000); - } catch (Exception ignored) { - } - if (!isInternetOnline() && !isOfflineVersion() && !isLibrariesExists()) { - TLocale.Logger.error("TLIB.LOAD-FAIL-OFFLINE", getDescription().getVersion()); - // 死锁 - try { - Thread.sleep(Long.MAX_VALUE); - } catch (Exception ignored) { - } - } - } - - private void setupDataFolder() { - playerDataFolder = new File(getConfig().getString("DATAURL.PLAYER-DATA")); - if (!playerDataFolder.exists()) { - playerDataFolder.mkdirs(); - } - serverDataFolder = new File(getConfig().getString("DATAURL.SERVER-DATA")); - if (!serverDataFolder.exists()) { - serverDataFolder.mkdirs(); - } - } - - private void setupLibraries() { - if (!isOfflineVersion()) { - return; - } - for (Dependency dependency : TDependencyInjector.getDependencies(TLib.getTLib())) { - if (dependency.type() == Dependency.Type.LIBRARY && dependency.maven().matches(".*:.*:.*")) { - String fileName = String.join("-", dependency.maven().split(":")) + ".jar"; - File targetFile = FileUtils.file(TLib.getTLib().getLibsFolder(), fileName); - InputStream inputStream = FileUtils.getResource("libs/" + fileName); - if (!targetFile.exists() && inputStream != null) { - FileUtils.inputStreamToFile(inputStream, FileUtils.file(TLib.getTLib().getLibsFolder(), fileName)); - } - } - } - } - - private void setupDatabase() { - DataUtils.addPluginData("TabooLibrary", null); - if (getConfig().getBoolean("MYSQL.ENABLE")) { - connection = new MySQLConnection(getConfig().getString("MYSQL.HOST"), getConfig().getString("MYSQL.USER"), getConfig().getString("MYSQL.POST"), getConfig().getString("MYSQL.PASSWORD"), getConfig().getString("MYSQL.DATABASE"), 30, this); - if (connection.isConnection()) { - connection.createTable(getTablePrefix() + "_playerdata", "username", "configuration"); - connection.createTable(getTablePrefix() + "_plugindata", "name", "variable", "upgrade"); - connection.createTable(getTablePrefix() + "_serveruuid", "uuid", "hash"); - if (!connection.isExists(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID())) { - connection.intoValue(getTablePrefix() + "_serveruuid", TabooLib.getServerUID(), StringUtils.hashKeyForDisk(getDataFolder().getPath())); - } else { - String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString(); - if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) { - TLocale.Logger.error("NOTIFY.ERROR-SERVER-KEY"); - TabooLib.resetServerUID(); - Bukkit.shutdown(); - } - } - } else { - TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FAIL"); - Bukkit.shutdown(); - } - storageType = StorageType.SQL; - } - } - - private void registerCommands() { - getCommand("language2").setExecutor(new Language2Command()); - getCommand("taboolibrarymodule").setExecutor(new TLMCommands()); - TBaseCommand.registerCommand("taboolib", new TabooLibMainCommand()); - TBaseCommand.registerCommand("tabooliblocale", new TabooLibLocaleCommand()); - TBaseCommand.registerCommand("taboolibplugin", new TabooLibPluginCommand()); - TBaseCommand.registerCommand("taboolibexecute", new TabooLibExecuteCommand()); - TBaseCommand.registerCommand("translateuuid", new TranslateUUIDCommand()); - } - - private void registerListener() { - getServer().getPluginManager().registerEvents(this, this); - getServer().getPluginManager().registerEvents(new ListenerPlayerCommand(), this); - getServer().getPluginManager().registerEvents(new ListenerPlayerJump(), this); - getServer().getPluginManager().registerEvents(new ListenerPlayerJoinAndQuit(), this); - getServer().getPluginManager().registerEvents(new ChatCatcher(), this); - getServer().getPluginManager().registerEvents(new DataUtils(), this); - getServer().getPluginManager().registerEvents(new AnvilContainerAPI(), this); - getServer().getPluginManager().registerEvents(new ListenerPluginDisable(), this); - getServer().getPluginManager().registerEvents(new PlayerDataManager(), this); - getServer().getPluginManager().registerEvents(new ListenerItemListCommand(), this); - getServer().getPluginManager().registerEvents(new ListenerSoundsCommand(), this); - - if (TabooLib.getVerint() > 10700) { - getServer().getPluginManager().registerEvents(new EntityUtils(), this); - getServer().getPluginManager().registerEvents(new SignUtils(), this); - } - - if (Bukkit.getPluginManager().getPlugin("YUM") != null) { - getServer().getPluginManager().registerEvents(new ListenerNetWork(), this); - } - } - // ********************************* // // Getter and Setter @@ -409,7 +257,7 @@ public class Main extends JavaPlugin implements Listener { } public static MySQLConnection getConnection() { - return connection; + return null; } public static Language2 getExampleLanguage2() { @@ -439,4 +287,26 @@ public class Main extends JavaPlugin implements Listener { public static boolean isLibrariesExists() { return TLib.getTLib().getLibsFolder().listFiles().length > 0; } + + // ********************************* + // + // Private Setter + // + // ********************************* + + static void setIsInternetOnline(boolean isInternetOnline) { + Main.isInternetOnline = isInternetOnline; + } + + static void setPlayerDataFolder(File playerDataFolder) { + Main.playerDataFolder = playerDataFolder; + } + + static void setServerDataFolder(File serverDataFolder) { + Main.serverDataFolder = serverDataFolder; + } + + static void setStorageType(StorageType storageType) { + Main.storageType = storageType; + } } diff --git a/src/main/java/me/skymc/taboolib/TabooLib.java b/src/main/java/me/skymc/taboolib/TabooLib.java index 9ae1e60..57f4dfa 100644 --- a/src/main/java/me/skymc/taboolib/TabooLib.java +++ b/src/main/java/me/skymc/taboolib/TabooLib.java @@ -23,6 +23,10 @@ public class TabooLib { } } + public static Main instance() { + return (Main) Main.getInst(); + } + public static boolean isSpigot() { return spigot; } diff --git a/src/main/java/me/skymc/taboolib/TabooLibDatabase.java b/src/main/java/me/skymc/taboolib/TabooLibDatabase.java new file mode 100644 index 0000000..772b759 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/TabooLibDatabase.java @@ -0,0 +1,128 @@ +package me.skymc.taboolib; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.mysql.builder.SQLColumn; +import me.skymc.taboolib.mysql.builder.SQLColumnType; +import me.skymc.taboolib.mysql.builder.SQLHost; +import me.skymc.taboolib.mysql.builder.SQLTable; +import me.skymc.taboolib.mysql.hikari.HikariHandler; +import me.skymc.taboolib.string.StringUtils; +import org.bukkit.Bukkit; + +import javax.sql.DataSource; +import java.util.HashMap; + +/** + * @Author sky + * @Since 2018-08-23 17:15 + */ +public class TabooLibDatabase { + + private static SQLHost host; + private static DataSource dataSource; + private static HashMap tables = new HashMap<>(); + + static void init() { + if (Main.getStorageType() != Main.StorageType.SQL) { + return; + } + // 数据库地址 + host = new SQLHost( + // 地址 + Main.getInst().getConfig().getString("MYSQL.HOST"), + // 用户 + Main.getInst().getConfig().getString("MYSQL.USER"), + // 端口 + Main.getInst().getConfig().getString("MYSQL.POST"), + // 密码 + Main.getInst().getConfig().getString("MYSQL.PASSWORD"), + // 数据库 + Main.getInst().getConfig().getString("MYSQL.DATABASE"), TabooLib.instance()); + // 连接数据库 + try { + dataSource = HikariHandler.createDataSource(host); + } catch (Exception ignored) { + TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FAIL"); + return; + } + // 创建各项数据表 + createTableWithPlayerData(); + createTableWithPluginData(); + createTableWithServerUUID(); + } + + /** + * 创建玩家数据表 + */ + static void createTableWithPlayerData() { + SQLTable table = new SQLTable(Main.getTablePrefix() + "_playerdata", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "username"), new SQLColumn(SQLColumnType.TEXT, "configuration")); + table.executeUpdate(table.createQuery()).dataSource(dataSource).run(); + tables.put("playerdata", table); + } + + /** + * 创建插件数据表 + */ + static void createTableWithPluginData() { + SQLTable table = new SQLTable(Main.getTablePrefix() + "_plugindata", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "name"), new SQLColumn(SQLColumnType.TEXT, "variable"), new SQLColumn(SQLColumnType.TEXT, "upgrade")); + table.executeUpdate(table.createQuery()).dataSource(dataSource).run(); + tables.put("plugindata", table); + } + + /** + * 创建服务器数据表 + */ + static void createTableWithServerUUID() { + SQLTable table = new SQLTable(Main.getTablePrefix() + "_serveruuid", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "uuid"), new SQLColumn(SQLColumnType.TEXT, "hash")); + table.executeUpdate(table.createQuery()).dataSource(dataSource).run(); + tables.put("serveruuid", table); + // 获取当前服务器信息 + String hash = getServerHash(TabooLib.getServerUID()); + if (hash == null) { + // 写入序列号 + table.executeUpdate("insert into " + table.getTableName() + " values(null, ?, ?)") + .dataSource(dataSource) + .statement(s -> { + s.setString(1, TabooLib.getServerUID()); + s.setString(2, StringUtils.hashKeyForDisk(Main.getInst().getDataFolder().getPath())); + }).run(); + } else if (!hash.equals(StringUtils.hashKeyForDisk(Main.getInst().getDataFolder().getPath()))) { + TLocale.Logger.error("NOTIFY.ERROR-SERVER-KEY"); + TabooLib.resetServerUID(); + Bukkit.shutdown(); + } + } + + /** + * 获取服务器序列号对应的目录哈希值 + * + * @param uuid 服务器序列号 + * @return 目录哈希值 + */ + public static String getServerHash(String uuid) { + SQLTable table = tables.get("serveruuid"); + return table.executeQuery("select * from " + table.getTableName() + " where uuid = ?") + .dataSource(dataSource) + .statement(s -> s.setString(1, uuid)) + .resultNext(r -> r.getString("hash")) + .run(null, ""); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static SQLHost getHost() { + return host; + } + + public static HashMap getTables() { + return tables; + } + + public static DataSource getDataSource() { + return dataSource; + } +} diff --git a/src/main/java/me/skymc/taboolib/TabooLibLoader.java b/src/main/java/me/skymc/taboolib/TabooLibLoader.java new file mode 100644 index 0000000..e753457 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/TabooLibLoader.java @@ -0,0 +1,126 @@ +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 me.skymc.taboolib.bstats.Metrics; +import me.skymc.taboolib.commands.language.Language2Command; +import me.skymc.taboolib.fileutils.FileUtils; +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.plugin.Plugin; + +import java.io.File; +import java.io.InputStream; +import java.net.InetAddress; +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * @Author sky + * @Since 2018-08-23 17:04 + */ +class TabooLibLoader { + + static void setup() { + testInternet(); + setupDataFolder(); + setupDatabase(); + setupLibraries(); + } + + static void register() { + registerListener(); + registerCommands(); + registerMetrics(); + } + + /** + * 初始化插件文件夹 + */ + static void setupDataFolder() { + Main.setPlayerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.PLAYER-DATA"))); + Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA"))); + } + + /** + * 初始化插件依赖库 + */ + static void setupLibraries() { + if (!Main.isOfflineVersion()) { + return; + } + for (Dependency dependency : TDependencyInjector.getDependencies(TLib.getTLib())) { + if (dependency.type() == Dependency.Type.LIBRARY && dependency.maven().matches(".*:.*:.*")) { + String fileName = String.join("-", dependency.maven().split(":")) + ".jar"; + File targetFile = FileUtils.file(TLib.getTLib().getLibsFolder(), fileName); + InputStream inputStream = FileUtils.getResource("libs/" + fileName); + if (!targetFile.exists() && inputStream != null) { + FileUtils.inputStreamToFile(inputStream, FileUtils.file(TLib.getTLib().getLibsFolder(), fileName)); + } + } + } + } + + /** + * 检查网络连接状态 + */ + static void testInternet() { + try { + InetAddress inetAddress = InetAddress.getByName(Main.getInst().getConfig().getString("TEST-URL", "aliyun.com")); + Main.setIsInternetOnline(inetAddress.isReachable(10000)); + } catch (Exception ignored) { + } + if (!Main.isInternetOnline() && !Main.isOfflineVersion() && !Main.isLibrariesExists()) { + TLocale.Logger.error("TLIB.LOAD-FAIL-OFFLINE", Main.getInst().getDescription().getVersion()); + try { + while (true) { + Thread.sleep(1000); + } + } catch (Exception ignored) { + } + } + } + + /** + * 载入插件数据库 + */ + 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 registerCommands() { + Bukkit.getPluginCommand("language2").setExecutor(new Language2Command()); + Bukkit.getPluginCommand("taboolibrarymodule").setExecutor(new TLMCommands()); + } + + /** + * 载入插件监听 + */ + static void registerListener() { + // 载入所有 TListener 监听器 + TListenerHandler.setupListeners(); + // 注册所有 TListener 监听器 + Bukkit.getScheduler().runTask(TabooLib.instance(), TListenerHandler::registerListeners); + } + + /** + * 注册插件统计 + */ + static void registerMetrics() { + Metrics metrics = new Metrics(TabooLib.instance()); + metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count()))); + metrics.addCustomChart(new Metrics.AdvancedPie("plugins_using_taboolib_name", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).collect(Collectors.toMap(Plugin::getName, plugin -> 1, (a, b) -> b)))); + } + +} diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java index cffc5d8..2ab1b0a 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java @@ -1,6 +1,7 @@ package me.skymc.taboolib.anvil; import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -19,9 +20,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -/** - * @author sky - */ +@TListener public class AnvilContainerAPI implements Listener { public static List list = new ArrayList<>(); diff --git a/src/main/java/me/skymc/taboolib/bstats/Metrics.java b/src/main/java/me/skymc/taboolib/bstats/Metrics.java index f8d9a67..42b50c0 100644 --- a/src/main/java/me/skymc/taboolib/bstats/Metrics.java +++ b/src/main/java/me/skymc/taboolib/bstats/Metrics.java @@ -1,6 +1,5 @@ package me.skymc.taboolib.bstats; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -18,21 +17,28 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.zip.GZIPOutputStream; /** * bStats collects some data for plugin authors. - *

* Check out https://bStats.org/ to learn more about bStats! + * + * @author Bastian */ public class Metrics { static { // You can use the property to disable the check in your test environment - if (System.getProperty("bstats.relocatecheck") == null || !"false".equals(System.getProperty("bstats.relocatecheck"))) { + if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D final String defaultPackage = new String( new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); @@ -44,34 +50,22 @@ public class Metrics { } } - /** - * The version of this bStats class - */ + // The version of this bStats class public static final int B_STATS_VERSION = 1; - /** - * The url to which the data is sent - */ + // The url to which the data is sent private static final String URL = "https://bStats.org/submitData/bukkit"; - /** - * Should failed requests be logged? - */ + // Should failed requests be logged? private static boolean logFailedRequests; - /** - * The uuid of the server - */ + // The uuid of the server private static String serverUUID; - /** - * The plugin - */ + // The plugin private final JavaPlugin plugin; - /** - * A list with all custom charts - */ + // A list with all custom charts private final List charts = new ArrayList<>(); /** @@ -109,32 +103,28 @@ public class Metrics { ).copyDefaults(true); try { config.save(configFile); - } catch (IOException ignored) { - } + } catch (IOException ignored) { } } // Load the data serverUUID = config.getString("serverUuid"); logFailedRequests = config.getBoolean("logFailedRequests", false); - - // ignored config - boolean found = false; - // Search for all other bStats Metrics classes to see if we are the first one - for (Class service : Bukkit.getServicesManager().getKnownServices()) { - try { - // Our identifier :) - service.getField("B_STATS_VERSION"); - // We aren't the first - found = true; - break; - } catch (NoSuchFieldException ignored) { + if (config.getBoolean("enabled", true)) { + boolean found = false; + // Search for all other bStats Metrics classes to see if we are the first one + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + found = true; // We aren't the first + break; + } catch (NoSuchFieldException ignored) { } + } + // Register our service + Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); + if (!found) { + // We are the first! + startSubmitting(); } - } - // Register our service - Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); - if (!found) { - // We are the first! - startSubmitting(); } } @@ -154,23 +144,27 @@ public class Metrics { * Starts the Scheduler which submits our data every 30 minutes. */ private void startSubmitting() { - ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("metrics-schedule-pool-%d").daemon(true).build()); - executorService.scheduleAtFixedRate(() -> { - if (!plugin.isEnabled()) { - executorService.shutdown(); - return; + final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (!plugin.isEnabled()) { // Plugin was disabled + timer.cancel(); + return; + } + // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler + // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) + Bukkit.getScheduler().runTask(plugin, new Runnable() { + @Override + public void run() { + submitData(); + } + }); } - /* - * Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler - * Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) - */ - Bukkit.getScheduler().runTask(plugin, this::submitData); - /* - * Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start - * WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! - * WARNING: Just don't do it! - */ - }, 5, 30, TimeUnit.MINUTES); + }, 1000*60*5, 1000*60*30); + // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start + // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! + // WARNING: Just don't do it! } /** @@ -185,16 +179,13 @@ public class Metrics { String pluginName = plugin.getDescription().getName(); String pluginVersion = plugin.getDescription().getVersion(); - // Append the name of the plugin - data.put("pluginName", pluginName); - // Append the version of the plugin - data.put("pluginVersion", pluginVersion); + data.put("pluginName", pluginName); // Append the name of the plugin + data.put("pluginVersion", pluginVersion); // Append the version of the plugin JSONArray customCharts = new JSONArray(); for (CustomChart customChart : charts) { // Add the data of the custom charts JSONObject chart = customChart.getRequestJsonObject(); - // If the chart is null, we skip it - if (chart == null) { + if (chart == null) { // If the chart is null, we skip it continue; } customCharts.add(chart); @@ -220,11 +211,10 @@ public class Metrics { ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; } catch (Exception e) { - // Just use the new method if the Reflection failed - playerAmount = Bukkit.getOnlinePlayers().size(); + playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed } int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; - String bukkitVersion = Bukkit.getVersion(); + String bukkitVersion = org.bukkit.Bukkit.getVersion(); bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); // OS/Java specific data @@ -261,33 +251,33 @@ public class Metrics { // Search for all other bStats Metrics classes to get their plugin data for (Class service : Bukkit.getServicesManager().getKnownServices()) { try { - // Our identifier :) - service.getField("B_STATS_VERSION"); + service.getField("B_STATS_VERSION"); // Our identifier :) for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { try { pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider())); - } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { - } + } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } } - } catch (NoSuchFieldException ignored) { - } + } catch (NoSuchFieldException ignored) { } } data.put("plugins", pluginData); // Create a new thread for the connection to the bStats server - Executors.newSingleThreadExecutor().execute(() -> { - try { - // Send the data - sendData(data); - } catch (Exception e) { - // Something went wrong! :( - if (logFailedRequests) { - plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + new Thread(new Runnable() { + @Override + public void run() { + try { + // Send the data + sendData(data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + } } } - }); + }).start(); } /** @@ -312,11 +302,9 @@ public class Metrics { connection.setRequestMethod("POST"); connection.addRequestProperty("Accept", "application/json"); connection.addRequestProperty("Connection", "close"); - // We gzip our request - connection.addRequestProperty("Content-Encoding", "gzip"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - // We send our data in JSON format - connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); // Send data @@ -326,8 +314,7 @@ public class Metrics { outputStream.flush(); outputStream.close(); - // We don't care about the response - Just send our data :) - connection.getInputStream().close(); + connection.getInputStream().close(); // We don't care about the response - Just send our data :) } /** @@ -353,9 +340,7 @@ public class Metrics { */ public static abstract class CustomChart { - /** - * The id of the chart - */ + // The id of the chart final String chartId; /** @@ -403,7 +388,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public SimplePie(String chartId, Callable callable) { @@ -434,7 +419,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public AdvancedPie(String chartId, Callable> callable) { @@ -478,7 +463,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public DrilldownPie(String chartId, Callable>> callable) { @@ -527,7 +512,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public SingleLineChart(String chartId, Callable callable) { @@ -559,7 +544,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public MultiLineChart(String chartId, Callable> callable) { @@ -604,7 +589,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public SimpleBarChart(String chartId, Callable> callable) { @@ -642,7 +627,7 @@ public class Metrics { /** * Class constructor. * - * @param chartId The id of the chart. + * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ public AdvancedBarChart(String chartId, Callable> callable) { diff --git a/src/main/java/me/skymc/taboolib/bungee/TabooLibBungee.java b/src/main/java/me/skymc/taboolib/bungee/TabooLibBungee.java new file mode 100644 index 0000000..1709569 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/bungee/TabooLibBungee.java @@ -0,0 +1,11 @@ +package me.skymc.taboolib.bungee; + +import net.md_5.bungee.api.plugin.Plugin; + +/** + * @Author sky + * @Since 2018-08-09 11:47 + */ +public class TabooLibBungee extends Plugin { + +} diff --git a/src/main/java/me/skymc/taboolib/client/LogClient.java b/src/main/java/me/skymc/taboolib/client/LogClient.java index 5fce466..2daf023 100644 --- a/src/main/java/me/skymc/taboolib/client/LogClient.java +++ b/src/main/java/me/skymc/taboolib/client/LogClient.java @@ -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()); } diff --git a/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java b/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java index f83d847..f75ea8c 100644 --- a/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.TCommand; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.commands.internal.type.CommandRegister; import me.skymc.taboolib.string.ArrayUtils; @@ -18,6 +19,11 @@ import org.bukkit.event.server.ServerCommandEvent; * @Author sky * @Since 2018-07-04 21:32 */ +@TCommand( + name = "taboolibexecute", + aliases = {"texecute"}, + permission = "taboolib.admin" +) public class TabooLibExecuteCommand extends BaseMainCommand { @Override diff --git a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java index 705133c..954d423 100644 --- a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java @@ -5,15 +5,22 @@ import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.TCommand; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.commands.internal.type.CommandRegister; import me.skymc.taboolib.commands.internal.type.CommandType; import me.skymc.taboolib.commands.taboolib.*; +import me.skymc.taboolib.database.GlobalDataManager; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.inventory.ItemUtils; +import me.skymc.taboolib.other.DateUtils; import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.player.PlayerUtils; import me.skymc.taboolib.plugin.PluginUtils; +import me.skymc.taboolib.timecycle.TimeCycle; +import me.skymc.taboolib.timecycle.TimeCycleEvent; +import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent; +import me.skymc.taboolib.timecycle.TimeCycleManager; import me.skymc.taboolib.update.UpdateTask; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -21,11 +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", + permission = "taboolib.admin", + aliases = "tlib" +) public class TabooLibMainCommand extends BaseMainCommand { @Override @@ -417,7 +431,9 @@ public class TabooLibMainCommand extends BaseMainCommand { @Override public void onCommand(CommandSender sender, Command command, String label, String[] args) { - new CycleListCommand(sender, args); + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.HEAD"); + TimeCycleManager.getTimeCycles().forEach(cycle -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.BODY", cycle.getName())); + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.FOOT"); } }; @@ -443,12 +459,24 @@ public class TabooLibMainCommand extends BaseMainCommand { @Override public void onCommand(CommandSender sender, Command command, String label, String[] args) { - new CycleInfoCommand(sender, args); + TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]); + if (cycle == null) { + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]); + } else { + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-INFO", + asString(cycle.getCycle() / 1000L), + cycle.getPlugin().getName(), + DateUtils.CH_ALL.format(TimeCycleManager.getBeforeTimeline(cycle.getName())), + DateUtils.CH_ALL.format(TimeCycleManager.getAfterTimeline(cycle.getName()))); + } } - @Override - public boolean ignoredLabel() { - return false; + private String asString(long seconds) { + long day = TimeUnit.SECONDS.toDays(seconds); + long hours = TimeUnit.SECONDS.toHours(seconds) - day * 24; + long minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toHours(seconds) * 60L; + long second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toMinutes(seconds) * 60L; + return "§f" + day + "§7 天, §f" + hours + "§7 小时, §f" + minute + "§7 分钟, §f" + second + "§7 秒"; } }; @@ -474,12 +502,24 @@ public class TabooLibMainCommand extends BaseMainCommand { @Override public void onCommand(CommandSender sender, Command command, String label, String[] args) { - new CycleResetCommand(sender, args); - } + TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]); + if (cycle == null) { + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]); + return; + } + new BukkitRunnable() { - @Override - public boolean ignoredLabel() { - return false; + @Override + public void run() { + long time = new TimeCycleInitializeEvent(cycle, System.currentTimeMillis()).call().getTimeline(); + // 初始化 + GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time)); + // 触发器 + Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); + // 提示 + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-RESET", args[0]); + } + }.runTaskAsynchronously(Main.getInst()); } }; @@ -505,84 +545,30 @@ public class TabooLibMainCommand extends BaseMainCommand { @Override public void onCommand(CommandSender sender, Command command, String label, String[] args) { - new CycleUpdateCommand(sender, args); - } + TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]); + if (cycle == null) { + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]); + return; + } + new BukkitRunnable() { - @Override - public boolean ignoredLabel() { - return false; + @Override + public void run() { + // 重置 + GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(System.currentTimeMillis())); + // 触发器 + Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); + // 提示 + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-UPDATE", args[0]); + } + }.runTaskAsynchronously(Main.getInst()); } }; @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 diff --git a/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java index 36ac981..ca6f376 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/BaseMainCommand.java @@ -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> linkClasses = new CopyOnWriteArrayList<>(); private List 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 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 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 ? "~" : ""; } diff --git a/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java index d8531eb..37a8dd8 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java @@ -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()); diff --git a/src/main/java/me/skymc/taboolib/commands/internal/IMainCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/IMainCommand.java deleted file mode 100644 index f280e1d..0000000 --- a/src/main/java/me/skymc/taboolib/commands/internal/IMainCommand.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.skymc.taboolib.commands.internal; - -/** - * @Author sky - * @Since 2018-05-07 21:36 - */ -public interface IMainCommand { - - /** - * 指令标题 - * - * @return 文本 - */ - String getCommandTitle(); - -} diff --git a/src/main/java/me/skymc/taboolib/commands/internal/ISubCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/ISubCommand.java deleted file mode 100644 index b9c2d07..0000000 --- a/src/main/java/me/skymc/taboolib/commands/internal/ISubCommand.java +++ /dev/null @@ -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); - -} diff --git a/src/main/java/me/skymc/taboolib/commands/internal/TBaseCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/TBaseCommand.java deleted file mode 100644 index 5d09a2d..0000000 --- a/src/main/java/me/skymc/taboolib/commands/internal/TBaseCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.skymc.taboolib.commands.internal; - -/** - * @Author sky - * @Since 2018-05-23 2:43 - */ -public class TBaseCommand { - - /** - * 向服务端注册 BaseMainCommand 类 - * - * @param command 命令全称(需在 plugin.yml 内注册) - * @param baseMainCommand 命令对象 - * @return {@link BaseMainCommand} - */ - public static BaseMainCommand registerCommand(String command, BaseMainCommand baseMainCommand) { - return BaseMainCommand.createCommandExecutor(command, baseMainCommand); - } -} diff --git a/src/main/java/me/skymc/taboolib/commands/internal/TCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/TCommand.java new file mode 100644 index 0000000..b3a69c7 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/commands/internal/TCommand.java @@ -0,0 +1,28 @@ +package me.skymc.taboolib.commands.internal; + +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 + * @Since 2018-08-23 20:34 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface TCommand { + + String name(); + + String permission() default ""; + + String permissionMessage() default ""; + + String description() default ""; + + String usage() default ""; + + String[] aliases() default ""; +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java b/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java new file mode 100644 index 0000000..16579ae --- /dev/null +++ b/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java @@ -0,0 +1,184 @@ +package me.skymc.taboolib.commands.internal; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.TabooLib; +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 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 aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabExecutor tabExecutor) { + try { + Constructor 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()) { + if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) { + 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; + } +} diff --git a/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java b/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java index b7800d1..da87278 100644 --- a/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java @@ -4,12 +4,12 @@ import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocaleLoader; import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.TCommand; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.commands.internal.type.CommandRegister; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -22,6 +22,11 @@ import java.util.stream.IntStream; * @author sky * @since 2018-04-22 14:36:28 */ +@TCommand( + name = "tabooliblocale", + aliases = {"taboolocale", "tlocale"}, + permission = "taboolib.admin" +) public class TabooLibLocaleCommand extends BaseMainCommand { @Override diff --git a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java index 2cc8b40..56f8b2f 100644 --- a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java @@ -4,7 +4,7 @@ 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; import me.skymc.taboolib.plugin.PluginLoadState; @@ -25,6 +25,11 @@ import java.util.stream.Collectors; * @Author sky * @Since 2018-05-07 20:14 */ +@TCommand( + name = "taboolibplugin", + aliases = {"tabooplugin", "tplugin"}, + permission = "taboolib.admin" +) public class TabooLibPluginCommand extends BaseMainCommand { @Override @@ -35,7 +40,7 @@ public class TabooLibPluginCommand extends BaseMainCommand { @Override public List 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 { @@ -58,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 @@ -108,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 @@ -150,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 @@ -183,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 diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleInfoCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/CycleInfoCommand.java deleted file mode 100644 index 6307c0c..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleInfoCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.other.DateUtils; -import me.skymc.taboolib.timecycle.TimeCycle; -import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.command.CommandSender; - -import java.util.concurrent.TimeUnit; - -public class CycleInfoCommand extends SubCommand { - - public CycleInfoCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]); - if (cycle == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[2]); - return; - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-INFO", - asString(cycle.getCycle() / 1000L), - cycle.getPlugin().getName(), - DateUtils.CH_ALL.format(TimeCycleManager.getBeforeTimeline(cycle.getName())), - DateUtils.CH_ALL.format(TimeCycleManager.getAfterTimeline(cycle.getName()))); - } - - public String asString(long seconds) { - long day = TimeUnit.SECONDS.toDays(seconds); - long hours = TimeUnit.SECONDS.toHours(seconds) - day * 24; - long minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toHours(seconds) * 60L; - long second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toMinutes(seconds) * 60L; - return "§f" + day + "§7 天, §f" + hours + "§7 小时, §f" + minute + "§7 分钟, §f" + second + "§7 秒"; - } - - @Override - public boolean command() { - return true; - } -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleListCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/CycleListCommand.java deleted file mode 100644 index 63561e5..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleListCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.command.CommandSender; - -public class CycleListCommand extends SubCommand { - - public CycleListCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.HEAD"); - - TimeCycleManager.getTimeCycles().forEach(cycle -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.BODY", cycle.getName())); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.FOOT"); - } - - @Override - public boolean command() { - return true; - } - -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleResetCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/CycleResetCommand.java deleted file mode 100644 index 5af4875..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleResetCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.database.GlobalDataManager; -import me.skymc.taboolib.timecycle.TimeCycle; -import me.skymc.taboolib.timecycle.TimeCycleEvent; -import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent; -import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.scheduler.BukkitRunnable; - -public class CycleResetCommand extends SubCommand { - - public CycleResetCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]); - if (cycle == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[2]); - return; - } - - new BukkitRunnable() { - - @Override - public void run() { - long time = new TimeCycleInitializeEvent(cycle, System.currentTimeMillis()).call().getTimeline(); - // 初始化 - GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time)); - // 触发器 - Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); - // 提示 - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-RESET", args[2]); - } - }.runTaskAsynchronously(Main.getInst()); - } - - @Override - public boolean command() { - return true; - } - -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleUpdateCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/CycleUpdateCommand.java deleted file mode 100644 index ad2ff66..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/CycleUpdateCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.database.GlobalDataManager; -import me.skymc.taboolib.timecycle.TimeCycle; -import me.skymc.taboolib.timecycle.TimeCycleEvent; -import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.scheduler.BukkitRunnable; - -public class CycleUpdateCommand extends SubCommand { - - public CycleUpdateCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]); - if (cycle == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[2]); - return; - } - - new BukkitRunnable() { - - @Override - public void run() { - // 重置 - GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(System.currentTimeMillis())); - // 触发器 - Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); - // 提示 - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-UPDATE", args[2]); - } - }.runTaskAsynchronously(Main.getInst()); - } - - @Override - public boolean command() { - return true; - } - -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/ShellLoadCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/ShellLoadCommand.java deleted file mode 100644 index d8e87eb..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/ShellLoadCommand.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/ShellUnloadCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/ShellUnloadCommand.java deleted file mode 100644 index 995ae2b..0000000 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/ShellUnloadCommand.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java index 42d3bf7..0346b2f 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java @@ -3,6 +3,7 @@ package me.skymc.taboolib.commands.taboolib.listener; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.inventory.InventoryUtil; import me.skymc.taboolib.inventory.ItemUtils; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -23,6 +24,7 @@ import java.util.List; * @author sky * @since 2018年2月4日 下午4:35:00 */ +@TListener public class ListenerItemListCommand implements Listener { /** diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java index 3985f99..d55d6b4 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java @@ -3,6 +3,7 @@ package me.skymc.taboolib.commands.taboolib.listener; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.inventory.InventoryUtil; import me.skymc.taboolib.inventory.ItemUtils; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -24,6 +25,7 @@ import java.util.stream.Collectors; * @author sky * @since 2018年2月4日 下午4:35:00 */ +@TListener public class ListenerSoundsCommand implements Listener { public static void openInventory(Player player, int page, String search) { diff --git a/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java b/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java index a61da6c..1fffb19 100644 --- a/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java +++ b/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java @@ -14,419 +14,402 @@ import java.util.LinkedList; import java.util.concurrent.ConcurrentHashMap; public class GlobalDataManager { - - public static FileConfiguration data = DataUtils.addPluginData("TabooLibrary-Variable.yml", null); - - /** - * 获取变量 - * - * @param name 名称 - * @param defaultVariable 默认值 - * @return - */ - public static String getVariable(String name, String defaultVariable) { - if (Main.getStorageType() == StorageType.SQL) { - Object obj = Main.getConnection().getValueLast(Main.getTablePrefix() + "_plugindata", "name", name, "variable"); - return obj != null ? "null".equals(obj.toString()) ? defaultVariable : obj.toString() : defaultVariable; - } - else { - return data.contains(name) ? data.getString(name) : defaultVariable; - } - } - - /** - * 获取缓存变量(该方法仅限数据库储存方式) - * - * @param name 名称 - * @param defaultVariable 默认值 - * @return - */ - public static String getVariableAsynchronous(String name, String defaultVariable) { - if (Main.getStorageType() == StorageType.SQL) { - SQLVariable variable = SQLMethod.getSQLVariable(name); - return variable == null ? defaultVariable : "null".equals(variable.getVariable()) ? defaultVariable : variable.getVariable(); - } - else { - return getVariable(name, defaultVariable); - } - } - - /** - * 设置变量 - * - * @param name 名称 - * @param variable 变量 - */ - public static void setVariable(String name, String variable) { - if (Main.getStorageType() == StorageType.SQL) { - Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, variable == null ? "null" : variable, TabooLib.getServerUID()); - } - else { - data.set(name, variable); - } - } - - /** - * 设置缓存变量(该方法仅限数据库储存方式) - * - * @param name - * @param variable - */ - public static void setVariableAsynchronous(String name, String variable) { - if (Main.getStorageType() == StorageType.SQL) { - SQLVariable _variable = SQLMethod.contains(name) ? SQLMethod.getSQLVariable(name).setVariable(variable == null ? "null" : variable) : SQLMethod.addSQLVariable(name, variable == null ? "null" : variable); - // 更新数据 - SQLMethod.uploadVariable(_variable, true); - } - else { - setVariable(name, variable); - } - } - - /** - * 检查变量是否存在 - * - * @param name 名称 - */ - public static boolean contains(String name) { - if (Main.getStorageType() == StorageType.SQL) { + + public static FileConfiguration data = DataUtils.addPluginData("TabooLibrary-Variable.yml", null); + + /** + * 获取变量 + * + * @param name 名称 + * @param defaultVariable 默认值 + * @return + */ + public static String getVariable(String name, String defaultVariable) { + if (Main.getStorageType() == StorageType.SQL) { + Object obj = Main.getConnection().getValueLast(Main.getTablePrefix() + "_plugindata", "name", name, "variable"); + return obj != null ? "null".equals(obj.toString()) ? defaultVariable : obj.toString() : defaultVariable; + } else { + return data.contains(name) ? data.getString(name) : defaultVariable; + } + } + + /** + * 获取缓存变量(该方法仅限数据库储存方式) + * + * @param name 名称 + * @param defaultVariable 默认值 + * @return + */ + public static String getVariableAsynchronous(String name, String defaultVariable) { + if (Main.getStorageType() == StorageType.SQL) { + SQLVariable variable = SQLMethod.getSQLVariable(name); + return variable == null ? defaultVariable : "null".equals(variable.getVariable()) ? defaultVariable : variable.getVariable(); + } else { + return getVariable(name, defaultVariable); + } + } + + /** + * 设置变量 + * + * @param name 名称 + * @param variable 变量 + */ + public static void setVariable(String name, String variable) { + if (Main.getStorageType() == StorageType.SQL) { + Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, variable == null ? "null" : variable, TabooLib.getServerUID()); + } else { + data.set(name, variable); + } + } + + /** + * 设置缓存变量(该方法仅限数据库储存方式) + * + * @param name + * @param variable + */ + public static void setVariableAsynchronous(String name, String variable) { + if (Main.getStorageType() == StorageType.SQL) { + SQLVariable _variable = SQLMethod.contains(name) ? SQLMethod.getSQLVariable(name).setVariable(variable == null ? "null" : variable) : SQLMethod.addSQLVariable(name, variable == null ? "null" : variable); + // 更新数据 + SQLMethod.uploadVariable(_variable, true); + } else { + setVariable(name, variable); + } + } + + /** + * 检查变量是否存在 + * + * @param name 名称 + */ + public static boolean contains(String name) { + if (Main.getStorageType() == StorageType.SQL) { return getVariable(name, null) != null; - } - else { - return data.contains(name); - } - } - - /** - * 检查变量是否被缓存(该方法仅限数据库储存方式) - * - * @param name 名称 - * @return - */ - public static boolean containsAsynchronous(String name) { - if (Main.getStorageType() == StorageType.SQL) { + } else { + return data.contains(name); + } + } + + /** + * 检查变量是否被缓存(该方法仅限数据库储存方式) + * + * @param name 名称 + * @return + */ + public static boolean containsAsynchronous(String name) { + if (Main.getStorageType() == StorageType.SQL) { return getVariableAsynchronous(name, null) != null; - } - else { - return contains(name); - } - } - - /** - * 清理所有失效的变量 - * 该方法仅限数据库储存时有效 - */ - public static void clearInvalidVariables() { - if (Main.getStorageType() == StorageType.SQL) { - HashMap map = getVariables(); - Main.getConnection().truncateTable(Main.getTablePrefix() + "_plugindata"); - for (String name : map.keySet()) { - Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, map.get(name), TabooLib.getServerUID()); - } - } - } - - /** - * 获取所有有效变量 - * - * @return - */ - public static HashMap getVariables() { - HashMap map = new HashMap<>(); - if (Main.getStorageType() == StorageType.SQL) { - LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable"); - for (HashMap _map : list) { - if (!"null".equals(_map.get("variable").toString())) { - map.put(_map.get("name").toString(), _map.get("variable").toString()); - } - } - } - else { - for (String name : data.getConfigurationSection("").getKeys(false)) { - map.put(name, data.getString(name)); - } - } - return map; - } - - /** - * 获取缓存变量(该方法仅限数据库储存方式) - * - * @return - */ - public static HashMap getVariablesAsynchronous() { - if (Main.getStorageType() == StorageType.SQL) { - HashMap map = new HashMap<>(); - for (SQLVariable variable : SQLMethod.getSQLVariables()) { - if (!"null".equals(variable.getVariable())) { - map.put(variable.getName(), variable.getVariable()); - } - } - return map; - } - else { - return getVariables(); - } - } - - /** - * 数据库变量 - * - * @author sky - * - */ - public static class SQLVariable { - - public String name = ""; - public String variable = ""; - public String upgradeUID = ""; - - public SQLVariable(String name, String variable, String upgradeUID) { - this.name = name; - this.variable = variable; - this.upgradeUID = upgradeUID; - } - - public String getName() { - return name; - } - - public String getVariable() { - return variable; - } - - public SQLVariable setVariable(String args) { - this.variable = args; - return this; - } - - public String getUpgradeUID() { - return upgradeUID; - } - } - - /** - * 数据库方法 - * - * @author sky - * - */ - public static class SQLMethod { - - private static ConcurrentHashMap variables = new ConcurrentHashMap<>(); - - /** - * 获取数据 - * - * @param name 名字 - */ - public static SQLVariable getSQLVariable(String name) { - return variables.get(name); - } - - /** - * 获取所有变量 - * - * @return - */ - public static Collection getSQLVariables() { - return variables.values(); - } - - /** - * 添加一个变量 - * - * @param name 名字 - * @param value 值 - * @return - */ - public static SQLVariable addSQLVariable(String name, String value) { - SQLVariable variable = new SQLVariable(name, value, TabooLib.getServerUID()); - variables.put(name, variable); - return variable; - } - - /** - * 移除一个变量 - * - * @param name 名字 - * @return - */ - public static SQLVariable removeSQLVariable(String name) { - if (variables.contains(name)) { - variables.get(name).setVariable("null"); - } - return variables.get(name); - } - - /** - * 是否包含变量 - * - * @param name 名字 - * @return - */ - public static boolean contains(String name) { - return variables.containsKey(name); - } - - /** - * 载入数据库中的所有变量缓存 - * - * @param sync 是否异步 - */ - public static void loadVariables(boolean sync) { - if (Main.getStorageType() == StorageType.LOCAL) { - return; - } - - BukkitRunnable runnable = new BukkitRunnable() { - - @Override - public void run() { - LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade"); - for (HashMap _map : list) { - if (!"null".equals(_map.get("variable").toString())) { - variables.put(_map.get("name").toString(), new SQLVariable(_map.get("name").toString(), _map.get("variable").toString(), _map.get("upgrade").toString())); - } - } - } - }; - - if (sync) { - runnable.runTaskAsynchronously(Main.getInst()); - } - else { - runnable.run(); - } - } - - /** - * 检查当前变量是否被其他服务器更新 - * - * @param sync 是否异步 - */ - public static void checkVariable(boolean sync) { - if (Main.getStorageType() == StorageType.LOCAL) { - return; - } - - BukkitRunnable runnable = new BukkitRunnable() { - - @Override - public void run() { - LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade"); - // 循环变量 - for (HashMap value : list) { - Object name = value.get("name"); - try { - // 如果变量存在 - if (variables.containsKey(name)) { - // 如果变量不是由本服更新 - if (!value.get("upgrade").equals(variables.get(name).getUpgradeUID())) { - // 如果变量是空 - if ("null".equals(value.get("variable"))) { - // 删除变量 - variables.remove(name); - } - else { - // 更新变量 - variables.get(name).setVariable(value.get("variable").toString()); - } - } - } - // 如果变量存在则下载到本地 - else if (!"null".equals(value.get("variable"))) { - variables.put(value.get("name").toString(), new SQLVariable(value.get("name").toString(), value.get("variable").toString(), value.get("upgrade").toString())); - } - } - catch (Exception e) { - // 移除 - variables.remove(name); - // 提示 - TLocale.Logger.error("GLOBAL-DATAMANAGER.ERROR-CHECK-VARIABLE", String.valueOf(name), e.toString()); - } - } - } - }; - - if (sync) { - runnable.runTaskAsynchronously(Main.getInst()); - } - else { - runnable.run(); - } - } - - /** - * 向数据库上传所有数据 - * - * @param sync 是否异步 - */ - public static void uploadVariables(boolean sync) { - if (Main.getStorageType() == StorageType.LOCAL) { - return; - } - - for (SQLVariable variable : variables.values()) { - uploadVariable(variable, sync); - } - } - - /** - * 向数据库上传当前数据 - * - * @param variable 数据 - * @param sync 是否异步 - */ - public static void uploadVariable(SQLVariable variable, boolean sync) { - if (Main.getStorageType() == StorageType.LOCAL) { - return; - } - - BukkitRunnable runnable = new BukkitRunnable() { - - @Override - public void run() { - Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", variable.getName(), variable.getVariable() == null ? "null" : variable.getVariable(), TabooLib.getServerUID()); - } - }; - - if (sync) { - runnable.runTaskAsynchronously(Main.getInst()); - } - else { - runnable.run(); - } - } - - /** - * 启动数据库储存方法 - * - */ - public static void startSQLMethod() { - long time = System.currentTimeMillis(); - // 载入数据 - loadVariables(false); - // 提示信息 + } else { + return contains(name); + } + } + + /** + * 清理所有失效的变量 + * 该方法仅限数据库储存时有效 + */ + public static void clearInvalidVariables() { + if (Main.getStorageType() == StorageType.SQL) { + HashMap map = getVariables(); + Main.getConnection().truncateTable(Main.getTablePrefix() + "_plugindata"); + for (String name : map.keySet()) { + Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, map.get(name), TabooLib.getServerUID()); + } + } + } + + /** + * 获取所有有效变量 + * + * @return + */ + public static HashMap getVariables() { + HashMap map = new HashMap<>(); + if (Main.getStorageType() == StorageType.SQL) { + LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable"); + for (HashMap _map : list) { + if (!"null".equals(_map.get("variable").toString())) { + map.put(_map.get("name").toString(), _map.get("variable").toString()); + } + } + } else { + for (String name : data.getConfigurationSection("").getKeys(false)) { + map.put(name, data.getString(name)); + } + } + return map; + } + + /** + * 获取缓存变量(该方法仅限数据库储存方式) + * + * @return + */ + public static HashMap getVariablesAsynchronous() { + if (Main.getStorageType() == StorageType.SQL) { + HashMap map = new HashMap<>(); + for (SQLVariable variable : SQLMethod.getSQLVariables()) { + if (!"null".equals(variable.getVariable())) { + map.put(variable.getName(), variable.getVariable()); + } + } + return map; + } else { + return getVariables(); + } + } + + /** + * 数据库变量 + * + * @author sky + */ + public static class SQLVariable { + + public String name = ""; + public String variable = ""; + public String upgradeUID = ""; + + public SQLVariable(String name, String variable, String upgradeUID) { + this.name = name; + this.variable = variable; + this.upgradeUID = upgradeUID; + } + + public String getName() { + return name; + } + + public String getVariable() { + return variable; + } + + public SQLVariable setVariable(String args) { + this.variable = args; + return this; + } + + public String getUpgradeUID() { + return upgradeUID; + } + } + + /** + * 数据库方法 + * + * @author sky + */ + public static class SQLMethod { + + private static ConcurrentHashMap variables = new ConcurrentHashMap<>(); + + /** + * 获取数据 + * + * @param name 名字 + */ + public static SQLVariable getSQLVariable(String name) { + return variables.get(name); + } + + /** + * 获取所有变量 + * + * @return + */ + public static Collection getSQLVariables() { + return variables.values(); + } + + /** + * 添加一个变量 + * + * @param name 名字 + * @param value 值 + * @return + */ + public static SQLVariable addSQLVariable(String name, String value) { + SQLVariable variable = new SQLVariable(name, value, TabooLib.getServerUID()); + variables.put(name, variable); + return variable; + } + + /** + * 移除一个变量 + * + * @param name 名字 + * @return + */ + public static SQLVariable removeSQLVariable(String name) { + if (variables.contains(name)) { + variables.get(name).setVariable("null"); + } + return variables.get(name); + } + + /** + * 是否包含变量 + * + * @param name 名字 + * @return + */ + public static boolean contains(String name) { + return variables.containsKey(name); + } + + /** + * 载入数据库中的所有变量缓存 + * + * @param sync 是否异步 + */ + public static void loadVariables(boolean sync) { + if (Main.getStorageType() == StorageType.LOCAL) { + return; + } + + BukkitRunnable runnable = new BukkitRunnable() { + + @Override + public void run() { + LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade"); + for (HashMap _map : list) { + if (!"null".equals(_map.get("variable").toString())) { + variables.put(_map.get("name").toString(), new SQLVariable(_map.get("name").toString(), _map.get("variable").toString(), _map.get("upgrade").toString())); + } + } + } + }; + + if (sync) { + runnable.runTaskAsynchronously(Main.getInst()); + } else { + runnable.run(); + } + } + + /** + * 检查当前变量是否被其他服务器更新 + * + * @param sync 是否异步 + */ + public static void checkVariable(boolean sync) { + if (Main.getStorageType() == StorageType.LOCAL) { + return; + } + + BukkitRunnable runnable = new BukkitRunnable() { + + @Override + public void run() { + LinkedList> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade"); + // 循环变量 + for (HashMap value : list) { + Object name = value.get("name"); + try { + // 如果变量存在 + if (variables.containsKey(name)) { + // 如果变量不是由本服更新 + if (!value.get("upgrade").equals(variables.get(name).getUpgradeUID())) { + // 如果变量是空 + if ("null".equals(value.get("variable"))) { + // 删除变量 + variables.remove(name); + } else { + // 更新变量 + variables.get(name).setVariable(value.get("variable").toString()); + } + } + } + // 如果变量存在则下载到本地 + else if (!"null".equals(value.get("variable"))) { + variables.put(value.get("name").toString(), new SQLVariable(value.get("name").toString(), value.get("variable").toString(), value.get("upgrade").toString())); + } + } catch (Exception e) { + // 移除 + variables.remove(name); + // 提示 + TLocale.Logger.error("GLOBAL-DATAMANAGER.ERROR-CHECK-VARIABLE", String.valueOf(name), e.toString()); + } + } + } + }; + + if (sync) { + runnable.runTaskAsynchronously(Main.getInst()); + } else { + runnable.run(); + } + } + + /** + * 向数据库上传所有数据 + * + * @param sync 是否异步 + */ + public static void uploadVariables(boolean sync) { + if (Main.getStorageType() == StorageType.LOCAL) { + return; + } + + for (SQLVariable variable : variables.values()) { + uploadVariable(variable, sync); + } + } + + /** + * 向数据库上传当前数据 + * + * @param variable 数据 + * @param sync 是否异步 + */ + public static void uploadVariable(SQLVariable variable, boolean sync) { + if (Main.getStorageType() == StorageType.LOCAL) { + return; + } + + BukkitRunnable runnable = new BukkitRunnable() { + + @Override + public void run() { + Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", variable.getName(), variable.getVariable() == null ? "null" : variable.getVariable(), TabooLib.getServerUID()); + } + }; + + if (sync) { + runnable.runTaskAsynchronously(Main.getInst()); + } else { + runnable.run(); + } + } + + /** + * 启动数据库储存方法 + */ + public static void startSQLMethod() { + long time = System.currentTimeMillis(); + // 载入数据 + loadVariables(false); + // 提示信息 TLocale.Logger.info("GLOBAL-DATAMANAGER.SUCCESS-LOADED-VARIABLE", String.valueOf(variables.size()), String.valueOf(System.currentTimeMillis() - time)); - // 检查更新 - new BukkitRunnable() { - - @Override - public void run() { - checkVariable(true); - } - }.runTaskTimerAsynchronously(Main.getInst(), Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20, Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20); - } - - /** - * 结束数据库储存方法 - * - */ - public static void cancelSQLMethod() { - // 上传数据 - uploadVariables(false); - } - } + // 检查更新 + new BukkitRunnable() { + + @Override + public void run() { + checkVariable(true); + } + }.runTaskTimerAsynchronously(Main.getInst(), Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20, Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20); + } + + /** + * 结束数据库储存方法 + */ + public static void cancelSQLMethod() { + // 上传数据 + uploadVariables(false); + } + } } diff --git a/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java b/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java index 51d2f09..93871a7 100644 --- a/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java +++ b/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java @@ -7,6 +7,7 @@ import me.skymc.taboolib.events.PlayerLoadedEvent; import me.skymc.taboolib.exception.PlayerOfflineException; import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; @@ -22,6 +23,7 @@ import java.io.File; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +@TListener public class PlayerDataManager implements Listener { private static final ConcurrentHashMap PLAYER_DATA = new ConcurrentHashMap<>(); diff --git a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java b/src/main/java/me/skymc/taboolib/entity/EntityUtils.java index 549d52f..d324e00 100644 --- a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java +++ b/src/main/java/me/skymc/taboolib/entity/EntityUtils.java @@ -5,7 +5,8 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.exception.PluginNotFoundException; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Entity; @@ -17,6 +18,10 @@ import org.bukkit.event.entity.EntitySpawnEvent; import java.lang.reflect.InvocationTargetException; import java.util.UUID; +/** + * @author sky + */ +@TListener(condition = "check") public class EntityUtils implements Listener { private static Entity lastSpawnedEntity = null; @@ -25,6 +30,10 @@ public class EntityUtils implements Listener { return lastSpawnedEntity; } + public static boolean check() { + return TabooLib.getVerint() > 10700; + } + /** * 根据 UUID 获取生物 * @@ -42,7 +51,7 @@ public class EntityUtils implements Listener { * @param world * @return */ - public static Entity getEntityWithUUID_World(UUID u, World world) { + public static Entity getEntityWithUUID(UUID u, World world) { return world.getLivingEntities().stream().filter(e -> e.getUniqueId().equals(u)).findFirst().orElse(null); } diff --git a/src/main/java/me/skymc/taboolib/fileutils/CopyUtils.java b/src/main/java/me/skymc/taboolib/fileutils/CopyUtils.java deleted file mode 100644 index dbfaa3a..0000000 --- a/src/main/java/me/skymc/taboolib/fileutils/CopyUtils.java +++ /dev/null @@ -1,97 +0,0 @@ -package me.skymc.taboolib.fileutils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; - -@Deprecated -public class CopyUtils { - - public static long Copy(File file1, File file2) throws IOException { - // CHECK THE FILE - if (!file1.exists()) { - file1.createNewFile(); - } - if (!file2.exists()) { - file2.createNewFile(); - } - - // RESET TIME - long time = System.currentTimeMillis(); - - // I/O SETTING - FileInputStream in = new FileInputStream(file1); - FileOutputStream out = new FileOutputStream(file2); - FileChannel inC = in.getChannel(); - FileChannel outC = out.getChannel(); - ByteBuffer b = null; - - // CAPACITY [2GB] - Integer length = 2097152; - - // WORKSPACE - while (true) { - if (inC.position() == inC.size()) { - inC.close(); - outC.close(); - return System.currentTimeMillis() - time; - } - if ((inC.size() - inC.position()) < length) { - length = (int) (inC.size()-inC.position()); - } - else { - length = 2097152; - } - - b = ByteBuffer.allocateDirect(length); - inC.read(b); - b.flip(); - outC.write(b); - outC.force(false); - } - } - - public static long Copy(FileInputStream in, File file2) throws IOException { - // CHECK THE FILE - if (!file2.exists()) { - file2.createNewFile(); - } - - // RESET TIME - long time = System.currentTimeMillis(); - - // I/O SETTING - FileOutputStream out = new FileOutputStream(file2); - FileChannel inC = in.getChannel(); - FileChannel outC = out.getChannel(); - ByteBuffer b = null; - - // CAPACITY [2GB] - Integer length = 2097152; - - // WORKSPACE - while (true) { - if (inC.position() == inC.size()) { - inC.close(); - outC.close(); - return System.currentTimeMillis() - time; - } - if ((inC.size() - inC.position()) < length) { - length = (int) (inC.size()-inC.position()); - } - else { - length = 2097152; - } - - b = ByteBuffer.allocateDirect(length); - inC.read(b); - b.flip(); - outC.write(b); - outC.force(false); - } - } - -} diff --git a/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java b/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java index ce1bbd9..9897b37 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java @@ -4,6 +4,9 @@ import java.io.*; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; +/** + * @author Unknown + */ public class EncodeUtils { /** @@ -53,7 +56,7 @@ public class EncodeUtils { */ public static void convert(File file, String fromCharsetName, String toCharsetName, FilenameFilter filter) throws Exception { if (file.isDirectory()) { - File[] fileList = null; + File[] fileList; if (filter == null) { fileList = file.listFiles(); } else { @@ -63,10 +66,8 @@ public class EncodeUtils { convert(f, fromCharsetName, toCharsetName, filter); } } else { - if (filter == null - || filter.accept(file.getParentFile(), file.getName())) { - String fileContent = getFileContentFromCharset(file, - fromCharsetName); + if (filter == null || filter.accept(file.getParentFile(), file.getName())) { + String fileContent = getFileContentFromCharset(file, fromCharsetName); saveFile2Charset(file, toCharsetName, fileContent); } } @@ -85,8 +86,7 @@ public class EncodeUtils { throw new UnsupportedCharsetException(fromCharsetName); } InputStream inputStream = new FileInputStream(file); - InputStreamReader reader = new InputStreamReader(inputStream, - fromCharsetName); + InputStreamReader reader = new InputStreamReader(inputStream, fromCharsetName); char[] chs = new char[(int) file.length()]; reader.read(chs); String str = new String(chs).trim(); @@ -110,7 +110,5 @@ public class EncodeUtils { OutputStreamWriter outWrite = new OutputStreamWriter(outputStream, toCharsetName); outWrite.write(content); outWrite.close(); - - System.out.println("[Encodeing...] 更改文件: " + file.getPath()); } } diff --git a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java index 676e092..57b5046 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java @@ -2,22 +2,32 @@ package me.skymc.taboolib.fileutils; import ch.njol.util.Closeable; import com.ilummc.tlib.util.IO; -import javafx.print.PageLayout; import me.skymc.taboolib.Main; import org.apache.commons.io.IOUtils; import org.bukkit.plugin.Plugin; import java.io.*; import java.net.HttpURLConnection; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; -import java.util.logging.Level; +import java.util.jar.JarFile; +/** + * @author sky + */ public class FileUtils { + /** + * 获取本地 IP 地址 + * + * @return {@link String} + */ public static String ip() { URL url; URLConnection con; @@ -49,10 +59,77 @@ public class FileUtils { } } + /** + * 获取插件所有类 + * + * @return {@link List} + */ + public static List getClasses(Class obj) { + List classes = new ArrayList<>(); + URL url = getCaller(obj).getProtectionDomain().getCodeSource().getLocation(); + try { + File src; + try { + src = new File(url.toURI()); + } catch (URISyntaxException e) { + src = new File(url.getPath()); + } + new JarFile(src).stream().filter(entry -> entry.getName().endsWith(".class")).forEach(entry -> { + String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6); + try { + classes.add(Class.forName(className, false, obj.getClassLoader())); + } catch (Throwable ignored) { + } + }); + } catch (Throwable ignored) { + } + return classes; + } + + /** + * 获取插件所有类 + * + * @return {@link List} + */ + public static List getClasses(Plugin plugin) { + List classes = new ArrayList<>(); + URL url = plugin.getClass().getProtectionDomain().getCodeSource().getLocation(); + try { + File src; + try { + src = new File(url.toURI()); + } catch (URISyntaxException e) { + src = new File(url.getPath()); + } + new JarFile(src).stream().filter(entry -> entry.getName().endsWith(".class")).forEach(entry -> { + String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6); + try { + classes.add(Class.forName(className, false, plugin.getClass().getClassLoader())); + } catch (Throwable ignored) { + } + }); + } catch (Throwable ignored) { + } + return classes; + } + + /** + * 获取资源文件 + * + * @param filename 文件名 + * @return {@link InputStream} + */ public static InputStream getResource(String filename) { return getResource(Main.getInst(), filename); } + /** + * 获取插件资源文件 + * + * @param plugin 插件 + * @param filename 文件名 + * @return {@link InputStream} + */ public static InputStream getResource(Plugin plugin, String filename) { try { URL url = plugin.getClass().getClassLoader().getResource(filename); @@ -68,6 +145,12 @@ public class FileUtils { } } + /** + * 写入文件 + * + * @param inputStream 输入流 + * @param file 文件 + */ public static void inputStreamToFile(InputStream inputStream, File file) { try { String text = new String(IO.readFully(inputStream), Charset.forName("utf-8")); @@ -93,15 +176,59 @@ public class FileUtils { return file; } + /** + * 检测文件并创建(目录) + * + * @param file 文件 + */ + public static void createNewFileAndPath(File file) { + if (!file.exists()) { + String filePath = file.getPath(); + int index = filePath.lastIndexOf(File.separator); + String folderPath; + File folder; + if ((index >= 0) && (!(folder = new File(filePath.substring(0, index))).exists())) { + folder.mkdirs(); + } + try { + file.createNewFile(); + } catch (IOException ignored) { + } + } + } + + /** + * 创建并获取目录 + * + * @param path 目录文件 + * @return + */ + public static File folder(File path) { + if (!path.exists()) { + path.mkdirs(); + } + return path; + } + + /** + * 创建并获取目录 + * + * @param path 目录地址 + * @return + */ + public static File folder(String path) { + return folder(new File(path)); + } + /** * 创建并获取文件 * - * @param Path 目录 + * @param path 目录 * @param filePath 地址 * @return */ - public static File file(File Path, String filePath) { - return createNewFile(new File(Path, filePath)); + public static File file(File path, String filePath) { + return createNewFile(new File(path, filePath)); } /** @@ -136,29 +263,29 @@ public class FileUtils { /** * 复制文件夹 * - * @param file1 文件1 - * @param file2 文件2 + * @param originFileName 文件1 + * @param targetFileName 文件2 */ - public static void copyAllFile(String file1, String file2) { - File _file1 = new File(file1); - File _file2 = new File(file2); - if (!_file2.exists()) { - if (!_file1.isDirectory()) { - createNewFile(_file2); + public static void copyAllFile(String originFileName, String targetFileName) { + File originFile = new File(originFileName); + File targetFile = new File(targetFileName); + if (!targetFile.exists()) { + if (!originFile.isDirectory()) { + createNewFile(targetFile); } else { - _file2.mkdirs(); + targetFile.mkdirs(); } } - if (_file1.isDirectory()) { - for (File file : Objects.requireNonNull(_file1.listFiles())) { + if (originFile.isDirectory()) { + for (File file : Objects.requireNonNull(originFile.listFiles())) { if (file.isDirectory()) { - copyAllFile(file.getAbsolutePath(), file2 + "/" + file.getName()); + copyAllFile(file.getAbsolutePath(), targetFileName + "/" + file.getName()); } else { - fileChannelCopy(file, new File(file2 + "/" + file.getName())); + fileChannelCopy(file, new File(targetFileName + "/" + file.getName())); } } } else { - fileChannelCopy(_file1, _file2); + fileChannelCopy(originFile, targetFile); } } @@ -313,6 +440,17 @@ public class FileUtils { download(downloadURL, new File(saveDir, filename)); } + @Deprecated + public static void close(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (Exception ignored) { + } + } + + @Deprecated public static byte[] read(InputStream in) { byte[] buffer = new byte[1024]; int len; @@ -326,12 +464,17 @@ public class FileUtils { return bos.toByteArray(); } - public static void close(Closeable closeable) { + // ********************************* + // + // Private Methods + // + // ********************************* + + private static Class getCaller(Class obj) { try { - if (closeable != null) { - closeable.close(); - } - } catch (Exception ignored) { + return Class.forName(Thread.currentThread().getStackTrace()[3].getClassName(), false, obj.getClassLoader()); + } catch (ClassNotFoundException ignored) { } + return null; } } diff --git a/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java b/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java deleted file mode 100644 index 08517d1..0000000 --- a/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.taboolib.fileutils; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.other.DateUtils; -import org.bukkit.plugin.Plugin; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; - -@Deprecated -public class LogUtils { - - public static void Log(String s, String s2) { - try { - File file = new File(Main.getInst().getDataFolder(), s2 + ".txt"); - if (!file.exists()) { - file.createNewFile(); - } - - FileWriter fileWritter = new FileWriter(file, true); - BufferedWriter bufferWritter = new BufferedWriter(fileWritter); - bufferWritter.write(s); - bufferWritter.newLine(); - bufferWritter.close(); - } catch (Exception e) { - Main.getInst().getLogger().warning(s2 + ":" + s); - } - } - - public static void newLog(Plugin main, String s, String s2) { - try { - File file = new File(main.getDataFolder(), s2 + ".txt"); - if (!file.exists()) { - file.createNewFile(); - } - - FileWriter fileWritter = new FileWriter(file, true); - BufferedWriter bufferWritter = new BufferedWriter(fileWritter); - bufferWritter.write("[" + DateUtils.CH_ALL.format(System.currentTimeMillis()) + "]" + s); - bufferWritter.newLine(); - bufferWritter.close(); - } catch (Exception e) { - Main.getInst().getLogger().warning(s2 + ":" + s); - } - } - -} diff --git a/src/main/java/me/skymc/taboolib/fileutils/TLogs.java b/src/main/java/me/skymc/taboolib/fileutils/TLogs.java new file mode 100644 index 0000000..49f6c89 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/fileutils/TLogs.java @@ -0,0 +1,157 @@ +package me.skymc.taboolib.fileutils; + +import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.commands.internal.BaseMainCommand; +import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.TCommand; +import me.skymc.taboolib.commands.internal.type.CommandArgument; +import me.skymc.taboolib.commands.internal.type.CommandRegister; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.FileWriter; +import java.text.SimpleDateFormat; + +/** + * @author sky + */ +@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"); + + @Override + public String getCommandTitle() { + return TLocale.asString("COMMANDS.TLOGS.COMMAND-TITLE"); + } + + @CommandRegister(priority = 0) + BaseSubCommand info = new BaseSubCommand() { + @Override + public String getLabel() { + return "info"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TLOGS.INFO.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.INFO.ARGUMENTS.0")), + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.INFO.ARGUMENTS.1")) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + info(args[0], args[1]); + if (sender instanceof Player) { + TLocale.sendTo(sender, "COMMANDS.TLOGS.INFO.SUCCESS"); + } + } + }; + + @CommandRegister(priority = 1) + BaseSubCommand error = new BaseSubCommand() { + @Override + public String getLabel() { + return "error"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TLOGS.ERROR.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.ERROR.ARGUMENTS.0")), + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.ERROR.ARGUMENTS.1")) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + info(args[0], args[1]); + if (sender instanceof Player) { + TLocale.sendTo(sender, "COMMANDS.TLOGS.ERROR.SUCCESS"); + } + } + }; + + @CommandRegister(priority = 2) + BaseSubCommand warning = new BaseSubCommand() { + @Override + public String getLabel() { + return "warning"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TLOGS.WARNING.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.WARNING.ARGUMENTS.0")), + new CommandArgument(TLocale.asString("COMMANDS.TLOGS.WARNING.ARGUMENTS.1")) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + info(args[0], args[1]); + if (sender instanceof Player) { + TLocale.sendTo(sender, "COMMANDS.TLOGS.WARNING.SUCCESS"); + } + } + }; + + public static void info(String filePath, String text) { + info(new File(!filePath.contains(".") ? filePath + ".txt" : filePath), text); + } + + public static void info(File file, String text) { + write(file, "[{0} INFO]: {1}\n", text); + } + + public static void error(String filePath, String text) { + info(new File(!filePath.contains(".") ? filePath + ".txt" : filePath), text); + } + + public static void error(File file, String text) { + write(file, "[{0} ERROR]: {1}\n", text); + } + + public static void warning(String filePath, String text) { + info(new File(!filePath.contains(".") ? filePath + ".txt" : filePath), text); + } + + public static void warning(File file, String text) { + write(file, "[{0} WARNING]: {1}\n", text); + } + + public static void write(File file, String format, String text) { + Bukkit.getScheduler().runTask(TabooLib.instance(), () -> { + FileUtils.createNewFileAndPath(file); + try (FileWriter writer = new FileWriter(file, true)) { + writer.write(Strings.replaceWithOrder(format, dateFormat.format(System.currentTimeMillis()), text)); + } catch (Exception ignored) { + } + }); + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java b/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java index 7cc3c40..67bd4da 100644 --- a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java +++ b/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java @@ -7,6 +7,9 @@ import org.bukkit.inventory.ItemStack; import java.util.Arrays; import java.util.LinkedList; +/** + * @author sky + */ public class InventoryUtil { public final static LinkedList SLOT_OF_CENTENTS = new LinkedList<>(Arrays.asList( diff --git a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java index 349eedb..2e38d61 100644 --- a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java @@ -34,6 +34,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.stream.IntStream; +/** + * @author sky + */ public class ItemUtils { private static FileConfiguration itemdir = null; @@ -418,11 +421,11 @@ public class ItemUtils { meta.setLore(asString(section.getStringList("lore"), papiPlayer)); } // 附魔 - if (section.contains("enchants")) { - for (String preEnchant : section.getConfigurationSection("enchants").getKeys(false)) { + if (section.contains("enchant")) { + for (String preEnchant : section.getConfigurationSection("enchant").getKeys(false)) { Enchantment enchant = asEnchantment(preEnchant); if (enchant != null) { - meta.addEnchant(enchant, section.getInt("enchants." + preEnchant), true); + meta.addEnchant(enchant, section.getInt("enchant." + preEnchant), true); } else { TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ENCHANTS", preEnchant); } diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java b/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java new file mode 100644 index 0000000..e727c1c --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java @@ -0,0 +1,176 @@ +package me.skymc.taboolib.inventory.builder; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.string.ArrayUtils; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.block.banner.Pattern; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.*; +import org.bukkit.potion.PotionData; +import org.bukkit.potion.PotionEffect; + +import java.util.Arrays; +import java.util.List; + +/** + * @Author sky + * @Since 2018-08-22 11:37 + * @BuilderVersion 1.0 + */ +public class ItemBuilder { + + private ItemStack itemStack; + private ItemMeta itemMeta; + + public ItemBuilder(Material material) { + this(material, 1, 0); + } + + public ItemBuilder(Material material, int amount) { + this(material, amount, 0); + } + + public ItemBuilder(Material material, int amount, int damage) { + itemStack = new ItemStack(material, amount, (short) damage); + itemMeta = itemStack.getItemMeta(); + } + + public ItemBuilder material(int id) { + itemStack.setType(Material.getMaterial(id)); + return this; + } + + public ItemBuilder material(String material) { + itemStack.setType(Material.getMaterial(material)); + return this; + } + + public ItemBuilder material(Material material) { + itemStack.setType(material); + return this; + } + + public ItemBuilder amount(int amount) { + itemStack.setAmount(amount); + return this; + } + + public ItemBuilder damage(int damage) { + itemStack.setDurability((short) damage); + return this; + } + + public ItemBuilder name(String name) { + itemMeta.setDisplayName(name); + return this; + } + + public ItemBuilder lore(List lore) { + itemMeta.setLore(lore); + return this; + } + + public ItemBuilder lore(String... lore) { + itemMeta.setLore(ArrayUtils.asList(lore)); + return this; + } + + public ItemBuilder flags(ItemFlag... flags) { + itemMeta.addItemFlags(flags); + return this; + } + + public ItemBuilder enchant(Enchantment enchantment, int level) { + return enchant(enchantment, level, false); + } + + public ItemBuilder enchant(Enchantment enchantment, int level, boolean bypass) { + itemMeta.addEnchant(enchantment, level, bypass); + return this; + } + + public ItemBuilder shiny() { + return enchant(Enchantment.LURE, 1, true).flags(ItemFlag.values()); + } + + public ItemBuilder color(Color color) { + if (itemMeta instanceof LeatherArmorMeta) { + ((LeatherArmorMeta) itemMeta).setColor(color); + } + return this; + } + + public ItemBuilder banner(Pattern... patterns) { + if (itemMeta instanceof BannerMeta) { + Arrays.stream(patterns).forEach(pattern -> ((BannerMeta) itemMeta).addPattern(pattern)); + } + return this; + } + + public ItemBuilder potionData(PotionData potionData) { + if (itemMeta instanceof PotionMeta) { + ((PotionMeta) itemMeta).setBasePotionData(potionData); + } + return this; + } + + public ItemBuilder potionColor(Color color) { + if (itemMeta instanceof PotionMeta) { + ((PotionMeta) itemMeta).setColor(color); + } + return this; + } + + public ItemBuilder potionEffect(PotionEffect potionEffect) { + if (itemMeta instanceof PotionMeta) { + ((PotionMeta) itemMeta).addCustomEffect(potionEffect, false); + } + return this; + } + + public ItemBuilder potionEffect(PotionEffect potionEffect, boolean b) { + if (itemMeta instanceof PotionMeta) { + ((PotionMeta) itemMeta).addCustomEffect(potionEffect, b); + } + return this; + } + + public ItemBuilder eggType(EntityType entityType) { + if (itemMeta instanceof SpawnEggMeta) { + ((SpawnEggMeta) itemMeta).setSpawnedType(entityType); + } + return this; + } + + public ItemBuilder unbreakable(boolean value) { + if (TabooLib.getVersionNumber() >= 12000) { + itemMeta.setUnbreakable(value); + } else { + itemMeta.spigot().setUnbreakable(value); + } + return this; + } + + public ItemBuilder colored() { + if (itemMeta.hasDisplayName()) { + itemMeta.setDisplayName(TLocale.Translate.setColored(itemMeta.getDisplayName())); + } + if (itemMeta.hasLore()) { + itemMeta.setLore(TLocale.Translate.setColored(itemMeta.getLore())); + } + return this; + } + + public ItemStack build() { + ItemStack buildItem = itemStack.clone(); + if (itemMeta != null) { + buildItem.setItemMeta(itemMeta.clone()); + } + return buildItem; + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/MenuBuilder.java b/src/main/java/me/skymc/taboolib/inventory/builder/MenuBuilder.java new file mode 100644 index 0000000..fb879d3 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/MenuBuilder.java @@ -0,0 +1,64 @@ +package me.skymc.taboolib.inventory.builder; + +import me.skymc.taboolib.inventory.builder.menu.MenuBuilderCallable; +import me.skymc.taboolib.inventory.builder.menu.MenuBuilderHolder; +import me.skymc.taboolib.inventory.builder.menu.MenuBuilderItem; +import org.bukkit.Bukkit; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * @Author sky + * @Since 2018-08-22 13:40 + * @BuilderVersion 1.0 + */ +public class MenuBuilder { + + private boolean lock; + private String name; + private int rows = 9; + + private HashMap items = new HashMap<>(); + + public MenuBuilder() { + this(true); + } + + public MenuBuilder(boolean lock) { + this.lock = lock; + } + + public MenuBuilder lock(boolean lock) { + this.lock = lock; + return this; + } + + public MenuBuilder name(String name) { + this.name = name; + return this; + } + + public MenuBuilder rows(int rows) { + this.rows = rows * 9; + return this; + } + + public MenuBuilder item(ItemStack itemStack, int... slots) { + Arrays.stream(slots).forEach(slot -> items.put(slot, new MenuBuilderItem(itemStack, null))); + return this; + } + + public MenuBuilder item(ItemStack itemStack, MenuBuilderCallable callable, int... slots) { + Arrays.stream(slots).forEach(slot -> items.put(slot, new MenuBuilderItem(itemStack, callable))); + return this; + } + + public Inventory build() { + Inventory inventory = Bukkit.createInventory(new MenuBuilderHolder(lock, items), rows, name); + items.forEach((key, value) -> inventory.setItem(key, value.getItemStack())); + return inventory; + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderCallable.java b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderCallable.java new file mode 100644 index 0000000..8a0beb6 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderCallable.java @@ -0,0 +1,10 @@ +package me.skymc.taboolib.inventory.builder.menu; + +/** + * @Author sky + * @Since 2018-08-22 15:41 + */ +public interface MenuBuilderCallable { + + void call(MenuBuilderEvent event); +} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderEvent.java b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderEvent.java new file mode 100644 index 0000000..692896c --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderEvent.java @@ -0,0 +1,48 @@ +package me.skymc.taboolib.inventory.builder.menu; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @Author sky + * @Since 2018-08-22 15:44 + */ +public class MenuBuilderEvent { + + private final InventoryClickEvent parentEvent; + private final Player player; + private final ItemStack clickItem; + private final int clickSlot; + + public MenuBuilderEvent(InventoryClickEvent parentEvent, Player player, ItemStack clickItem, int clickSlot) { + this.parentEvent = parentEvent; + this.player = player; + this.clickItem = clickItem; + this.clickSlot = clickSlot; + } + + public InventoryClickEvent getParentEvent() { + return parentEvent; + } + + public Player getPlayer() { + return player; + } + + public ItemStack getClickItem() { + return clickItem; + } + + public int getClickSlot() { + return clickSlot; + } + + public void setCancelled(boolean canceled) { + parentEvent.setCancelled(canceled); + } + + public boolean isCancelled() { + return parentEvent.isCancelled(); + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderHolder.java b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderHolder.java new file mode 100644 index 0000000..6c663bb --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderHolder.java @@ -0,0 +1,40 @@ +package me.skymc.taboolib.inventory.builder.menu; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +import java.util.HashMap; + +/** + * @author sky + * @Since 2018-08-22 13:40 + */ +public class MenuBuilderHolder implements InventoryHolder { + + private final boolean lock; + private final HashMap items; + + public MenuBuilderHolder(boolean lock, HashMap items) { + this.lock = lock; + this.items = items; + } + + @Override + public Inventory getInventory() { + return null; + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public boolean isLock() { + return lock; + } + + public HashMap getItems() { + return items; + } +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderItem.java b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderItem.java new file mode 100644 index 0000000..17e0cce --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderItem.java @@ -0,0 +1,26 @@ +package me.skymc.taboolib.inventory.builder.menu; + +import org.bukkit.inventory.ItemStack; + +/** + * @Author sky + * @Since 2018-08-22 15:36 + */ +public class MenuBuilderItem { + + private final ItemStack itemStack; + private final MenuBuilderCallable callable; + + public MenuBuilderItem(ItemStack itemStack, MenuBuilderCallable callable) { + this.itemStack = itemStack; + this.callable = callable; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public MenuBuilderCallable getCallable() { + return callable; + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderListener.java b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderListener.java new file mode 100644 index 0000000..54cb73e --- /dev/null +++ b/src/main/java/me/skymc/taboolib/inventory/builder/menu/MenuBuilderListener.java @@ -0,0 +1,36 @@ +package me.skymc.taboolib.inventory.builder.menu; + +import me.skymc.taboolib.listener.TListener; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; + +import java.util.Optional; + +/** + * @Author sky + * @Since 2018-08-22 13:40 + */ +@TListener +public class MenuBuilderListener implements Listener { + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onClick(InventoryClickEvent e) { + if (!(e.getInventory().getHolder() instanceof MenuBuilderHolder)) { + return; + } + MenuBuilderHolder holder = (MenuBuilderHolder) e.getInventory().getHolder(); + if (holder.isLock() || e.getAction() == InventoryAction.COLLECT_TO_CURSOR) { + e.setCancelled(true); + } + Optional.ofNullable(holder.getItems().get(e.getRawSlot())).ifPresent(item -> { + if (item.getCallable() != null) { + item.getCallable().call(new MenuBuilderEvent(e, (Player) e.getWhoClicked(), e.getCurrentItem(), e.getRawSlot())); + } + }); + } + +} diff --git a/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java b/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java deleted file mode 100644 index e551099..0000000 --- a/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java +++ /dev/null @@ -1,76 +0,0 @@ -package me.skymc.taboolib.javascript; - -import me.skymc.taboolib.Main; - -import javax.script.Invocable; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; - -@Deprecated -public class JavaScriptUtils { - - private static ScriptEngineManager manager = new ScriptEngineManager(); - - public static ScriptEngineManager getScriptManager() { - return manager; - } - - public static void invokeJavaScript(File jsFile, String method, Object... o) { - ScriptEngine engine = manager.getEngineByName("javascript"); - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(Main.class.getClassLoader()); - - FileReader reader = new FileReader(jsFile); - engine.eval(reader); - - // TODO run - - Thread.currentThread().setContextClassLoader(classLoader); - } catch (Exception e) { - // TODO: handle exception - } - } - - @Deprecated - public static Object JavaScriptInterface(String jsFile, Object... o) { - - ScriptEngine engine = manager.getEngineByName("javascript"); - try { - FileReader reader = new FileReader(jsFile); - engine.eval(reader); - - if (engine instanceof Invocable) { - return ((Invocable) engine).invokeFunction("main", o); - } - - reader.close(); - } catch (NoSuchMethodException | IOException | ScriptException e) { - e.printStackTrace(); - } - return null; - } - - @Deprecated - public static void JavaScriptExecute(String jsFile, Object... o) { - - ScriptEngine engine = manager.getEngineByName("javascript"); - try { - FileReader reader = new FileReader(jsFile); - engine.eval(reader); - - if (engine instanceof Invocable) { - ((Invocable) engine).invokeFunction("main", o); - } - - reader.close(); - } catch (NoSuchMethodException | IOException | ScriptException e) { - e.printStackTrace(); - } - } - -} diff --git a/src/main/java/me/skymc/taboolib/javascript/ScriptHandler.java b/src/main/java/me/skymc/taboolib/javascript/ScriptHandler.java new file mode 100644 index 0000000..694bb7b --- /dev/null +++ b/src/main/java/me/skymc/taboolib/javascript/ScriptHandler.java @@ -0,0 +1,55 @@ +package me.skymc.taboolib.javascript; + +import com.ilummc.tlib.logger.TLogger; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import org.bukkit.configuration.file.FileConfiguration; + +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.util.Objects; + +/** + * @Author sky + * @Since 2018-06-02 22:48 + */ +public class ScriptHandler { + + private static ScriptEngine scriptEngine; + private static ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); + private static FileConfiguration scriptsFile; + + public static void inst() { + try { + NashornScriptEngineFactory factory = (NashornScriptEngineFactory) scriptEngineManager.getEngineFactories().stream().filter(factories -> "Oracle Nashorn".equalsIgnoreCase(factories.getEngineName())).findFirst().orElse(null); + scriptEngine = Objects.requireNonNull(factory).getScriptEngine("-doe", "--global-per-engine"); + } catch (Exception ignored) { + scriptEngine = scriptEngineManager.getEngineByName("JavaScript"); + } + } + + public static CompiledScript compile(String script) { + try { + Compilable compilable = (Compilable) scriptEngine; + return compilable.compile(script); + } catch (Exception e) { + TLogger.getGlobalLogger().info("§4JavaScript §c" + script + "§4 Compile Failed: §c" + e.toString()); + return null; + } + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static ScriptEngine getScriptEngine() { + return scriptEngine; + } + + public static ScriptEngineManager getScriptEngineManager() { + return scriptEngineManager; + } +} diff --git a/src/main/java/me/skymc/taboolib/javashell/JavaShell.java b/src/main/java/me/skymc/taboolib/javashell/JavaShell.java deleted file mode 100644 index 51e794f..0000000 --- a/src/main/java/me/skymc/taboolib/javashell/JavaShell.java +++ /dev/null @@ -1,219 +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; - -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> 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> getShells() { - return shells; - } - - public static void setShells(HashMap> 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)); - } -} diff --git a/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java b/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java deleted file mode 100644 index 97dafac..0000000 --- a/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java +++ /dev/null @@ -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 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 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()); - } - } - -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerNetWork.java b/src/main/java/me/skymc/taboolib/listener/ListenerNetWork.java index 619c842..76739df 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerNetWork.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerNetWork.java @@ -11,17 +11,18 @@ import pw.yumc.Yum.events.PluginNetworkEvent; * @author sky * @since 2018年2月23日 下午11:10:03 */ +@TListener(depend = "YUM") public class ListenerNetWork implements Listener { - - public static final String GG = "本监听只是为了防止本插件的更新检测被 YUM 插件阻止,别无它用。"; - - @EventHandler (priority = EventPriority.HIGHEST) - public void onNetWork(PluginNetworkEvent e) { - if (e.getPlugin() != null && e.getPlugin().equals(Main.getInst())) { - // 取消阻止 - e.setCancelled(false); - // 后台提示 - MsgUtils.warn("已取消 &4YUM &c对本插件网络访问的阻止!"); - } - } + + public static final String GG = "本监听只是为了防止本插件的更新检测被 YUM 插件阻止,别无它用。"; + + @EventHandler(priority = EventPriority.HIGHEST) + public void onNetWork(PluginNetworkEvent e) { + if (e.getPlugin() != null && e.getPlugin().equals(Main.getInst())) { + // 取消阻止 + e.setCancelled(false); + // 后台提示 + MsgUtils.warn("已取消 &4YUM &c对本插件网络访问的阻止!"); + } + } } diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java index 7b07bf3..e6da994 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java @@ -13,6 +13,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.server.ServerCommandEvent; +@TListener public class ListenerPlayerCommand implements Listener { @EventHandler diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJoinAndQuit.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJoinAndQuit.java index f166520..e2488a9 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJoinAndQuit.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJoinAndQuit.java @@ -13,6 +13,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +@TListener public class ListenerPlayerJoinAndQuit implements Listener { @EventHandler diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java index 659efd7..ad2217c 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java @@ -14,6 +14,7 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; +@TListener public class ListenerPlayerJump implements Listener { public HashMap cooldown = new HashMap<>(); diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java b/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java index 5c9d258..c1b101b 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java @@ -14,6 +14,7 @@ import org.bukkit.scheduler.BukkitRunnable; import java.util.ArrayList; import java.util.List; +@TListener public class ListenerPluginDisable implements Listener { @EventHandler diff --git a/src/main/java/me/skymc/taboolib/listener/TListener.java b/src/main/java/me/skymc/taboolib/listener/TListener.java new file mode 100644 index 0000000..7d172ae --- /dev/null +++ b/src/main/java/me/skymc/taboolib/listener/TListener.java @@ -0,0 +1,44 @@ +package me.skymc.taboolib.listener; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Author sky + * @Since 2018-08-22 13:41 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface TListener { + + /** + * 注册时执行方法 + * + * @return 方法名 + */ + String register() default ""; + + /** + * 注销时执行方法 + * + * @return 方法名 + */ + String cancel() default ""; + + /** + * 注册时判断条件 + * + * @return 方法名 + */ + String condition() default ""; + + /** + * 注册前判断依赖插件 + * + * @return 依赖插件 + */ + String[] depend() default ""; + +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/listener/TListenerCommand.java b/src/main/java/me/skymc/taboolib/listener/TListenerCommand.java new file mode 100644 index 0000000..32317bc --- /dev/null +++ b/src/main/java/me/skymc/taboolib/listener/TListenerCommand.java @@ -0,0 +1,9 @@ +package me.skymc.taboolib.listener; + +/** + * @Author sky + * @Since 2018-08-25 10:16 + */ +public class TListenerCommand { + +} diff --git a/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java b/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java new file mode 100644 index 0000000..100e8ba --- /dev/null +++ b/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java @@ -0,0 +1,183 @@ +package me.skymc.taboolib.listener; + +import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.fileutils.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +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-08-22 13:48 + */ +@TListener +public class TListenerHandler implements Listener { + + private static HashMap> listeners = new HashMap<>(); + + /** + * 初始化所有插件的所有监听器 + */ + public static void setupListeners() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) { + try { + setupListener(plugin); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + * 初始化插件的所有监听器 + * 该操作会执行无参构造方法 + * + * @param plugin 插件 + */ + public static void setupListener(Plugin plugin) { + List 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; + } + } + // 实例化监听器 + 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(); + } + } + } + } + + /** + * 注册所有插件的所有监听器 + */ + public static void registerListeners() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + try { + registerListener(plugin); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 注册插件的所有监听器 + * 该操作会执行 TListener 注解中的 register() 对应方法 + * + * @param plugin 插件 + */ + public static void registerListener(Plugin plugin) { + Optional.ofNullable(listeners.get(plugin.getName())).ifPresent(listeners -> { + for (Listener listener : listeners) { + TListener tListener = listener.getClass().getAnnotation(TListener.class); + // 检查注册条件 + if (!Strings.isBlank(tListener.condition())) { + try { + Method method = listener.getClass().getDeclaredMethod(tListener.condition()); + method.setAccessible(true); + if (!(boolean) method.invoke(listener)) { + continue; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + // 执行注册方法 + if (!Strings.isBlank(tListener.register())) { + try { + Method method = listener.getClass().getDeclaredMethod(tListener.register()); + method.setAccessible(true); + method.invoke(listener); + } catch (Exception e) { + e.printStackTrace(); + } + } + // 注册监听 + Bukkit.getPluginManager().registerEvents(listener, plugin); + } + }); + } + + /** + * 注销所有插件的所有监听器 + */ + public static void cancelListeners() { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + try { + cancelListener(plugin); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 注销插件的所有监听器 + * 该操作会执行 TListener 注解中的 cancel() 对应方法 + * + * @param plugin 插件 + */ + public static void cancelListener(Plugin plugin) { + Optional.ofNullable(listeners.remove(plugin.getName())).ifPresent(listeners -> { + for (Listener listener : listeners) { + HandlerList.unregisterAll(listener); + TListener tListener = listener.getClass().getAnnotation(TListener.class); + if (!Strings.isBlank(tListener.cancel())) { + try { + Method method = listener.getClass().getDeclaredMethod(tListener.cancel()); + method.setAccessible(true); + method.invoke(listener); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + + @EventHandler + public void onPluginEnable(PluginEnableEvent e) { + try { + setupListener(e.getPlugin()); + registerListener(e.getPlugin()); + } catch (Exception ignored) { + } + } + + @EventHandler + public void onPluginDisable(PluginDisableEvent e) { + try { + cancelListener(e.getPlugin()); + } catch (Exception ignored) { + } + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static HashMap> getListeners() { + return listeners; + } +} diff --git a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java b/src/main/java/me/skymc/taboolib/message/ChatCatcher.java index aa7f6a2..c0fd373 100644 --- a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java +++ b/src/main/java/me/skymc/taboolib/message/ChatCatcher.java @@ -1,5 +1,6 @@ package me.skymc.taboolib.message; +import me.skymc.taboolib.listener.TListener; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -9,6 +10,7 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; import java.util.LinkedList; +@TListener public class ChatCatcher implements Listener { private static HashMap> playerdata = new HashMap<>(); diff --git a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java index 3a00da6..4ff774d 100644 --- a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java +++ b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java @@ -11,6 +11,7 @@ import java.util.*; /** * @author sky */ +@Deprecated public class MySQLConnection { private String url; diff --git a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java b/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java index 10fd367..3d5ba16 100644 --- a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java +++ b/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java @@ -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)); } } diff --git a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java b/src/main/java/me/skymc/taboolib/player/PlayerUtils.java index 3fd1b95..cb2ed91 100644 --- a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java +++ b/src/main/java/me/skymc/taboolib/player/PlayerUtils.java @@ -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) { + } + } } diff --git a/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java b/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java index a5de455..d5e0abb 100644 --- a/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java +++ b/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java @@ -5,6 +5,7 @@ import me.skymc.taboolib.Main; import me.skymc.taboolib.database.PlayerDataManager; import me.skymc.taboolib.exception.PlayerOfflineException; import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.listener.TListener; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; @@ -19,6 +20,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; +@TListener public class DataUtils implements Listener { public static final ConcurrentHashMap> CACHE_DATA_PLUGIN = new ConcurrentHashMap<>(); diff --git a/src/main/java/me/skymc/taboolib/scoreboard/SimpleScoreboard.java b/src/main/java/me/skymc/taboolib/scoreboard/SimpleScoreboard.java new file mode 100644 index 0000000..45344f5 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/scoreboard/SimpleScoreboard.java @@ -0,0 +1,216 @@ +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; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; + +import java.lang.reflect.Constructor; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class SimpleScoreboard { + + private static Map cache = new HashMap<>(); + + private Scoreboard scoreboard; + private String title; + private Map scores; + private Objective obj; + private List teams; + private List removed; + private Set updated; + + public SimpleScoreboard(String title) { + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + this.title = ChatColor.translateAlternateColorCodes('&', title); + this.scores = new ConcurrentHashMap<>(); + this.teams = Collections.synchronizedList(Lists.newArrayList()); + this.removed = Lists.newArrayList(); + this.updated = Collections.synchronizedSet(new HashSet<>()); + } + + 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); + } + + public boolean remove(Integer score, String text) { + return remove(score, text, true); + } + + public boolean remove(Integer score, String n, boolean b) { + String toRemove = get(score, n); + if (toRemove == null) { + return false; + } + scores.remove(toRemove); + if (b) { + removed.add(score); + } + return true; + } + + public String get(int score, String n) { + String str = null; + for (Map.Entry entry : scores.entrySet()) { + if (entry.getValue().equals(score) && !entry.getKey().equals(n)) { + str = entry.getKey(); + } + } + return str; + } + + private Map.Entry createTeam(String text, int pos) { + Team team; + ChatColor color = ChatColor.values()[pos]; + OfflinePlayer result; + 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); + return new AbstractMap.SimpleEntry<>(team, result); + } + + private void applyText(Team team, String text, OfflinePlayer result) { + Iterator iterator = Splitter.fixedLength(16).split(text).iterator(); + String prefix = iterator.next(); + team.setPrefix(prefix); + 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) { + prefixColor = ""; + } + 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); + } + } + + public void update() { + 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.forEach((remove) -> { + for (String s : scoreboard.getEntries()) { + Score score = obj.getScore(s); + if (score == null) { + continue; + } + if (score.getScore() != remove) { + continue; + } + scoreboard.resetScores(s); + } + }); + removed.clear(); + int index = scores.size(); + for (Map.Entry text : scores.entrySet()) { + Team t = scoreboard.getTeam(ChatColor.values()[text.getValue()].toString()); + Map.Entry team; + if (!updated.contains(text.getKey())) { + continue; + } + 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) { + obj.setDisplayName(this.title); + } + } + + public void reset() { + teams.forEach(Team::unregister); + teams.clear(); + scores.clear(); + } + + public Scoreboard getScoreboard() { + return scoreboard; + } + + public void send(Player... players) { + Arrays.stream(players).forEach(p -> p.setScoreboard(scoreboard)); + } + + private final UUID invalidUserUUID = UUID.nameUUIDFromBytes("InvalidUsername".getBytes(Charsets.UTF_8)); + private Class gameProfileClass; + private Constructor gameProfileConstructor; + private Constructor craftOfflinePlayerConstructor; + + @SuppressWarnings("deprecation") + private OfflinePlayer getOfflinePlayerSkipLookup(String name) { + try { + if (gameProfileConstructor == null) { + try { // 1.7 + gameProfileClass = Class.forName("net.minecraft.util.com.mojang.authlib.GameProfile"); + } catch (ClassNotFoundException e) { // 1.8 + gameProfileClass = Class.forName("com.mojang.authlib.GameProfile"); + } + gameProfileConstructor = gameProfileClass.getDeclaredConstructor(UUID.class, String.class); + gameProfileConstructor.setAccessible(true); + } + if (craftOfflinePlayerConstructor == null) { + Class serverClass = Bukkit.getServer().getClass(); + 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) { + return Bukkit.getOfflinePlayer(name); + } + } +} diff --git a/src/main/java/me/skymc/taboolib/sign/SignUtils.java b/src/main/java/me/skymc/taboolib/sign/SignUtils.java index 822bb00..0194c5f 100644 --- a/src/main/java/me/skymc/taboolib/sign/SignUtils.java +++ b/src/main/java/me/skymc/taboolib/sign/SignUtils.java @@ -1,6 +1,8 @@ package me.skymc.taboolib.sign; import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.listener.TListener; import me.skymc.taboolib.location.LocationUtils; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.methods.MethodsUtils; @@ -22,10 +24,15 @@ import java.lang.reflect.InvocationTargetException; import java.util.HashMap; @Deprecated +@TListener(condition = "check") public class SignUtils implements Listener { public static HashMap signs = new HashMap<>(); + public static boolean check() { + return TabooLib.getVerint() > 10700; + } + public static void openSign(Player p, Block b) { if (!(b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST))) { diff --git a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java b/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java index 9b88a78..909e87d 100644 --- a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java +++ b/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java @@ -12,24 +12,14 @@ import org.bukkit.inventory.ItemStack; * @since 2018-02-28 15:40:55 */ public class SkriptHandler { - - private static SkriptHandler inst = null; - - private SkriptHandler() { - if (Bukkit.getPluginManager().getPlugin("Skript") != null) { - Skript.registerExpression(ExpressionItemCache.class, ItemStack.class, ExpressionType.SIMPLE, "taboolib itemcache %string%"); - Skript.registerExpression(ExpressionTabooCodeItem.class, ItemStack.class, ExpressionType.SIMPLE, "taboocode itemcache %string%"); - } - } - - public static SkriptHandler getInst() { - if (inst == null) { - synchronized (SkriptHandler.class) { - if (inst == null) { - inst = new SkriptHandler(); - } - } - } - return inst; - } + + public static void register() { + if (Bukkit.getPluginManager().getPlugin("Skript") != null) { + try { + Skript.registerExpression(ExpressionItemCache.class, ItemStack.class, ExpressionType.SIMPLE, "taboolib itemcache %string%"); + Skript.registerExpression(ExpressionTabooCodeItem.class, ItemStack.class, ExpressionType.SIMPLE, "taboocode itemcache %string%"); + } catch (Exception ignored) { + } + } + } } diff --git a/src/main/java/me/skymc/taboolib/socket/TabooLibClient.java b/src/main/java/me/skymc/taboolib/socket/TabooLibClient.java new file mode 100644 index 0000000..d6a9a66 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/TabooLibClient.java @@ -0,0 +1,121 @@ +package me.skymc.taboolib.socket; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketSerializer; +import org.bukkit.Bukkit; + +import java.io.*; +import java.net.Socket; +import java.net.SocketException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @Author sky + * @Since 2018-08-22 22:27 + */ +public class TabooLibClient { + + private static Socket socket; + private static BufferedReader reader; + private static PrintWriter writer; + private static ExecutorService executorService = Executors.newCachedThreadPool(); + private static Packet packet; + private static boolean notify = false; + private static long latestResponse = System.currentTimeMillis(); + + public static void init() { + if (TabooLibSettings.load()) { + connect(); + Bukkit.getScheduler().runTaskTimerAsynchronously(TabooLib.instance(), TabooLibClient::reconnect, 0, 100); + } else { + TLocale.sendToConsole("COMMUNICATION.FAILED-LOAD-SETTINGS", TabooLibSettings.getThrowable().toString()); + } + } + + public static void sendPacket(Packet packet) { + writer.println(PacketSerializer.serialize(packet)); + } + + public static void reconnect() { + if (System.currentTimeMillis() - latestResponse > NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.timeout"))) { + connect(); + } + } + + public static void connect() { + try { + if (socket != null) { + socket.close(); + } + } catch (Exception ignored) { + } + + try { + socket = new Socket("localhost", NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.port"))); + reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), TabooLibSettings.getCharset())); + writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), TabooLibSettings.getCharset()), true); + notify = false; + TLocale.sendToConsole("COMMUNICATION.SUCCESS-CONNECTED"); + } catch (SocketException e) { + /* + 防止未启用终端服务器导致重复提示连接失败信息 + */ + if (!notify) { + notify = true; + TLocale.sendToConsole("COMMUNICATION.FAILED-CONNECT-SERVER"); + } + return; + } catch (IOException e) { + TLocale.sendToConsole("COMMUNICATION.FAILED-CONNECT-CLIENT", e.getMessage()); + return; + } + + executorService.execute(() -> { + try { + while (!socket.isClosed() && (packet = PacketSerializer.unSerialize(reader.readLine())) != null) { + packet.readOnClient(); + } + } catch (IOException e) { + TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.getMessage()); + } + }); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static Socket getSocket() { + return socket; + } + + public static BufferedReader getReader() { + return reader; + } + + public static PrintWriter getWriter() { + return writer; + } + + public static ExecutorService getExecutorService() { + return executorService; + } + + public static Packet getLatestPacket() { + return packet; + } + + public static long getLatestResponse() { + return latestResponse; + } + + public static void setLatestResponse(long latestResponse) { + TabooLibClient.latestResponse = latestResponse; + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java b/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java new file mode 100644 index 0000000..57a30ef --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java @@ -0,0 +1,118 @@ +package me.skymc.taboolib.socket; + +import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketSerializer; +import me.skymc.taboolib.socket.packet.impl.PacketHeartbeat; +import me.skymc.taboolib.socket.packet.impl.PacketQuit; +import me.skymc.taboolib.socket.server.ClientConnection; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * 研究了一个小时 log4j 愣是没整明白,不搞那些高端日志工具了 + * + * @Author sky + * @Since 2018-08-22 20:45 + */ +public class TabooLibServer { + + private static SimpleDateFormat infoFormat = new SimpleDateFormat("HH:mm:ss"); + private static ServerSocket server = null; + private static ExecutorService executorService = Executors.newCachedThreadPool(); + private static ConcurrentHashMap client = new ConcurrentHashMap<>(); + + public static void main(String[] args) { + println("TabooLib Communication Area Starting..."); + + if (!TabooLibSettings.load()) { + println("Settings loading failed: " + TabooLibSettings.getThrowable().toString()); + return; + } + + try { + server = new ServerSocket(NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.port"))); + println("Starting TabooLib server on " + server.getInetAddress().getHostName() + ":" + server.getLocalPort()); + } catch (IOException e) { + println("Server starting failed: " + e.toString()); + return; + } + + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { + /* + 向所有已连接的客户端发送心跳包 + */ + sendPacket(new PacketHeartbeat(0)); + /* + 检测无效的客户端连接,如果超过 5000 毫秒没有收到客户端的回应(上一次心跳包的回应)则注销链接 + */ + client.entrySet().stream().filter(connection -> connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket); + }, 0, 1, TimeUnit.SECONDS); + + while (true) { + try { + Socket socket = server.accept(); + ClientConnection connection = new ClientConnection(socket); + client.put(socket.getPort(), connection); + executorService.execute(connection); + println("Client accepted: " + socket.getPort() + " online: " + client.size()); + } catch (Exception e) { + println("Client accept failed: " + e.toString()); + } + } + } + + public static void sendPacket(Packet packet) { + sendPacket(PacketSerializer.serialize(packet)); + } + + public static void sendPacket(String origin) { + println("Packet sending: " + origin + ", online: " + client.size()); + // 在服务端尝试解析动作并运行 + Optional.ofNullable(PacketSerializer.unSerialize(origin)).ifPresent(Packet::readOnServer); + // 将动作发送至所有客户端 + for (ClientConnection connection : TabooLibServer.getClient().values()) { + try { + connection.getWriter().println(origin); + } catch (Exception e) { + TabooLibServer.println("Packet sending failed: " + e.toString()); + } + } + } + + public static void println(Object obj) { + System.out.println("[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj); + } + + + public static Optional> getConnection(int port) { + return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst(); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static ServerSocket getServer() { + return server; + } + + public static ConcurrentHashMap getClient() { + return client; + } + + public static ExecutorService getExecutorService() { + return executorService; + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/TabooLibSettings.java b/src/main/java/me/skymc/taboolib/socket/TabooLibSettings.java new file mode 100644 index 0000000..fe39e1b --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/TabooLibSettings.java @@ -0,0 +1,62 @@ +package me.skymc.taboolib.socket; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.util.Properties; + +/** + * @Author sky + * @Since 2018-08-22 23:55 + */ +public class TabooLibSettings { + + private static Charset charset = Charset.forName("UTF-8"); + private static Properties settings = new Properties(); + private static Throwable throwable; + + public static boolean load() { + try { + settings.load(getSettingsInputStream()); + return true; + } catch (Throwable e) { + throwable = e; + return false; + } + } + + public static InputStream getSettingsInputStream() { + try { + URL url = TabooLibServer.class.getClassLoader().getResource("settings.properties"); + if (url == null) { + return null; + } else { + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } + } catch (IOException ignored) { + return null; + } + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static Properties getSettings() { + return settings; + } + + public static Throwable getThrowable() { + return throwable; + } + + public static Charset getCharset() { + return charset; + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/Packet.java b/src/main/java/me/skymc/taboolib/socket/packet/Packet.java new file mode 100644 index 0000000..dcdfcf4 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/Packet.java @@ -0,0 +1,45 @@ +package me.skymc.taboolib.socket.packet; + +import com.google.gson.JsonObject; + +import java.util.UUID; + +/** + * @Author sky + * @Since 2018-08-22 23:01 + */ +public abstract class Packet { + + private final int port; + private final String uid; + + public Packet(int port) { + this.port = port; + this.uid = UUID.randomUUID().toString(); + } + + public int getPort() { + return port; + } + + public String getUid() { + return uid; + } + + public void readOnServer() { + + } + + public void readOnClient() { + + } + + public void serialize(JsonObject json) { + + } + + public void unSerialize(JsonObject json) { + + } + +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java new file mode 100644 index 0000000..0f733fd --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java @@ -0,0 +1,50 @@ +package me.skymc.taboolib.socket.packet; + +import com.google.gson.JsonObject; +import me.skymc.taboolib.fileutils.FileUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @Author sky + * @Since 2018-08-22 23:07 + */ +public class PacketParser { + + private List> packets = new ArrayList<>(); + + public PacketParser() { + FileUtils.getClasses(PacketParser.class).stream().filter(clazz -> clazz.isAnnotationPresent(PacketType.class)).forEach(clazz -> packets.add(clazz)); + } + + public Packet parser(JsonObject json) { + if (!json.has("packet")) { + return null; + } + String packetType = json.get("packet").getAsString(); + Optional> packetFind = packets.stream().filter(packet -> packet.getAnnotation(PacketType.class).name().equals(packetType)).findFirst(); + if (!packetFind.isPresent()) { + return null; + } + try { + Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt()); + packetObject.unSerialize(json); + return packetObject; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public List> getPackets() { + return packets; + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java new file mode 100644 index 0000000..2ec3b94 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java @@ -0,0 +1,44 @@ +package me.skymc.taboolib.socket.packet; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import me.skymc.taboolib.socket.packet.impl.PacketEmpty; + +/** + * @Author sky + * @Since 2018-08-22 23:32 + */ +public class PacketSerializer { + + private static PacketParser parser = new PacketParser(); + + public static String serialize(Packet packet) { + JsonObject json = new JsonObject(); + json.addProperty("uid", packet.getUid()); + json.addProperty("port", packet.getPort()); + json.addProperty("packet", packet.getClass().getAnnotation(PacketType.class).name()); + packet.serialize(json); + return json.toString(); + } + + public static Packet unSerialize(String origin) { + Packet packet = null; + try { + packet = parser.parser((JsonObject) new JsonParser().parse(origin)); + } catch (JsonSyntaxException e) { + e.printStackTrace(); + } + return packet == null ? new PacketEmpty(0) : packet; + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public static PacketParser getParser() { + return parser; + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketType.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketType.java new file mode 100644 index 0000000..10ead35 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketType.java @@ -0,0 +1,18 @@ +package me.skymc.taboolib.socket.packet; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Author sky + * @Since 2018-08-22 23:09 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface PacketType { + + String name(); + +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketAlive.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketAlive.java new file mode 100644 index 0000000..ebd7c3a --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketAlive.java @@ -0,0 +1,26 @@ +package me.skymc.taboolib.socket.packet.impl; + +import me.skymc.taboolib.socket.TabooLibServer; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:01 + */ +@PacketType(name = "alive") +public class PacketAlive extends Packet { + + public PacketAlive(int port) { + super(port); + } + + @Override + public void readOnServer() { + TabooLibServer.getConnection(getPort()).ifPresent(connect -> connect.getValue().setLatestResponse(System.currentTimeMillis())); + } + + @Override + public void readOnClient() { + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketEmpty.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketEmpty.java new file mode 100644 index 0000000..dfdce56 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketEmpty.java @@ -0,0 +1,24 @@ +package me.skymc.taboolib.socket.packet.impl; + +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:01 + */ +@PacketType(name = "empty") +public class PacketEmpty extends Packet { + + public PacketEmpty(int port) { + super(port); + } + + @Override + public void readOnServer() { + } + + @Override + public void readOnClient() { + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketHeartbeat.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketHeartbeat.java new file mode 100644 index 0000000..346e26f --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketHeartbeat.java @@ -0,0 +1,29 @@ +package me.skymc.taboolib.socket.packet.impl; + +import me.skymc.taboolib.socket.TabooLibClient; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:01 + */ +@PacketType(name = "heartbeat") +public class PacketHeartbeat extends Packet { + + public PacketHeartbeat(int port) { + super(port); + } + + @Override + public void readOnServer() { + } + + @Override + public void readOnClient() { + // 更新响应时间 + TabooLibClient.setLatestResponse(System.currentTimeMillis()); + // 回应服务端 + TabooLibClient.sendPacket(new PacketAlive(TabooLibClient.getSocket().getLocalPort())); + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketJoin.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketJoin.java new file mode 100644 index 0000000..d20ef1a --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketJoin.java @@ -0,0 +1,28 @@ +package me.skymc.taboolib.socket.packet.impl; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.socket.TabooLibServer; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:38 + */ +@PacketType(name = "join") +public class PacketJoin extends Packet { + + public PacketJoin(int port) { + super(port); + } + + @Override + public void readOnServer() { + TabooLibServer.println("Client " + getPort() + " joined Communication Area."); + } + + @Override + public void readOnClient() { + TLocale.sendToConsole("COMMUNICATION.CLIENT-JOINED", String.valueOf(getPort())); + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java new file mode 100644 index 0000000..a2f8927 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java @@ -0,0 +1,46 @@ +package me.skymc.taboolib.socket.packet.impl; + +import com.google.gson.JsonObject; +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.socket.TabooLibServer; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:01 + */ +@PacketType(name = "message") +public class PacketMessage extends Packet { + + private String message; + + public PacketMessage(int port) { + this(port, "none"); + } + + public PacketMessage(int port, String message) { + super(port); + this.message = message; + } + + @Override + public void readOnServer() { + TabooLibServer.println(message); + } + + @Override + public void readOnClient() { + TLocale.sendToConsole("COMMUNICATION.PACKET-MESSAGE", String.valueOf(getPort()), message); + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("message", message); + } + + @Override + public void unSerialize(JsonObject json) { + message = json.get("message").getAsString(); + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java new file mode 100644 index 0000000..cdb740c --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java @@ -0,0 +1,56 @@ +package me.skymc.taboolib.socket.packet.impl; + +import com.google.gson.JsonObject; +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.socket.TabooLibServer; +import me.skymc.taboolib.socket.packet.Packet; +import me.skymc.taboolib.socket.packet.PacketType; + +/** + * @Author sky + * @Since 2018-08-22 23:38 + */ +@PacketType(name = "quit") +public class PacketQuit extends Packet { + + private String message; + + public PacketQuit(int port) { + this(port, "connect closed."); + } + + public PacketQuit(int port, String message) { + super(port); + this.message = message; + } + + @Override + public void readOnServer() { + TabooLibServer.getConnection(getPort()).ifPresent(connection -> { + // 注销连接 + TabooLibServer.getClient().remove(connection.getKey()); + // 关闭连接 + try { + connection.getValue().getSocket().close(); + } catch (Exception ignored) { + } + // 提示信息 + TabooLibServer.println("Client " + getPort() + " leaved Communication Area: " + message); + }); + } + + @Override + public void readOnClient() { + TLocale.sendToConsole("COMMUNICATION.CLIENT-QUITED", String.valueOf(getPort())); + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("message", message); + } + + @Override + public void unSerialize(JsonObject json) { + message = json.get("message").getAsString(); + } +} diff --git a/src/main/java/me/skymc/taboolib/socket/server/ClientConnection.java b/src/main/java/me/skymc/taboolib/socket/server/ClientConnection.java new file mode 100644 index 0000000..997d1ab --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/server/ClientConnection.java @@ -0,0 +1,88 @@ +package me.skymc.taboolib.socket.server; + +import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.socket.TabooLibServer; +import me.skymc.taboolib.socket.TabooLibSettings; +import me.skymc.taboolib.socket.packet.impl.PacketJoin; +import me.skymc.taboolib.socket.packet.impl.PacketQuit; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.SocketException; + +/** + * @Author sky + * @Since 2018-08-22 22:30 + */ +public class ClientConnection implements Runnable { + + private final Socket socket; + private BufferedReader reader; + private PrintWriter writer; + private String latestPacket; + private long latestResponse = System.currentTimeMillis(); + + public ClientConnection(Socket socket) { + this.socket = socket; + try { + reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), TabooLibSettings.getCharset())); + writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), TabooLibSettings.getCharset()), true); + TabooLibServer.sendPacket(new PacketJoin(socket.getPort())); + } catch (Exception e) { + TabooLibServer.println("Client joined failed: " + e.toString()); + } + } + + @Override + public void run() { + try { + while ((latestPacket = reader.readLine()) != null) { + TabooLibServer.sendPacket(latestPacket); + } + } catch (SocketException e) { + /* + 连接丢失,客户端退出 + */ + TabooLibServer.sendPacket(new PacketQuit(socket.getPort(), e.getMessage())); + } catch (Exception e) { + TabooLibServer.println("Client running failed: " + e.toString()); + } + } + + public boolean isAlive() { + return System.currentTimeMillis() - latestResponse < NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.timeout")); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public Socket getSocket() { + return socket; + } + + public BufferedReader getReader() { + return reader; + } + + public PrintWriter getWriter() { + return writer; + } + + public String getLatestPacket() { + return latestPacket; + } + + public long getLatestResponse() { + return latestResponse; + } + + public void setLatestResponse(long latestResponse) { + this.latestResponse = latestResponse; + } +} diff --git a/src/main/java/me/skymc/taboolib/string/ArrayUtils.java b/src/main/java/me/skymc/taboolib/string/ArrayUtils.java index 86bc5fe..8b16548 100644 --- a/src/main/java/me/skymc/taboolib/string/ArrayUtils.java +++ b/src/main/java/me/skymc/taboolib/string/ArrayUtils.java @@ -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 skipEmpty(T obj) { + return skipEmpty(obj, null); + } + + public static T[] skipEmpty(T[] obj) { + return skipEmpty(obj, null); + } + + public static T skipEmpty(T obj, T def) { + return Strings.isEmpty(String.valueOf(obj)) ? def : obj; + } + + public static T[] skipEmpty(T[] obj, T[] def) { + if (obj.length == 0) { + return def; + } + T firstElement = skipEmpty(obj[0]); + return firstElement == null ? def : obj; + } + // ********************************* // // Deprecated diff --git a/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java b/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java index f2d4596..37c3537 100644 --- a/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java +++ b/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java @@ -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 - } + } } diff --git a/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java b/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java index 662344d..750e218 100644 --- a/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java +++ b/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java @@ -5,6 +5,7 @@ import java.util.LinkedList; /** * @author sky */ +@Deprecated public class ThreadUtils { private static final LinkedList queue = new LinkedList<>(); diff --git a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java index 0817bdd..86e3c31 100644 --- a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java +++ b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java @@ -3,6 +3,7 @@ package me.skymc.taboolib.translateuuid; 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.TCommand; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.commands.internal.type.CommandRegister; import org.bukkit.command.Command; @@ -12,6 +13,11 @@ import org.bukkit.command.CommandSender; * @Author sky * @Since 2018-06-22 17:09 */ +@TCommand( + name = "translateuuid", + aliases = "tuuid", + permission = "taboolib.admin" +) public class TranslateUUIDCommand extends BaseMainCommand { @Override diff --git a/src/main/resources/JavaShells/scripts/-testshell.java b/src/main/resources/JavaShells/scripts/-testshell.java deleted file mode 100644 index 8c6b542..0000000 --- a/src/main/resources/JavaShells/scripts/-testshell.java +++ /dev/null @@ -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!"); - } -} \ No newline at end of file diff --git a/src/main/resources/bungee.yml b/src/main/resources/bungee.yml new file mode 100644 index 0000000..1ac27bb --- /dev/null +++ b/src/main/resources/bungee.yml @@ -0,0 +1,5 @@ +name: TabooLib +main: me.skymc.taboolib.bungee.TabooLibBungee +version: ${project.version} + +author: [lzzelAliz, 坏黑] \ No newline at end of file diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index fbf0b08..2684f3a 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -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: '设置玩家展示名称' @@ -367,6 +356,7 @@ COMMANDS: - ' &f- &7注册插件: &f{1}' - ' &f- &7上次刷新时间: &f{2}' - ' &f- &7下次刷新时间: &f{3}' + - '' LIST: HEAD: - '' @@ -548,7 +538,37 @@ COMMANDS: 0: '目标' 1: '内容' INVALID-TARGET-NOT-FOUND: '&8[&3&lTabooLib&8] &4目标 &c{0} &4不存在.' + TLOGS: + COMMAND-TITLE: '&e&l----- &6&lTabooLibLogs Commands &e&l-----' + INFO: + DESCRIPTION: '写入一般记录' + ARGUMENTS: + 0: '目录' + 1: '内容' + SUCCESS: '&8[&3&lTabooLib&8] &7写入完成.' + ERROR: + DESCRIPTION: '写入错误记录' + ARGUMENTS: + 0: '目录' + 1: '内容' + SUCCESS: '&8[&3&lTabooLib&8] &7写入完成.' + WARNING: + DESCRIPTION: '写入警告记录' + ARGUMENTS: + 0: '目录' + 1: '内容' + SUCCESS: '&8[&3&lTabooLib&8] &7写入完成.' DATABASE: CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}' - CONNECTION-ERROR: '连接到数据库错误:{0}' \ No newline at end of file + CONNECTION-ERROR: '连接到数据库错误:{0}' + +COMMUNICATION: + FAILED-LOAD-SETTINGS: '§8[§3§lTabooLibClient§8] &4配置载入失败: {0}' + FAILED-CONNECT-SERVER: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接失败.' + FAILED-CONNECT-CLIENT: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接出错: {0}' + FAILED-READING-PACKET: '§8[§3§lTabooLibClient§8] &4本地通讯网络数据包读取失败: {0}' + 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退出本地通讯网络.' + PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2a0c06d..c3521d8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,34 +1,15 @@ - name: TabooLib - -authors: [坏黑] -website: http://www.15imc.com/index.html - main: me.skymc.taboolib.Main - version: ${project.version} +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 - -depend: [Vault] -softdepend: [PlaceholderAPI, Skript, MassiveLag] \ No newline at end of file + aliases: [tlm] \ No newline at end of file diff --git a/src/main/resources/settings.properties b/src/main/resources/settings.properties new file mode 100644 index 0000000..d6c7750 --- /dev/null +++ b/src/main/resources/settings.properties @@ -0,0 +1,2 @@ +channel.port=5260 +channel.timeout=5000 \ No newline at end of file