From 4d59c7c3d6d596858c1ce2ac045da01b848d6fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sat, 8 Sep 2018 18:06:43 +0800 Subject: [PATCH] =?UTF-8?q?TabooLib=20v4.25=20+=20=E6=96=B0=E5=A2=9E=20TCo?= =?UTF-8?q?nfiguration=20=E5=B7=A5=E5=85=B7=EF=BC=8C=E4=B8=8E=20TConfigWat?= =?UTF-8?q?cher=20=E8=81=94=E5=8A=A8=E5=88=9B=E5=BB=BA=E8=83=BD=E5=A4=9F?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E8=BD=BD=E7=9A=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E3=80=82=EF=BC=88=E5=B0=9A=E6=9C=AA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=89=20+=20=E6=96=B0=E5=A2=9E=20TFunction=20?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=EF=BC=8C=E8=87=AA=E5=8A=A8=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E8=BD=BD=E5=85=A5=E4=B8=8E=E5=8D=B8=E8=BD=BD=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=80=82=EF=BC=88=E5=8F=98=E6=87=92=E7=AC=AC=E4=B8=80=E6=AD=A5?= =?UTF-8?q?=EF=BC=8C=E6=94=BE=E5=BC=83=E6=B3=A8=E5=86=8C=E6=AD=A5=E9=AA=A4?= =?UTF-8?q?=EF=BC=89=20+=20=E8=B0=83=E6=95=B4=20TLogger=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=EF=BC=8C=E5=85=81=E8=AE=B8=E4=BB=A5=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=90=8D=E7=A7=B0=E5=88=9B=E5=BB=BA=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9C=A8=20BungeeCord=20=E4=B8=8B=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=80=82=20+=20=E8=B0=83=E6=95=B4=20TListener=20?= =?UTF-8?q?=E4=B8=8E=20Instantiable=20=E6=B3=A8=E8=A7=A3=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E5=86=8D=E9=87=8D=E5=A4=8D=E8=AF=BB=E5=8F=96=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E4=BA=86=E3=80=82=20+=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=20ReflectionUtils=20=E5=B7=A5=E5=85=B7=EF=BC=8C=E5=AF=B9?= =?UTF-8?q?=E9=83=A8=E5=88=86=E8=AF=AD=E6=B3=95=E8=BF=9B=E8=A1=8C=E4=BA=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E3=80=82=20+=20=E8=B0=83=E6=95=B4=20TabooLib?= =?UTF-8?q?=20=E7=B1=BB=E4=B8=8B=E7=9A=84=20isSpigot=20=E4=B8=8E=20getVers?= =?UTF-8?q?ion=20=E7=AE=97=E6=B3=95=E3=80=82=20+=20=E9=87=8D=E5=81=9A=20An?= =?UTF-8?q?vilContainerAPI=20=E5=B7=A5=E5=85=B7=EF=BC=8C=E7=8E=B0=E5=9C=A8?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=AD=A3=E5=B8=B8=E4=BD=BF=E7=94=A8=E4=BA=86?= =?UTF-8?q?=E3=80=82=EF=BC=88=E4=B8=A2=E4=BA=BA=E7=8E=A9=E6=84=8F=E5=84=BF?= =?UTF-8?q?=E7=BB=88=E4=BA=8E=E9=87=8D=E5=86=99=E4=BA=86=EF=BC=89=20+=20In?= =?UTF-8?q?stanceHandler=20=E7=B1=BB=E6=9B=B4=E5=90=8D=E4=B8=BA=20Instanti?= =?UTF-8?q?ableLoader=20+=20MsgUtils=20=E7=B1=BB=E8=A2=AB=E8=B5=8B?= =?UTF-8?q?=E4=BA=88=E5=B0=8A=E8=B4=B5=E7=9A=84=20@Deprecated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../java/com/ilummc/tlib/logger/TLogger.java | 64 +- .../java/com/ilummc/tlib/nms/ActionBar.java | 4 +- .../tlib/util/asm/AsmClassTransformer.java | 25 +- src/main/java/me/skymc/taboolib/Main.java | 3 + src/main/java/me/skymc/taboolib/TabooLib.java | 15 +- .../me/skymc/taboolib/TabooLibLoader.java | 83 +- .../skymc/taboolib/anvil/AnvilContainer.java | 85 +- .../taboolib/anvil/AnvilContainerAPI.java | 101 +- .../anvil/AnvilContainerAPIEvent.java | 28 - .../taboolib/anvil/AnvilContainerAsm.java | 145 +++ .../common/configuration/TConfiguration.java | 86 ++ .../taboolib/common/function/TFunction.java | 19 + .../common/function/TFunctionLoader.java | 90 ++ .../taboolib/listener/TListenerHandler.java | 36 +- .../me/skymc/taboolib/message/MsgUtils.java | 1 + .../taboolib/methods/ReflectionUtils.java | 1071 +++++++++-------- ...ceHandler.java => InstantiableLoader.java} | 29 +- src/main/resources/lang/zh_CN.yml | 8 +- 19 files changed, 1098 insertions(+), 797 deletions(-) delete mode 100644 src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPIEvent.java create mode 100644 src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java create mode 100644 src/main/java/me/skymc/taboolib/common/configuration/TConfiguration.java create mode 100644 src/main/java/me/skymc/taboolib/common/function/TFunction.java create mode 100644 src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java rename src/main/java/me/skymc/taboolib/object/{InstanceHandler.java => InstantiableLoader.java} (70%) diff --git a/pom.xml b/pom.xml index 1ecd919..9a828b7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.23 + 4.25 UTF-8 diff --git a/src/main/java/com/ilummc/tlib/logger/TLogger.java b/src/main/java/com/ilummc/tlib/logger/TLogger.java index 0feee53..2b3b664 100644 --- a/src/main/java/com/ilummc/tlib/logger/TLogger.java +++ b/src/main/java/com/ilummc/tlib/logger/TLogger.java @@ -1,9 +1,12 @@ package com.ilummc.tlib.logger; +import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.plugin.Plugin; public class TLogger { @@ -12,7 +15,7 @@ public class TLogger { private static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE); private final String pattern; - private Plugin plugin; + private String name; private int level; public static TLogger getGlobalLogger() { @@ -23,8 +26,8 @@ public class TLogger { return pattern; } - public Plugin getPlugin() { - return plugin; + public String getName() { + return name; } public int getLevel() { @@ -37,49 +40,83 @@ public class TLogger { public TLogger(String pattern, Plugin plugin, int level) { this.pattern = pattern; - this.plugin = plugin; + this.name = plugin.getName(); + this.level = level; + } + + public TLogger(String pattern, String name, int level) { + this.pattern = pattern; + this.name = name; this.level = level; } public void verbose(String msg) { if (level <= VERBOSE) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg)))); + } } } public void finest(String msg) { if (level <= FINEST) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg)))); + } } } public void fine(String msg) { if (level <= FINE) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg)))); + } } } public void info(String msg) { if (level <= INFO) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg)))); + } } } public void warn(String msg) { if (level <= WARN) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg)))); + } } } public void error(String msg) { if (level <= ERROR) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg)))); + } } } public void fatal(String msg) { if (level <= FATAL) { - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg))); + if (TabooLib.isSpigot()) { + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg))); + } else { + BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg)))); + } } } @@ -87,4 +124,7 @@ public class TLogger { return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.FINE); } + public static TLogger getUnformatted(String name) { + return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.FINE); + } } diff --git a/src/main/java/com/ilummc/tlib/nms/ActionBar.java b/src/main/java/com/ilummc/tlib/nms/ActionBar.java index 7ef5d6a..46e3edc 100644 --- a/src/main/java/com/ilummc/tlib/nms/ActionBar.java +++ b/src/main/java/com/ilummc/tlib/nms/ActionBar.java @@ -40,10 +40,8 @@ public abstract class ActionBar { @Override public void send(Player player, String text) { net.minecraft.server.v1_12_R1.ChatComponentText component = new net.minecraft.server.v1_12_R1.ChatComponentText(text); - net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component, - net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2)); + net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component, net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2)); ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } } } diff --git a/src/main/java/com/ilummc/tlib/util/asm/AsmClassTransformer.java b/src/main/java/com/ilummc/tlib/util/asm/AsmClassTransformer.java index a074273..59ef090 100644 --- a/src/main/java/com/ilummc/tlib/util/asm/AsmClassTransformer.java +++ b/src/main/java/com/ilummc/tlib/util/asm/AsmClassTransformer.java @@ -13,16 +13,15 @@ import java.util.Map; public class AsmClassTransformer extends ClassVisitor implements Opcodes { private final Class from; - - private final String fromVer, toVer; - + private final String fromVer; + private final String toVer; private final ClassWriter writer; - - private String newClassName, prevName; + private String newClassName; + private String prevName; private AsmClassTransformer(Class from, String fromVer, String toVer, ClassWriter classWriter) { super(Opcodes.ASM6, classWriter); - writer = classWriter; + this.writer = classWriter; this.from = from; this.fromVer = fromVer; this.toVer = toVer; @@ -67,9 +66,15 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes { super.visitInnerClass(replace(name), outerName, replace(name).substring(outerName.length() + 1), access); } + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit(version, access, newClassName.replace('.', '/'), replace(signature), replace(superName), replace(interfaces)); + } + private String replace(String text) { if (text != null) { - return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer) + return text + .replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer) .replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer) .replace(prevName, newClassName.replace('.', '/')); } else { @@ -88,12 +93,6 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes { } } - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, newClassName.replace('.', '/'), replace(signature), - replace(superName), replace(interfaces)); - } - private class AsmMethodTransformer extends MethodVisitor { AsmMethodTransformer(MethodVisitor visitor) { diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 8c3a5df..c6d0453 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.TLib; import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.IO; import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.common.function.TFunctionLoader; import me.skymc.taboolib.database.GlobalDataManager; import me.skymc.taboolib.database.PlayerDataManager; import me.skymc.taboolib.economy.EcoUtils; @@ -198,6 +199,8 @@ public class Main extends JavaPlugin { HikariHandler.closeDataSourceForce(); // 注销监听器 TListenerHandler.cancelListeners(); + // 注销子模块 + TFunctionLoader.unloadFunction(); // 结束数据库储存方法 if (getStorageType() == StorageType.SQL) { GlobalDataManager.SQLMethod.cancelSQLMethod(); diff --git a/src/main/java/me/skymc/taboolib/TabooLib.java b/src/main/java/me/skymc/taboolib/TabooLib.java index 8cb287c..44a5683 100644 --- a/src/main/java/me/skymc/taboolib/TabooLib.java +++ b/src/main/java/me/skymc/taboolib/TabooLib.java @@ -18,7 +18,8 @@ public class TabooLib { static { try { - spigot = Bukkit.getConsoleSender() != null; + Class.forName("org.bukkit.Bukkit"); + spigot = true; } catch (Exception ignored) { } } @@ -32,6 +33,16 @@ public class TabooLib { return (Main) Main.getInst(); } + /** + * 插件是否为 TabooLib(沙雕方法) + * + * @param plugin 插件 + * @return boolean + */ + public static boolean isTabooLib(Plugin plugin) { + return plugin.equals(instance()) || plugin.getName().equals("TabooLib"); + } + /** * 插件是否依赖于 TabooLib(依赖或软兼容) * @@ -66,7 +77,7 @@ public class TabooLib { * @return String */ public static String getVersion() { - return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + return Bukkit.getServer().getClass().getName().split("\\.")[3]; } /** diff --git a/src/main/java/me/skymc/taboolib/TabooLibLoader.java b/src/main/java/me/skymc/taboolib/TabooLibLoader.java index 57a1176..108a652 100644 --- a/src/main/java/me/skymc/taboolib/TabooLibLoader.java +++ b/src/main/java/me/skymc/taboolib/TabooLibLoader.java @@ -5,25 +5,45 @@ import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.inject.TDependencyInjector; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.bstats.Metrics; -import me.skymc.taboolib.commands.language.Language2Command; import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.listener.TListener; import me.skymc.taboolib.listener.TListenerHandler; import me.skymc.taboolib.playerdata.DataUtils; -import me.skymc.tlm.command.TLMCommands; import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.plugin.Plugin; import java.io.File; import java.io.InputStream; import java.net.InetAddress; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; /** * @Author sky * @Since 2018-08-23 17:04 */ -class TabooLibLoader { +@TListener +public class TabooLibLoader implements Listener { + + static HashMap> pluginClasses = new HashMap<>(); + + @EventHandler (priority = EventPriority.LOWEST) + public void onEnable(PluginEnableEvent e) { + pluginClasses.remove(e.getPlugin().getName()); + } + + @EventHandler (priority = EventPriority.MONITOR) + public void onDisable(PluginDisableEvent e) { + setupClasses(e.getPlugin()); + } static void setup() { testInternet(); @@ -33,10 +53,21 @@ class TabooLibLoader { } static void register() { + setupClasses(); registerListener(); registerMetrics(); } + /** + * 获取插件所有被读取到的类 + * + * @param plugin 插件 + * @return List + */ + public static Optional> getPluginClasses(Plugin plugin) { + return Optional.ofNullable(pluginClasses.get(plugin.getName())); + } + /** * 初始化插件文件夹 */ @@ -45,6 +76,40 @@ class TabooLibLoader { Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA"))); } + /** + * 载入插件数据库 + */ + static void setupDatabase() { + DataUtils.addPluginData("TabooLibrary", null); + // 检查是否启用数据库 + Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL); + // 初始化数据库 + TabooLibDatabase.init(); + } + + /** + * 读取插件类 + */ + static void setupClasses() { + Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TabooLibLoader::setupClasses); + } + + /** + * 读取插件类 + */ + static void setupClasses(Plugin plugin) { + if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) { + return; + } + try { + long time = System.currentTimeMillis(); + List classes = FileUtils.getClasses(plugin); + TLocale.Logger.info("DEPENDENCY.LOAD-CLASSES", plugin.getName(), String.valueOf(classes.size()), String.valueOf(System.currentTimeMillis() - time)); + pluginClasses.put(plugin.getName(), classes); + } catch (Exception ignored) { + } + } + /** * 初始化插件依赖库 */ @@ -84,17 +149,6 @@ class TabooLibLoader { } } - /** - * 载入插件数据库 - */ - static void setupDatabase() { - DataUtils.addPluginData("TabooLibrary", null); - // 检查是否启用数据库 - Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL); - // 初始化数据库 - TabooLibDatabase.init(); - } - /** * 载入插件监听 */ @@ -113,5 +167,4 @@ class TabooLibLoader { metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count()))); metrics.addCustomChart(new Metrics.AdvancedPie("plugins_using_taboolib_name", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).collect(Collectors.toMap(Plugin::getName, plugin -> 1, (a, b) -> b)))); } - } diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java index b9a4246..0ebfc47 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainer.java @@ -1,78 +1,29 @@ package me.skymc.taboolib.anvil; -import me.skymc.taboolib.nms.NMSUtils; import org.bukkit.entity.Player; /** - * @author sky + * @Author sky + * @Since 2018-09-08 15:47 */ -public class AnvilContainer { +public class AnvilContainer extends net.minecraft.server.v1_12_R1.ContainerAnvil { -// private static IAnvilContainer instance; + public AnvilContainer(net.minecraft.server.v1_12_R1.EntityHuman player) { + super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player); + } - private static Class ChatMessage = NMSUtils.getNMSClass("ChatMessage"); - private static Class PacketPlayOutOpenWindow = NMSUtils.getNMSClass("PacketPlayOutOpenWindow"); - private static Class IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent"); - private static Class Packet = NMSUtils.getNMSClass("Packet"); - -// public static IAnvilContainer getInstance() { -// return instance; -// } -// -// static { -// /* -// * 玩不懂玩不懂... 似乎不会更改父类的包名? -// */ -// instance = (IAnvilContainer) AsmClassTransformer.builder() -// .from(AnvilContainerImpl.class) -// .fromVersion("v1_12_R1") -// .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]) -// .build() -// .transform(); -// } + @Override + public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) { + return true; + } public static void openAnvil(Player p) { - try { - Object player = p.getClass().getMethod("getHandle").invoke(p); - int c = (int) player.getClass().getMethod("nextContainerCounter").invoke(player); - Object chatMessage = ChatMessage.getConstructor(String.class, Object[].class).newInstance("Repairing", new Object[0]); - Object packetPlayOutOpenWindow = PacketPlayOutOpenWindow.getConstructor(Integer.TYPE, String.class, IChatBaseComponent, Integer.TYPE).newInstance(c, "minecraft:anvil", chatMessage, 0); - Object playerConnection = player.getClass().getDeclaredField("playerConnection").get(player); - playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packetPlayOutOpenWindow); - } catch (Exception ignored) { - } + net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle(); + AnvilContainer container = new AnvilContainer(player); + int c = player.nextContainerCounter(); + player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0)); + player.activeContainer = container; + player.activeContainer.windowId = c; + player.activeContainer.addSlotListener(player); } -} - -//interface IAnvilContainer { -// -// /** -// * 打开铁砧界面 -// * -// * @param player 玩家 -// */ -// void openAnvil(Player player); -//} -// -//class AnvilContainerImpl extends net.minecraft.server.v1_12_R1.ContainerAnvil implements IAnvilContainer { -// -// public AnvilContainerImpl(net.minecraft.server.v1_12_R1.EntityHuman player) { -// super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player); -// } -// -// @Override -// public void openAnvil(Player p) { -// net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle(); -// AnvilContainerImpl container = new AnvilContainerImpl(player); -// int c = player.nextContainerCounter(); -// player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0)); -// player.activeContainer = container; -// player.activeContainer.windowId = c; -// player.activeContainer.addSlotListener(player); -// } -// -// @Override -// public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) { -// return true; -// } -//} +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java index 2ab1b0a..d15768a 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java @@ -1,105 +1,42 @@ package me.skymc.taboolib.anvil; -import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.util.asm.AsmClassLoader; +import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.listener.TListener; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +/** + * @author sky + */ @TListener public class AnvilContainerAPI implements Listener { - public static List list = new ArrayList<>(); - public static ItemStack item = new ItemStack(Material.NAME_TAG); - public static HashMap isOpen = new HashMap<>(); - public static AnvilContainerAPIEvent event; + private static Class impl; - public static void send(Player p, String type, String str, List lorelist) { - isOpen.put(p.getName(), type); - - AnvilContainer.openAnvil(p); - ItemMeta meta = item.getItemMeta(); - - list.clear(); - if (lorelist == null) { - list.addAll(TLocale.asStringList("ANVIL-CONTAINER.LORE-NORMAL")); - } else { - list = lorelist; - } - - meta.setLore(list); - meta.setDisplayName(str); - item.setItemMeta(meta); - - p.getOpenInventory().getTopInventory().setItem(0, item); - p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1); - } - - @EventHandler - public void close(InventoryCloseEvent e) { - if (isOpen.containsKey(e.getPlayer().getName())) { - isOpen.remove(e.getPlayer().getName()); - if (e.getInventory().getType() == InventoryType.ANVIL) { - e.getInventory().clear(); - } + public AnvilContainerAPI() { + try { + impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerAsm.create(TabooLib.getVersion())); + } catch (Exception e) { + e.printStackTrace(); } } - @EventHandler - public void click(InventoryClickEvent e) { - if (!isOpen.containsKey(e.getWhoClicked().getName())) { - return; - } - if (e.getInventory().getType() != InventoryType.ANVIL) { - return; - } - e.setCancelled(true); - - int slot = e.getRawSlot(); - if (slot != 2) { - return; - } - - Inventory inv = e.getInventory(); - if (inv.getItem(2) == null) { - return; - } - - if (inv.getItem(2).getItemMeta().hasDisplayName()) { - event = new AnvilContainerAPIEvent(e, isOpen.get(e.getWhoClicked().getName()), inv.getItem(2).getItemMeta().getDisplayName()); - e.getWhoClicked().closeInventory(); - Bukkit.getPluginManager().callEvent(event); + public static void openAnvil(Player player) { + try { + impl.getMethod("openAnvil", Player.class).invoke(impl, player); + } catch (Exception e) { + e.printStackTrace(); } } @EventHandler public void example(PlayerCommandPreprocessEvent e) { - if ("/anvilexample".equals(e.getMessage())) { - if (e.getPlayer().hasPermission("taboolib.admin")) { - e.setCancelled(true); - AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", TLocale.asString("ANVIL-CONTAINER.NAME-EXAMPLE"), null); - } - } - } - - @EventHandler - public void example2(AnvilContainerAPIEvent e) { - if ("EXAMPLE".equals(e.type)) { - e.event.getWhoClicked().sendMessage(e.string); + if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) { + e.setCancelled(true); + openAnvil(e.getPlayer()); } } } diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPIEvent.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPIEvent.java deleted file mode 100644 index cb7f4c8..0000000 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPIEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.skymc.taboolib.anvil; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.bukkit.event.inventory.InventoryClickEvent; - -public class AnvilContainerAPIEvent extends Event { - - public static final HandlerList handlers = new HandlerList(); - public InventoryClickEvent event; - public String string; - public String type; - - public AnvilContainerAPIEvent(InventoryClickEvent e, String t, String s) { - event = e; - string = s; - type = t; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } -} diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java new file mode 100644 index 0000000..608f39e --- /dev/null +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAsm.java @@ -0,0 +1,145 @@ +package me.skymc.taboolib.anvil; + +import org.objectweb.asm.*; + +/** + * @author sky + */ +public class AnvilContainerAsm { + + public static byte[] create(String version) { + + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "me/skymc/taboolib/anvil/AnvilContainer", null, "net/minecraft/server/" + version + "/ContainerAnvil", null); + + cw.visitSource("AnvilContainer.java", null); + + { + mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(12, l0); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "inventory", "Lnet/minecraft/server/" + version + "/PlayerInventory;"); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "world", "Lnet/minecraft/server/" + version + "/World;"); + mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/BlockPosition"); + mv.visitInsn(Opcodes.DUP); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/BlockPosition", "", "(III)V", false); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ContainerAnvil", "", "(Lnet/minecraft/server/" + version + "/PlayerInventory;Lnet/minecraft/server/" + version + "/World;Lnet/minecraft/server/" + version + "/BlockPosition;Lnet/minecraft/server/" + version + "/EntityHuman;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(13, l1); + mv.visitInsn(Opcodes.RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l2, 0); + mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l2, 1); + mv.visitMaxs(8, 2); + mv.visitEnd(); + } + { + mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "a", "(Lnet/minecraft/server/" + version + "/EntityHuman;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(17, l0); + mv.visitInsn(Opcodes.ICONST_1); + mv.visitInsn(Opcodes.IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l1, 0); + mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + } + { + mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "openAnvil", "(Lorg/bukkit/entity/Player;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(21, l0); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitTypeInsn(Opcodes.CHECKCAST, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer"); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer", "getHandle", "()Lnet/minecraft/server/" + version + "/EntityPlayer;", false); + mv.visitVarInsn(Opcodes.ASTORE, 1); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(22, l1); + mv.visitTypeInsn(Opcodes.NEW, "me/skymc/taboolib/anvil/AnvilContainer"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "me/skymc/taboolib/anvil/AnvilContainer", "", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", false); + mv.visitVarInsn(Opcodes.ASTORE, 2); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(23, l2); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/EntityPlayer", "nextContainerCounter", "()I", false); + mv.visitVarInsn(Opcodes.ISTORE, 3); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(24, l3); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "playerConnection", "Lnet/minecraft/server/" + version + "/PlayerConnection;"); + mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ILOAD, 3); + mv.visitLdcInsn("minecraft:anvil"); + mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/ChatMessage"); + mv.visitInsn(Opcodes.DUP); + mv.visitLdcInsn("Repairing"); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ChatMessage", "", "(Ljava/lang/String;[Ljava/lang/Object;)V", false); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow", "", "(ILjava/lang/String;Lnet/minecraft/server/" + version + "/IChatBaseComponent;I)V", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/PlayerConnection", "sendPacket", "(Lnet/minecraft/server/" + version + "/Packet;)V", false); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(25, l4); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitVarInsn(Opcodes.ALOAD, 2); + mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;"); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(26, l5); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;"); + mv.visitVarInsn(Opcodes.ILOAD, 3); + mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/Container", "windowId", "I"); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(27, l6); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;"); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/Container", "addSlotListener", "(Lnet/minecraft/server/" + version + "/ICrafting;)V", false); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(28, l7); + mv.visitInsn(Opcodes.RETURN); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLocalVariable("p", "Lorg/bukkit/entity/Player;", null, l0, l8, 0); + mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityPlayer;", null, l1, l8, 1); + mv.visitLocalVariable("container", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l2, l8, 2); + mv.visitLocalVariable("c", "I", null, l3, l8, 3); + mv.visitMaxs(9, 4); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } +} diff --git a/src/main/java/me/skymc/taboolib/common/configuration/TConfiguration.java b/src/main/java/me/skymc/taboolib/common/configuration/TConfiguration.java new file mode 100644 index 0000000..361aa75 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/common/configuration/TConfiguration.java @@ -0,0 +1,86 @@ +package me.skymc.taboolib.common.configuration; + +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.logger.TLogger; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.util.Optional; + +/** + * @Author sky + * @Since 2018-09-08 15:00 + */ +public class TConfiguration extends YamlConfiguration { + + private File file; + private Runnable runnable; + + private TConfiguration(File file) { + this.file = file; + reload(); + TLib.getTLib().getConfigWatcher().addSimpleListener(this.file, this::reload); + } + + /** + * 释放文件监听 + */ + public void release() { + TLib.getTLib().getConfigWatcher().removeListener(file); + } + + /** + * 重新载入配置 + */ + public void reload() { + try { + load(file); + Optional.ofNullable(runnable).ifPresent(Runnable::run); + } catch (IOException | InvalidConfigurationException e) { + TLogger.getGlobalLogger().warn("Cannot load configuration from stream: " + e.toString()); + } + } + + /** + * 创建配置文件 + * + * @param file 文件 + * @return {@link TConfiguration} + */ + public static TConfiguration create(File file) { + return new TConfiguration(file); + } + + /** + * 从插件里释放文件并创建 + * + * @param plugin 插件 + * @param path 目录 + * @return {@link TConfiguration} + */ + public static TConfiguration createInResource(Plugin plugin, String path) { + File file = new File(plugin.getDataFolder(), path); + if (!file.exists()) { + plugin.saveResource(path, true); + } + return create(file); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public File getFile() { + return file; + } + + public TConfiguration listener(Runnable runnable) { + this.runnable = runnable; + return this; + } +} diff --git a/src/main/java/me/skymc/taboolib/common/function/TFunction.java b/src/main/java/me/skymc/taboolib/common/function/TFunction.java new file mode 100644 index 0000000..4bc3925 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/common/function/TFunction.java @@ -0,0 +1,19 @@ +package me.skymc.taboolib.common.function; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Author sky + * @Since 2018-09-08 14:01 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface TFunction { + + String enable() default "onEnable"; + String disable() default "onDisable"; + +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java b/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java new file mode 100644 index 0000000..9ef819f --- /dev/null +++ b/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java @@ -0,0 +1,90 @@ +package me.skymc.taboolib.common.function; + +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.TabooLibLoader; +import me.skymc.taboolib.listener.TListener; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Method; +import java.util.*; + +/** + * @Author sky + * @Since 2018-09-08 14:00 + */ +@TListener +public class TFunctionLoader implements Listener { + + private static HashMap> pluginFunction = new HashMap<>(); + + TFunctionLoader() { + loadFunction(); + } + + public static void loadFunction() { + Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::loadFunction); + } + + public static void loadFunction(Plugin plugin) { + if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) { + return; + } + TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> { + for (Class pluginClass : classes) { + if (pluginClass.isAnnotationPresent(TFunction.class)) { + TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class); + try { + Method method = pluginClass.getDeclaredMethod(function.enable()); + if (method == null) { + continue; + } + method.setAccessible(true); + method.invoke(pluginClass.newInstance()); + pluginFunction.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(pluginClass); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + + public static void unloadFunction() { + Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::unloadFunction); + } + + public static void unloadFunction(Plugin plugin) { + Optional.ofNullable(pluginFunction.remove(plugin.getName())).ifPresent(classes -> { + for (Class pluginClass : classes) { + if (pluginClass.isAnnotationPresent(TFunction.class)) { + TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class); + try { + Method method = pluginClass.getDeclaredMethod(function.disable()); + if (method == null) { + continue; + } + method.setAccessible(true); + method.invoke(pluginClass.newInstance()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + + @EventHandler + public void onEnable(PluginEnableEvent e) { + loadFunction(e.getPlugin()); + } + + @EventHandler + public void onDisable(PluginDisableEvent e) { + unloadFunction(e.getPlugin()); + } +} diff --git a/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java b/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java index b46fdf8..02fd37c 100644 --- a/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java +++ b/src/main/java/me/skymc/taboolib/listener/TListenerHandler.java @@ -2,7 +2,9 @@ package me.skymc.taboolib.listener; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.TabooLibLoader; import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.methods.ReflectionUtils; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; @@ -43,28 +45,26 @@ public class TListenerHandler implements Listener { * @param plugin 插件 */ public static void setupListener(Plugin plugin) { - if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) { - return; - } - List classes = FileUtils.getClasses(plugin); - for (Class pluginClass : classes) { - if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) { - try { - TListener tListener = pluginClass.getAnnotation(TListener.class); - // 检查注册条件 - if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) { - if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) { - continue; + TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> { + for (Class pluginClass : classes) { + if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) { + try { + TListener tListener = pluginClass.getAnnotation(TListener.class); + // 检查注册条件 + if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) { + if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) { + continue; + } } + // 实例化监听器 + Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) ReflectionUtils.instantiateObject(pluginClass); + listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener); + } catch (Exception e) { + e.printStackTrace(); } - // 实例化监听器 - Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance(); - listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener); - } catch (Exception e) { - e.printStackTrace(); } } - } + }); } /** diff --git a/src/main/java/me/skymc/taboolib/message/MsgUtils.java b/src/main/java/me/skymc/taboolib/message/MsgUtils.java index 8692de7..9ed7c56 100644 --- a/src/main/java/me/skymc/taboolib/message/MsgUtils.java +++ b/src/main/java/me/skymc/taboolib/message/MsgUtils.java @@ -5,6 +5,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; +@Deprecated public class MsgUtils { public static void send(CommandSender sender, String s) { diff --git a/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java b/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java index 6b2c54a..eede188 100644 --- a/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java +++ b/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java @@ -19,582 +19,585 @@ import java.util.Map; *
  • Don't claim this class as your own *
  • Don't remove this disclaimer * - *

    + * * It would be nice if you provide credit to me if you use this class in a published project - * + * * @author DarkBlade12 * @version 1.1 */ public final class ReflectionUtils { - // Prevent accidental construction - private ReflectionUtils() {} + // Prevent accidental construction + private ReflectionUtils() { + } - /** - * Returns the constructor of a given class with the given parameter types - * - * @param clazz Target class - * @param parameterTypes Parameter types of the desired constructor - * @return The constructor of the target class with the specified parameter types - * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found - * @see DataType - * @see DataType#getPrimitive(Class[]) - * @see DataType#compare(Class[], Class[]) - */ - public static Constructor getConstructor(Class clazz, Class... parameterTypes) throws NoSuchMethodException { - Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); - for (Constructor constructor : clazz.getConstructors()) { - if (!DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) { - continue; - } - return constructor; - } - throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types"); - } + /** + * Returns the constructor of a given class with the given parameter types + * + * @param clazz Target class + * @param parameterTypes Parameter types of the desired constructor + * @return The constructor of the target class with the specified parameter types + * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found + * @see DataType + * @see DataType#getPrimitive(Class[]) + * @see DataType#compare(Class[], Class[]) + */ + public static Constructor getConstructor(Class clazz, Class... parameterTypes) throws NoSuchMethodException { + Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); + for (Constructor constructor : clazz.getDeclaredConstructors()) { + if (!DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) { + continue; + } + constructor.setAccessible(true); + return constructor; + } + throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types"); + } - /** - * Returns the constructor of a desired class with the given parameter types - * - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param parameterTypes Parameter types of the desired constructor - * @return The constructor of the desired target class with the specified parameter types - * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found - * @throws ClassNotFoundException ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #getConstructor(Class, Class...) - */ - public static Constructor getConstructor(String className, PackageType packageType, Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { - return getConstructor(packageType.getClass(className), parameterTypes); - } + /** + * Returns the constructor of a desired class with the given parameter types + * + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param parameterTypes Parameter types of the desired constructor + * @return The constructor of the desired target class with the specified parameter types + * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found + * @throws ClassNotFoundException ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #getConstructor(Class, Class...) + */ + public static Constructor getConstructor(String className, PackageType packageType, Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { + return getConstructor(packageType.getClass(className), parameterTypes); + } - /** - * Returns an instance of a class with the given arguments - * - * @param clazz Target class - * @param arguments Arguments which are used to construct an object of the target class - * @return The instance of the target class with the specified arguments - * @throws InstantiationException If you cannot create an instance of the target class due to certain circumstances - * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances - * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments) - * @throws InvocationTargetException If the desired constructor cannot be invoked - * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found - */ - public static Object instantiateObject(Class clazz, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { - return getConstructor(clazz, DataType.getPrimitive(arguments)).newInstance(arguments); - } + /** + * Returns an instance of a class with the given arguments + * + * @param clazz Target class + * @param arguments Arguments which are used to construct an object of the target class + * @return The instance of the target class with the specified arguments + * @throws InstantiationException If you cannot create an instance of the target class due to certain circumstances + * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances + * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments) + * @throws InvocationTargetException If the desired constructor cannot be invoked + * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found + */ + public static Object instantiateObject(Class clazz, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getConstructor(clazz, DataType.getPrimitive(arguments)).newInstance(arguments); + } - /** - * Returns an instance of a desired class with the given arguments - * - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param arguments Arguments which are used to construct an object of the desired target class - * @return The instance of the desired target class with the specified arguments - * @throws InstantiationException If you cannot create an instance of the desired target class due to certain circumstances - * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances - * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments) - * @throws InvocationTargetException If the desired constructor cannot be invoked - * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #instantiateObject(Class, Object...) - */ - public static Object instantiateObject(String className, PackageType packageType, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { - return instantiateObject(packageType.getClass(className), arguments); - } + /** + * Returns an instance of a desired class with the given arguments + * + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param arguments Arguments which are used to construct an object of the desired target class + * @return The instance of the desired target class with the specified arguments + * @throws InstantiationException If you cannot create an instance of the desired target class due to certain circumstances + * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances + * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments) + * @throws InvocationTargetException If the desired constructor cannot be invoked + * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #instantiateObject(Class, Object...) + */ + public static Object instantiateObject(String className, PackageType packageType, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { + return instantiateObject(packageType.getClass(className), arguments); + } - /** - * Returns a method of a class with the given parameter types - * - * @param clazz Target class - * @param methodName Name of the desired method - * @param parameterTypes Parameter types of the desired method - * @return The method of the target class with the specified name and parameter types - * @throws NoSuchMethodException If the desired method of the target class with the specified name and parameter types cannot be found - * @see DataType#getPrimitive(Class[]) - * @see DataType#compare(Class[], Class[]) - */ - public static Method getMethod(Class clazz, String methodName, Class... parameterTypes) throws NoSuchMethodException { - Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); - for (Method method : clazz.getMethods()) { - if (!method.getName().equals(methodName) || !DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) { - continue; - } - return method; - } - throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types"); - } + /** + * Returns a method of a class with the given parameter types + * + * @param clazz Target class + * @param methodName Name of the desired method + * @param parameterTypes Parameter types of the desired method + * @return The method of the target class with the specified name and parameter types + * @throws NoSuchMethodException If the desired method of the target class with the specified name and parameter types cannot be found + * @see DataType#getPrimitive(Class[]) + * @see DataType#compare(Class[], Class[]) + */ + public static Method getMethod(Class clazz, String methodName, Class... parameterTypes) throws NoSuchMethodException { + Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); + for (Method method : clazz.getDeclaredMethods()) { + if (!method.getName().equals(methodName) || !DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) { + continue; + } + method.setAccessible(true); + return method; + } + throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types"); + } - /** - * Returns a method of a desired class with the given parameter types - * - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param methodName Name of the desired method - * @param parameterTypes Parameter types of the desired method - * @return The method of the desired target class with the specified name and parameter types - * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and parameter types cannot be found - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #getMethod(Class, String, Class...) - */ - public static Method getMethod(String className, PackageType packageType, String methodName, Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { - return getMethod(packageType.getClass(className), methodName, parameterTypes); - } + /** + * Returns a method of a desired class with the given parameter types + * + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param methodName Name of the desired method + * @param parameterTypes Parameter types of the desired method + * @return The method of the desired target class with the specified name and parameter types + * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and parameter types cannot be found + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #getMethod(Class, String, Class...) + */ + public static Method getMethod(String className, PackageType packageType, String methodName, Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { + return getMethod(packageType.getClass(className), methodName, parameterTypes); + } - /** - * Invokes a method on an object with the given arguments - * - * @param instance Target object - * @param methodName Name of the desired method - * @param arguments Arguments which are used to invoke the desired method - * @return The result of invoking the desired method on the target object - * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances - * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) - * @throws InvocationTargetException If the desired method cannot be invoked on the target object - * @throws NoSuchMethodException If the desired method of the class of the target object with the specified name and arguments cannot be found - * @see #getMethod(Class, String, Class...) - * @see DataType#getPrimitive(Object[]) - */ - public static Object invokeMethod(Object instance, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { - return getMethod(instance.getClass(), methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); - } + /** + * Invokes a method on an object with the given arguments + * + * @param instance Target object + * @param methodName Name of the desired method + * @param arguments Arguments which are used to invoke the desired method + * @return The result of invoking the desired method on the target object + * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances + * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) + * @throws InvocationTargetException If the desired method cannot be invoked on the target object + * @throws NoSuchMethodException If the desired method of the class of the target object with the specified name and arguments cannot be found + * @see #getMethod(Class, String, Class...) + * @see DataType#getPrimitive(Object[]) + */ + public static Object invokeMethod(Object instance, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getMethod(instance.getClass(), methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); + } - /** - * Invokes a method of the target class on an object with the given arguments - * - * @param instance Target object - * @param clazz Target class - * @param methodName Name of the desired method - * @param arguments Arguments which are used to invoke the desired method - * @return The result of invoking the desired method on the target object - * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances - * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) - * @throws InvocationTargetException If the desired method cannot be invoked on the target object - * @throws NoSuchMethodException If the desired method of the target class with the specified name and arguments cannot be found - * @see #getMethod(Class, String, Class...) - * @see DataType#getPrimitive(Object[]) - */ - public static Object invokeMethod(Object instance, Class clazz, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { - return getMethod(clazz, methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); - } + /** + * Invokes a method of the target class on an object with the given arguments + * + * @param instance Target object + * @param clazz Target class + * @param methodName Name of the desired method + * @param arguments Arguments which are used to invoke the desired method + * @return The result of invoking the desired method on the target object + * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances + * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) + * @throws InvocationTargetException If the desired method cannot be invoked on the target object + * @throws NoSuchMethodException If the desired method of the target class with the specified name and arguments cannot be found + * @see #getMethod(Class, String, Class...) + * @see DataType#getPrimitive(Object[]) + */ + public static Object invokeMethod(Object instance, Class clazz, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getMethod(clazz, methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); + } - /** - * Invokes a method of a desired class on an object with the given arguments - * - * @param instance Target object - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param methodName Name of the desired method - * @param arguments Arguments which are used to invoke the desired method - * @return The result of invoking the desired method on the target object - * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances - * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) - * @throws InvocationTargetException If the desired method cannot be invoked on the target object - * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and arguments cannot be found - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #invokeMethod(Object, Class, String, Object...) - */ - public static Object invokeMethod(Object instance, String className, PackageType packageType, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { - return invokeMethod(instance, packageType.getClass(className), methodName, arguments); - } + /** + * Invokes a method of a desired class on an object with the given arguments + * + * @param instance Target object + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param methodName Name of the desired method + * @param arguments Arguments which are used to invoke the desired method + * @return The result of invoking the desired method on the target object + * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances + * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments) + * @throws InvocationTargetException If the desired method cannot be invoked on the target object + * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and arguments cannot be found + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #invokeMethod(Object, Class, String, Object...) + */ + public static Object invokeMethod(Object instance, String className, PackageType packageType, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { + return invokeMethod(instance, packageType.getClass(className), methodName, arguments); + } - /** - * Returns a field of the target class with the given name - * - * @param clazz Target class - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @return The field of the target class with the specified name - * @throws NoSuchFieldException If the desired field of the given class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - */ - public static Field getField(Class clazz, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException { - Field field = declared ? clazz.getDeclaredField(fieldName) : clazz.getField(fieldName); - field.setAccessible(true); - return field; - } + /** + * Returns a field of the target class with the given name + * + * @param clazz Target class + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @return The field of the target class with the specified name + * @throws NoSuchFieldException If the desired field of the given class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + */ + public static Field getField(Class clazz, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException { + Field field = declared ? clazz.getDeclaredField(fieldName) : clazz.getField(fieldName); + field.setAccessible(true); + return field; + } - /** - * Returns a field of a desired class with the given name - * - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @return The field of the desired target class with the specified name - * @throws NoSuchFieldException If the desired field of the desired class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #getField(Class, boolean, String) - */ - public static Field getField(String className, PackageType packageType, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException, ClassNotFoundException { - return getField(packageType.getClass(className), declared, fieldName); - } + /** + * Returns a field of a desired class with the given name + * + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @return The field of the desired target class with the specified name + * @throws NoSuchFieldException If the desired field of the desired class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #getField(Class, boolean, String) + */ + public static Field getField(String className, PackageType packageType, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException, ClassNotFoundException { + return getField(packageType.getClass(className), declared, fieldName); + } - /** - * Returns the value of a field of the given class of an object - * - * @param instance Target object - * @param clazz Target class - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @return The value of field of the target object - * @throws IllegalArgumentException If the target object does not feature the desired field - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the target class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @see #getField(Class, boolean, String) - */ - public static Object getValue(Object instance, Class clazz, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { - return getField(clazz, declared, fieldName).get(instance); - } + /** + * Returns the value of a field of the given class of an object + * + * @param instance Target object + * @param clazz Target class + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @return The value of field of the target object + * @throws IllegalArgumentException If the target object does not feature the desired field + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the target class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @see #getField(Class, boolean, String) + */ + public static Object getValue(Object instance, Class clazz, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + return getField(clazz, declared, fieldName).get(instance); + } - /** - * Returns the value of a field of a desired class of an object - * - * @param instance Target object - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @return The value of field of the target object - * @throws IllegalArgumentException If the target object does not feature the desired field - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the desired class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #getValue(Object, Class, boolean, String) - */ - public static Object getValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { - return getValue(instance, packageType.getClass(className), declared, fieldName); - } + /** + * Returns the value of a field of a desired class of an object + * + * @param instance Target object + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @return The value of field of the target object + * @throws IllegalArgumentException If the target object does not feature the desired field + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the desired class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #getValue(Object, Class, boolean, String) + */ + public static Object getValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { + return getValue(instance, packageType.getClass(className), declared, fieldName); + } - /** - * Returns the value of a field with the given name of an object - * - * @param instance Target object - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @return The value of field of the target object - * @throws IllegalArgumentException If the target object does not feature the desired field (should not occur since it searches for a field with the given name in the class of the object) - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the target object cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @see #getValue(Object, Class, boolean, String) - */ - public static Object getValue(Object instance, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { - return getValue(instance, instance.getClass(), declared, fieldName); - } + /** + * Returns the value of a field with the given name of an object + * + * @param instance Target object + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @return The value of field of the target object + * @throws IllegalArgumentException If the target object does not feature the desired field (should not occur since it searches for a field with the given name in the class of the object) + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the target object cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @see #getValue(Object, Class, boolean, String) + */ + public static Object getValue(Object instance, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + return getValue(instance, instance.getClass(), declared, fieldName); + } - /** - * Sets the value of a field of the given class of an object - * - * @param instance Target object - * @param clazz Target class - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @param value New value - * @throws IllegalArgumentException If the type of the value does not match the type of the desired field - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the target class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @see #getField(Class, boolean, String) - */ - public static void setValue(Object instance, Class clazz, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { - getField(clazz, declared, fieldName).set(instance, value); - } + /** + * Sets the value of a field of the given class of an object + * + * @param instance Target object + * @param clazz Target class + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @param value New value + * @throws IllegalArgumentException If the type of the value does not match the type of the desired field + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the target class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @see #getField(Class, boolean, String) + */ + public static void setValue(Object instance, Class clazz, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + getField(clazz, declared, fieldName).set(instance, value); + } - /** - * Sets the value of a field of a desired class of an object - * - * @param instance Target object - * @param className Name of the desired target class - * @param packageType Package where the desired target class is located - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @param value New value - * @throws IllegalArgumentException If the type of the value does not match the type of the desired field - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the desired class cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found - * @see #setValue(Object, Class, boolean, String, Object) - */ - public static void setValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { - setValue(instance, packageType.getClass(className), declared, fieldName, value); - } + /** + * Sets the value of a field of a desired class of an object + * + * @param instance Target object + * @param className Name of the desired target class + * @param packageType Package where the desired target class is located + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @param value New value + * @throws IllegalArgumentException If the type of the value does not match the type of the desired field + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the desired class cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found + * @see #setValue(Object, Class, boolean, String, Object) + */ + public static void setValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { + setValue(instance, packageType.getClass(className), declared, fieldName, value); + } - /** - * Sets the value of a field with the given name of an object - * - * @param instance Target object - * @param declared Whether the desired field is declared or not - * @param fieldName Name of the desired field - * @param value New value - * @throws IllegalArgumentException If the type of the value does not match the type of the desired field - * @throws IllegalAccessException If the desired field cannot be accessed - * @throws NoSuchFieldException If the desired field of the target object cannot be found - * @throws SecurityException If the desired field cannot be made accessible - * @see #setValue(Object, Class, boolean, String, Object) - */ - public static void setValue(Object instance, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { - setValue(instance, instance.getClass(), declared, fieldName, value); - } + /** + * Sets the value of a field with the given name of an object + * + * @param instance Target object + * @param declared Whether the desired field is declared or not + * @param fieldName Name of the desired field + * @param value New value + * @throws IllegalArgumentException If the type of the value does not match the type of the desired field + * @throws IllegalAccessException If the desired field cannot be accessed + * @throws NoSuchFieldException If the desired field of the target object cannot be found + * @throws SecurityException If the desired field cannot be made accessible + * @see #setValue(Object, Class, boolean, String, Object) + */ + public static void setValue(Object instance, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + setValue(instance, instance.getClass(), declared, fieldName, value); + } - /** - * Represents an enumeration of dynamic packages of NMS and CraftBukkit - *

    - * This class is part of the ReflectionUtils and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.0 - */ - public enum PackageType { - MINECRAFT_SERVER("net.minecraft.server." + getServerVersion()), - CRAFTBUKKIT("org.bukkit.craftbukkit." + getServerVersion()), - CRAFTBUKKIT_BLOCK(CRAFTBUKKIT, "block"), - CRAFTBUKKIT_CHUNKIO(CRAFTBUKKIT, "chunkio"), - CRAFTBUKKIT_COMMAND(CRAFTBUKKIT, "command"), - CRAFTBUKKIT_CONVERSATIONS(CRAFTBUKKIT, "conversations"), - CRAFTBUKKIT_ENCHANTMENS(CRAFTBUKKIT, "enchantments"), - CRAFTBUKKIT_ENTITY(CRAFTBUKKIT, "entity"), - CRAFTBUKKIT_EVENT(CRAFTBUKKIT, "event"), - CRAFTBUKKIT_GENERATOR(CRAFTBUKKIT, "generator"), - CRAFTBUKKIT_HELP(CRAFTBUKKIT, "help"), - CRAFTBUKKIT_INVENTORY(CRAFTBUKKIT, "inventory"), - CRAFTBUKKIT_MAP(CRAFTBUKKIT, "map"), - CRAFTBUKKIT_METADATA(CRAFTBUKKIT, "metadata"), - CRAFTBUKKIT_POTION(CRAFTBUKKIT, "potion"), - CRAFTBUKKIT_PROJECTILES(CRAFTBUKKIT, "projectiles"), - CRAFTBUKKIT_SCHEDULER(CRAFTBUKKIT, "scheduler"), - CRAFTBUKKIT_SCOREBOARD(CRAFTBUKKIT, "scoreboard"), - CRAFTBUKKIT_UPDATER(CRAFTBUKKIT, "updater"), - CRAFTBUKKIT_UTIL(CRAFTBUKKIT, "util"); + /** + * Represents an enumeration of dynamic packages of NMS and CraftBukkit + *

    + * This class is part of the ReflectionUtils and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.0 + */ + public enum PackageType { + MINECRAFT_SERVER("net.minecraft.server." + getServerVersion()), + CRAFTBUKKIT("org.bukkit.craftbukkit." + getServerVersion()), + CRAFTBUKKIT_BLOCK(CRAFTBUKKIT, "block"), + CRAFTBUKKIT_CHUNKIO(CRAFTBUKKIT, "chunkio"), + CRAFTBUKKIT_COMMAND(CRAFTBUKKIT, "command"), + CRAFTBUKKIT_CONVERSATIONS(CRAFTBUKKIT, "conversations"), + CRAFTBUKKIT_ENCHANTMENS(CRAFTBUKKIT, "enchantments"), + CRAFTBUKKIT_ENTITY(CRAFTBUKKIT, "entity"), + CRAFTBUKKIT_EVENT(CRAFTBUKKIT, "event"), + CRAFTBUKKIT_GENERATOR(CRAFTBUKKIT, "generator"), + CRAFTBUKKIT_HELP(CRAFTBUKKIT, "help"), + CRAFTBUKKIT_INVENTORY(CRAFTBUKKIT, "inventory"), + CRAFTBUKKIT_MAP(CRAFTBUKKIT, "map"), + CRAFTBUKKIT_METADATA(CRAFTBUKKIT, "metadata"), + CRAFTBUKKIT_POTION(CRAFTBUKKIT, "potion"), + CRAFTBUKKIT_PROJECTILES(CRAFTBUKKIT, "projectiles"), + CRAFTBUKKIT_SCHEDULER(CRAFTBUKKIT, "scheduler"), + CRAFTBUKKIT_SCOREBOARD(CRAFTBUKKIT, "scoreboard"), + CRAFTBUKKIT_UPDATER(CRAFTBUKKIT, "updater"), + CRAFTBUKKIT_UTIL(CRAFTBUKKIT, "util"); - private final String path; + private final String path; - /** - * Construct a new package type - * - * @param path Path of the package - */ - PackageType(String path) { - this.path = path; - } + /** + * Construct a new package type + * + * @param path Path of the package + */ + PackageType(String path) { + this.path = path; + } - /** - * Construct a new package type - * - * @param parent Parent package of the package - * @param path Path of the package - */ - PackageType(PackageType parent, String path) { - this(parent + "." + path); - } + /** + * Construct a new package type + * + * @param parent Parent package of the package + * @param path Path of the package + */ + PackageType(PackageType parent, String path) { + this(parent + "." + path); + } - /** - * Returns the path of this package type - * - * @return The path - */ - public String getPath() { - return path; - } + /** + * Returns the path of this package type + * + * @return The path + */ + public String getPath() { + return path; + } - /** - * Returns the class with the given name - * - * @param className Name of the desired class - * @return The class with the specified name - * @throws ClassNotFoundException If the desired class with the specified name and package cannot be found - */ - public Class getClass(String className) throws ClassNotFoundException { - return Class.forName(this + "." + className); - } + /** + * Returns the class with the given name + * + * @param className Name of the desired class + * @return The class with the specified name + * @throws ClassNotFoundException If the desired class with the specified name and package cannot be found + */ + public Class getClass(String className) throws ClassNotFoundException { + return Class.forName(this + "." + className); + } - // Override for convenience - @Override - public String toString() { - return path; - } + // Override for convenience + @Override + public String toString() { + return path; + } - /** - * Returns the version of your server - * - * @return The server version - */ - public static String getServerVersion() { - return Bukkit.getServer().getClass().getPackage().getName().substring(23); - } - } + /** + * Returns the version of your server + * + * @return The server version + */ + public static String getServerVersion() { + return Bukkit.getServer().getClass().getPackage().getName().substring(23); + } + } - /** - * Represents an enumeration of Java data types with corresponding classes - *

    - * This class is part of the ReflectionUtils and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.0 - */ - public enum DataType { - BYTE(byte.class, Byte.class), - SHORT(short.class, Short.class), - INTEGER(int.class, Integer.class), - LONG(long.class, Long.class), - CHARACTER(char.class, Character.class), - FLOAT(float.class, Float.class), - DOUBLE(double.class, Double.class), - BOOLEAN(boolean.class, Boolean.class); + /** + * Represents an enumeration of Java data types with corresponding classes + *

    + * This class is part of the ReflectionUtils and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.0 + */ + public enum DataType { + BYTE(byte.class, Byte.class), + SHORT(short.class, Short.class), + INTEGER(int.class, Integer.class), + LONG(long.class, Long.class), + CHARACTER(char.class, Character.class), + FLOAT(float.class, Float.class), + DOUBLE(double.class, Double.class), + BOOLEAN(boolean.class, Boolean.class); - private static final Map, DataType> CLASS_MAP = new HashMap<>(); - private final Class primitive; - private final Class reference; + private static final Map, DataType> CLASS_MAP = new HashMap<>(); + private final Class primitive; + private final Class reference; - // Initialize map for quick class lookup - static { - for (DataType type : values()) { - CLASS_MAP.put(type.primitive, type); - CLASS_MAP.put(type.reference, type); - } - } + // Initialize map for quick class lookup + static { + for (DataType type : values()) { + CLASS_MAP.put(type.primitive, type); + CLASS_MAP.put(type.reference, type); + } + } - /** - * Construct a new data type - * - * @param primitive Primitive class of this data type - * @param reference Reference class of this data type - */ - DataType(Class primitive, Class reference) { - this.primitive = primitive; - this.reference = reference; - } + /** + * Construct a new data type + * + * @param primitive Primitive class of this data type + * @param reference Reference class of this data type + */ + DataType(Class primitive, Class reference) { + this.primitive = primitive; + this.reference = reference; + } - /** - * Returns the primitive class of this data type - * - * @return The primitive class - */ - public Class getPrimitive() { - return primitive; - } + /** + * Returns the primitive class of this data type + * + * @return The primitive class + */ + public Class getPrimitive() { + return primitive; + } - /** - * Returns the reference class of this data type - * - * @return The reference class - */ - public Class getReference() { - return reference; - } + /** + * Returns the reference class of this data type + * + * @return The reference class + */ + public Class getReference() { + return reference; + } - /** - * Returns the data type with the given primitive/reference class - * - * @param clazz Primitive/Reference class of the data type - * @return The data type - */ - public static DataType fromClass(Class clazz) { - return CLASS_MAP.get(clazz); - } + /** + * Returns the data type with the given primitive/reference class + * + * @param clazz Primitive/Reference class of the data type + * @return The data type + */ + public static DataType fromClass(Class clazz) { + return CLASS_MAP.get(clazz); + } - /** - * Returns the primitive class of the data type with the given reference class - * - * @param clazz Reference class of the data type - * @return The primitive class - */ - public static Class getPrimitive(Class clazz) { - DataType type = fromClass(clazz); - return type == null ? clazz : type.getPrimitive(); - } + /** + * Returns the primitive class of the data type with the given reference class + * + * @param clazz Reference class of the data type + * @return The primitive class + */ + public static Class getPrimitive(Class clazz) { + DataType type = fromClass(clazz); + return type == null ? clazz : type.getPrimitive(); + } - /** - * Returns the reference class of the data type with the given primitive class - * - * @param clazz Primitive class of the data type - * @return The reference class - */ - public static Class getReference(Class clazz) { - DataType type = fromClass(clazz); - return type == null ? clazz : type.getReference(); - } + /** + * Returns the reference class of the data type with the given primitive class + * + * @param clazz Primitive class of the data type + * @return The reference class + */ + public static Class getReference(Class clazz) { + DataType type = fromClass(clazz); + return type == null ? clazz : type.getReference(); + } - /** - * Returns the primitive class array of the given class array - * - * @param classes Given class array - * @return The primitive class array - */ - public static Class[] getPrimitive(Class[] classes) { - int length = classes == null ? 0 : classes.length; - Class[] types = new Class[length]; - for (int index = 0; index < length; index++) { - types[index] = getPrimitive(classes[index]); - } - return types; - } + /** + * Returns the primitive class array of the given class array + * + * @param classes Given class array + * @return The primitive class array + */ + public static Class[] getPrimitive(Class[] classes) { + int length = classes == null ? 0 : classes.length; + Class[] types = new Class[length]; + for (int index = 0; index < length; index++) { + types[index] = getPrimitive(classes[index]); + } + return types; + } - /** - * Returns the reference class array of the given class array - * - * @param classes Given class array - * @return The reference class array - */ - public static Class[] getReference(Class[] classes) { - int length = classes == null ? 0 : classes.length; - Class[] types = new Class[length]; - for (int index = 0; index < length; index++) { - types[index] = getReference(classes[index]); - } - return types; - } + /** + * Returns the reference class array of the given class array + * + * @param classes Given class array + * @return The reference class array + */ + public static Class[] getReference(Class[] classes) { + int length = classes == null ? 0 : classes.length; + Class[] types = new Class[length]; + for (int index = 0; index < length; index++) { + types[index] = getReference(classes[index]); + } + return types; + } - /** - * Returns the primitive class array of the given object array - * - * @return The primitive class array - */ - public static Class[] getPrimitive(Object[] objects) { - int length = objects == null ? 0 : objects.length; - Class[] types = new Class[length]; - for (int index = 0; index < length; index++) { - types[index] = getPrimitive(objects[index].getClass()); - } - return types; - } + /** + * Returns the primitive class array of the given object array + * + * @return The primitive class array + */ + public static Class[] getPrimitive(Object[] objects) { + int length = objects == null ? 0 : objects.length; + Class[] types = new Class[length]; + for (int index = 0; index < length; index++) { + types[index] = getPrimitive(objects[index].getClass()); + } + return types; + } - /** - * Returns the reference class array of the given object array - * - * @return The reference class array - */ - public static Class[] getReference(Object[] objects) { - int length = objects == null ? 0 : objects.length; - Class[] types = new Class[length]; - for (int index = 0; index < length; index++) { - types[index] = getReference(objects[index].getClass()); - } - return types; - } + /** + * Returns the reference class array of the given object array + * + * @return The reference class array + */ + public static Class[] getReference(Object[] objects) { + int length = objects == null ? 0 : objects.length; + Class[] types = new Class[length]; + for (int index = 0; index < length; index++) { + types[index] = getReference(objects[index].getClass()); + } + return types; + } - /** - * Compares two class arrays on equivalence - * - * @param primary Primary class array - * @param secondary Class array which is compared to the primary array - * @return Whether these arrays are equal or not - */ - public static boolean compare(Class[] primary, Class[] secondary) { - if (primary == null || secondary == null || primary.length != secondary.length) { - return false; - } - for (int index = 0; index < primary.length; index++) { - Class primaryClass = primary[index]; - Class secondaryClass = secondary[index]; - if (primaryClass.equals(secondaryClass) || primaryClass.isAssignableFrom(secondaryClass)) { - continue; - } - return false; - } - return true; - } - } + /** + * Compares two class arrays on equivalence + * + * @param primary Primary class array + * @param secondary Class array which is compared to the primary array + * @return Whether these arrays are equal or not + */ + public static boolean compare(Class[] primary, Class[] secondary) { + if (primary == null || secondary == null || primary.length != secondary.length) { + return false; + } + for (int index = 0; index < primary.length; index++) { + Class primaryClass = primary[index]; + Class secondaryClass = secondary[index]; + if (primaryClass.equals(secondaryClass) || primaryClass.isAssignableFrom(secondaryClass)) { + continue; + } + return false; + } + return true; + } + } } \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/object/InstanceHandler.java b/src/main/java/me/skymc/taboolib/object/InstantiableLoader.java similarity index 70% rename from src/main/java/me/skymc/taboolib/object/InstanceHandler.java rename to src/main/java/me/skymc/taboolib/object/InstantiableLoader.java index b07d69f..45e7c0d 100644 --- a/src/main/java/me/skymc/taboolib/object/InstanceHandler.java +++ b/src/main/java/me/skymc/taboolib/object/InstantiableLoader.java @@ -1,9 +1,9 @@ package me.skymc.taboolib.object; import com.ilummc.tlib.util.Ref; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.TabooLibLoader; import me.skymc.taboolib.listener.TListener; +import me.skymc.taboolib.methods.ReflectionUtils; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -19,11 +19,11 @@ import java.util.concurrent.ConcurrentHashMap; * @Since 2018-08-27 10:04 */ @TListener -public class InstanceHandler implements Listener { +public class InstantiableLoader implements Listener { private static ConcurrentHashMap instance = new ConcurrentHashMap<>(); - public InstanceHandler() { + public InstantiableLoader() { loadInstantiable(); } @@ -52,19 +52,18 @@ public class InstanceHandler implements Listener { } public static void loadInstantiable(Plugin plugin) { - if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) { - return; - } - for (Class pluginClass : FileUtils.getClasses(plugin)) { - if (pluginClass.isAnnotationPresent(Instantiable.class)) { - Instantiable instantiable = (Instantiable) pluginClass.getAnnotation(Instantiable.class); - try { - instance.put(instantiable.value(), pluginClass.newInstance()); - } catch (Exception e) { - e.printStackTrace(); + TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> { + for (Class pluginClass : classes) { + if (pluginClass.isAnnotationPresent(Instantiable.class)) { + Instantiable instantiable = (Instantiable) pluginClass.getAnnotation(Instantiable.class); + try { + instance.put(instantiable.value(), ReflectionUtils.instantiateObject(pluginClass)); + } catch (Exception e) { + e.printStackTrace(); + } } } - } + }); } // ********************************* diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 41defa2..1ff2780 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -28,6 +28,7 @@ DEPENDENCY: LIBRARY-LOAD-SUCCESS: ' {0} 请求的库文件 {1} 加载成功' LIBRARY-LOAD-FAIL: ' {0} 请求的库文件 {1} 加载失败' LOAD-COMPLETE: '依赖加载完成' + LOAD-CLASSES: '&7缓存 &f{0} &7插件的 &f{1} &7个类耗时&f {2} &7毫秒.' CONFIG: LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解' @@ -112,13 +113,6 @@ LANGUAGE2: TIMECYCLE: FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复' -ANVIL-CONTAINER: - NAME-EXAMPLE: '在这里输入文本' - LORE-NORMAL: - - '' - - '&7在上方文本框内输入信息' - - '&7随后点击右侧输出物品' - UPDATETASK: VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!' VERSION-LATEST: '&7插件已是最新版, 无需更新!'