+ fix tlocale

+ fix tinject
+ fix tschedule
+ update ref
This commit is contained in:
坏黑 2019-11-04 15:56:04 +08:00
parent 1e55b6be29
commit 7154cdfe65
14 changed files with 216 additions and 113 deletions

View File

@ -6,7 +6,7 @@ plugins {
} }
group = 'me.skymc' group = 'me.skymc'
version = '5.1' version = '5.11'
sourceCompatibility = 1.8 sourceCompatibility = 1.8
targetCompatibility = 1.8 targetCompatibility = 1.8

View File

@ -12,13 +12,6 @@ MISC:
FIELD-COPY-FAILED: '拷贝 {0} 对象失败' FIELD-COPY-FAILED: '拷贝 {0} 对象失败'
FIELD-COPY-ERROR: '拷贝 {0} 对象出错:{1}' FIELD-COPY-ERROR: '拷贝 {0} 对象出错:{1}'
ITEM-UTILS:
FAIL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
FAIL-LOAD-ENCHANT: '&c{0} &4不是一个有效的附魔名称, 输入 &c/tlib enchants&4 查看所有附魔'
FAIL-LOAD-POTION: '&c{0} &4不是一个有效的药水名称, 输入 &c/tlib potions&4 查看所有药水'
FAIL-LOAD-FLAG: '&c{0} &4不是一个有效的标签名称, 输入 &c/tlib flags&4 查看所有标签'
FAIL-SAVE-EXISTS: '无法载入载入物品 &4{0}&c, 因为它已经存在了'
MYSQL-HIKARI: MYSQL-HIKARI:
CREATE-SUCCESS: '&7插件 &f{0} &7注册新的连接池: &f{1}' CREATE-SUCCESS: '&7插件 &f{0} &7注册新的连接池: &f{1}'
CREATE-EXISTS: '&7插件 &f{0} &7引用插件 &f{1} &7注册的连接池.' CREATE-EXISTS: '&7插件 &f{0} &7引用插件 &f{1} &7注册的连接池.'

View File

@ -5,7 +5,6 @@ import io.izzel.taboolib.module.config.TConfig;
import io.izzel.taboolib.module.config.TConfigWatcher; import io.izzel.taboolib.module.config.TConfigWatcher;
import io.izzel.taboolib.module.db.local.Local; import io.izzel.taboolib.module.db.local.Local;
import io.izzel.taboolib.module.db.local.LocalPlayer; import io.izzel.taboolib.module.db.local.LocalPlayer;
import io.izzel.taboolib.module.db.source.DBSource;
import io.izzel.taboolib.module.dependency.Dependency; import io.izzel.taboolib.module.dependency.Dependency;
import io.izzel.taboolib.module.locale.TLocaleLoader; import io.izzel.taboolib.module.locale.TLocaleLoader;
import io.izzel.taboolib.module.locale.logger.TLogger; import io.izzel.taboolib.module.locale.logger.TLogger;
@ -82,8 +81,6 @@ public class TabooLib {
LocalPlayer.saveFiles(); LocalPlayer.saveFiles();
// 关闭文件监听 // 关闭文件监听
TConfigWatcher.getInst().unregisterAll(); TConfigWatcher.getInst().unregisterAll();
// 关闭连接池
DBSource.closeDataSourceForce();
// 关闭插件 // 关闭插件
PluginLoader.stop(getPlugin()); PluginLoader.stop(getPlugin());
}); });

View File

@ -16,8 +16,7 @@ public class CompatKotlin {
public static Object getCompanion(Class<?> pluginClass) { public static Object getCompanion(Class<?> pluginClass) {
try { try {
return Reflection.getValue(null, TabooLibAPI.getPluginBridge().getClass(pluginClass.getName().substring(0, pluginClass.getName().indexOf("$Companion"))), true, "Companion"); return Reflection.getValue(null, TabooLibAPI.getPluginBridge().getClass(pluginClass.getName().substring(0, pluginClass.getName().indexOf("$Companion"))), true, "Companion");
} catch (Throwable t) { } catch (Throwable ignored) {
t.printStackTrace();
} }
return null; return null;
} }

View File

@ -52,7 +52,7 @@ public class TInjectHelper {
} }
} }
// Nothing // Nothing
else if (instance.isEmpty()) { if (instance.isEmpty()) {
TLogger.getGlobalLogger().error(field.getName() + " is not a static field. (" + pluginClass.getName() + ")"); TLogger.getGlobalLogger().error(field.getName() + " is not a static field. (" + pluginClass.getName() + ")");
} }
return instance; return instance;
@ -60,22 +60,22 @@ public class TInjectHelper {
public static List<Object> getInstance(Method method, Class<?> pluginClass, Plugin plugin) { public static List<Object> getInstance(Method method, Class<?> pluginClass, Plugin plugin) {
List<Object> instance = Lists.newArrayList(); List<Object> instance = Lists.newArrayList();
// Object
if (CompatKotlin.getInstance(pluginClass) != null) {
instance.add(CompatKotlin.getInstance(pluginClass));
}
// Companion Object
else if (CompatKotlin.isCompanion(pluginClass)) {
instance.add(CompatKotlin.getCompanion(pluginClass));
}
// Static // Static
else if (Modifier.isStatic(method.getModifiers())) { if (Modifier.isStatic(method.getModifiers())) {
instance.add(null); instance.add(null);
} }
// No Static // No Static
else if (!Modifier.isStatic(method.getModifiers())) { else if (!Modifier.isStatic(method.getModifiers())) {
// Object
if (CompatKotlin.getInstance(pluginClass) != null) {
instance.add(CompatKotlin.getInstance(pluginClass));
}
// Companion Object
else if (CompatKotlin.isCompanion(pluginClass)) {
instance.add(CompatKotlin.getCompanion(pluginClass));
}
// Main // Main
if (pluginClass.equals(plugin.getClass())) { else if (pluginClass.equals(plugin.getClass())) {
instance.add(plugin); instance.add(plugin);
} }
// TInject // TInject
@ -84,7 +84,7 @@ public class TInjectHelper {
} }
} }
// Nothing // Nothing
else if (instance.isEmpty()) { if (instance.isEmpty()) {
TLogger.getGlobalLogger().error(method.getName() + " is not a static method. (" + pluginClass.getName() + ")"); TLogger.getGlobalLogger().error(method.getName() + " is not a static method. (" + pluginClass.getName() + ")");
} }
return instance; return instance;

View File

@ -16,7 +16,6 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
/** /**
@ -59,17 +58,19 @@ public class TInjectLoader implements TabooLibLoader.Loader {
field.set(instance, config); field.set(instance, config);
if (!args.reload().isEmpty()) { if (!args.reload().isEmpty()) {
try { try {
Method declaredMethod = pluginClass.getDeclaredMethod(args.reload()); Ref.getDeclaredMethods(pluginClass).forEach(method -> {
declaredMethod.setAccessible(true); if (method.getName().equals(args.reload())) {
config.listener(() -> { method.setAccessible(true);
try { config.listener(() -> {
declaredMethod.invoke(instance); try {
} catch (Throwable t) { method.invoke(instance);
t.printStackTrace(); } catch (Throwable t) {
t.printStackTrace();
}
});
TabooLibLoader.runTask(config::runListener);
} }
}); });
TabooLibLoader.runTask(config::runListener);
} catch (NoSuchMethodException ignore) {
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }

View File

@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.izzel.taboolib.TabooLib; import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.TabooLibLoader; import io.izzel.taboolib.TabooLibLoader;
import io.izzel.taboolib.util.Ref;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -63,7 +64,12 @@ public class TScheduleLoader implements TabooLibLoader.Loader {
try { try {
method.invoke(instance); method.invoke(instance);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); try {
method.invoke(Ref.UNSAFE.allocateInstance(pluginClass));
} catch (Throwable t2) {
t.printStackTrace();
t2.printStackTrace();
}
} }
} }
}))); })));

View File

@ -15,6 +15,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -32,80 +33,88 @@ public class TLocale {
return Arrays.stream(obj).map(String::valueOf).toArray(String[]::new); return Arrays.stream(obj).map(String::valueOf).toArray(String[]::new);
} }
static void sendTo(String path, CommandSender sender, String[] args, Class<?> callerClass) { static void sendTo0(Collection<? extends CommandSender> sender, String path, String... args) {
TLocaleLoader.sendTo(Ref.getCallerPlugin(callerClass), path, sender, args); sender.forEach(i -> TLocaleLoader.sendTo(Ref.getCallerPlugin(), path, i, args));
} }
static String asString(String path, Class<?> callerClass, String... args) { static String asString0(String path, String... args) {
return TLocaleLoader.asString(Ref.getCallerPlugin(callerClass), path, args); try {
return TLocaleLoader.asString(Ref.getCallerPlugin(), path, args);
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return "§4Error: " + path;
}
} }
static List<String> asStringList(String path, Class<?> callerClass, String... args) { static List<String> asStringList0(String path, String... args) {
return TLocaleLoader.asStringList(Ref.getCallerPlugin(callerClass), path, args); try {
return TLocaleLoader.asStringList(Ref.getCallerPlugin(), path, args);
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return Collections.singletonList("§4Error: " + path);
}
} }
public static void sendTo(CommandSender sender, String path, Object... args) { public static void sendTo(CommandSender sender, String path, Object... args) {
Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, toArray(args), clazz)); sendTo0(Collections.singletonList(sender), path, toArray(args));
} }
public static void sendTo(CommandSender sender, String path, String... args) { public static void sendTo(CommandSender sender, String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); sendTo0(Collections.singletonList(sender), path, args);
}
public static void sendTo(CommandSender sender, String path) {
sendTo0(Collections.singletonList(sender), path);
} }
public static void sendToConsole(String path, Object... args) { public static void sendToConsole(String path, Object... args) {
Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), toArray(args), clazz)); sendTo0(Collections.singletonList(Bukkit.getConsoleSender()), path, toArray(args));
} }
public static void sendToConsole(String path, String... args) { public static void sendToConsole(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), args, clazz)); sendTo0(Collections.singletonList(Bukkit.getConsoleSender()), path, args);
}
public static void sendToConsole(String path) {
sendTo0(Collections.singletonList(Bukkit.getConsoleSender()), path);
} }
public static void broadcast(String path, Object... args) { public static void broadcast(String path, Object... args) {
Ref.getCallerClass(3).ifPresent(clazz -> Bukkit.getOnlinePlayers().forEach(player -> sendTo(path, player, toArray(args), clazz))); sendTo0(Bukkit.getOnlinePlayers(), path, toArray(args));
} }
public static void broadcast(String path, String... args) { public static void broadcast(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> Bukkit.getOnlinePlayers().forEach(player -> sendTo(path, player, args, clazz))); sendTo0(Bukkit.getOnlinePlayers(), path, args);
}
public static void broadcast(String path) {
sendTo0(Bukkit.getOnlinePlayers(), path);
} }
public static String asString(String path, Object... args) { public static String asString(String path, Object... args) {
try { return asString0(path, toArray(args));
return asString(path, Ref.getCallerClass(3).orElse(TabooLib.class), toArray(args));
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return "§4<" + path + "§4>";
}
} }
public static String asString(String path, String... args) { public static String asString(String path, String... args) {
try { return asString0(path, args);
return asString(path, Ref.getCallerClass(3).orElse(TabooLib.class), args); }
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path)); public static String asString(String path) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage())); return asString0(path);
return "§4<" + path + "§4>";
}
} }
public static List<String> asStringList(String path, Object... args) { public static List<String> asStringList(String path, Object... args) {
try { return asStringList0(path, toArray(args));
return asStringList(path, Ref.getCallerClass(3).orElse(TabooLib.class), toArray(args));
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return Collections.singletonList("§4<" + path + "§4>");
}
} }
public static List<String> asStringList(String path, String... args) { public static List<String> asStringList(String path, String... args) {
try { return asStringList0(path, args);
return asStringList(path, Ref.getCallerClass(3).orElse(TabooLib.class), args); }
} catch (Exception e) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path)); public static List<String> asStringList(String path) {
TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage())); return asStringList0(path);
return Collections.singletonList("§4<" + path + "§4>");
}
} }
public static void reload() { public static void reload() {
@ -176,31 +185,31 @@ public class TLocale {
public static final class Logger extends TLocale { public static final class Logger extends TLocale {
public static void info(String path, String... args) { public static void info(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).info(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).info(locale));
} }
public static void warn(String path, String... args) { public static void warn(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).warn(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).warn(locale));
} }
public static void error(String path, String... args) { public static void error(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).error(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).error(locale));
} }
public static void fatal(String path, String... args) { public static void fatal(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).fatal(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).fatal(locale));
} }
public static void fine(String path, String... args) { public static void fine(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).fine(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).fine(locale));
} }
public static void finest(String path, String... args) { public static void finest(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).finest(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).finest(locale));
} }
public static void verbose(String path, String... args) { public static void verbose(String path, String... args) {
Ref.getCallerClass(3).ifPresent(clazz -> asStringList(path, clazz, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin(clazz)).verbose(locale))); asStringList(path, args).forEach(locale -> TLoggerManager.getLogger(Ref.getCallerPlugin()).verbose(locale));
} }
} }
} }

View File

@ -51,7 +51,7 @@ class TLocaleInstance {
public void sendTo(String path, CommandSender sender, String... args) { public void sendTo(String path, CommandSender sender, String... args) {
try { try {
map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).forEach(tSender -> { map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(plugin, path))).forEach(tSender -> {
if (Bukkit.isPrimaryThread() || Objects.equals(System.getProperty("tlib.forceAsync"), "true")) { if (Bukkit.isPrimaryThread() || Objects.equals(System.getProperty("tlib.forceAsync"), "true")) {
tSender.sendTo(sender, args); tSender.sendTo(sender, args);
} else { } else {
@ -65,11 +65,11 @@ class TLocaleInstance {
} }
public String asString(String path, String... args) { public String asString(String path, String... args) {
return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asString(args); return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(plugin, path))).get(0).asString(args);
} }
public List<String> asStringList(String path, String... args) { public List<String> asStringList(String path, String... args) {
return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(path))).get(0).asStringList(args); return map.getOrDefault(path, ImmutableList.of(TLocaleSerialize.getEmpty(plugin, path))).get(0).asStringList(args);
} }
private static boolean isListString(List list) { private static boolean isListString(List list) {

View File

@ -1,7 +1,10 @@
package io.izzel.taboolib.module.locale; package io.izzel.taboolib.module.locale;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.TabooLibAPI;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.plugin.Plugin;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -47,7 +50,7 @@ public abstract class TLocaleSerialize implements TLocaleSender, ConfigurationSe
}; };
} }
static TLocaleSerialize getEmpty(String path) { static TLocaleSerialize getEmpty(Plugin plugin, String path) {
return new TLocaleSerialize() { return new TLocaleSerialize() {
@Override @Override
@ -57,17 +60,29 @@ public abstract class TLocaleSerialize implements TLocaleSender, ConfigurationSe
@Override @Override
public void sendTo(CommandSender sender, String... args) { public void sendTo(CommandSender sender, String... args) {
sender.sendMessage("§8<" + path + "§8>"); if (TabooLibAPI.isDependTabooLib(plugin)) {
TLocaleLoader.sendTo(TabooLib.getPlugin(), path, sender, args);
} else {
sender.sendMessage("§8Notfound: " + path);
}
} }
@Override @Override
public String asString(String... args) { public String asString(String... args) {
return "§8<" + path + "§8>"; if (TabooLibAPI.isDependTabooLib(plugin)) {
return TLocaleLoader.asString(TabooLib.getPlugin(), path, args);
} else {
return "§8Notfound: " + path;
}
} }
@Override @Override
public List<String> asStringList(String... args) { public List<String> asStringList(String... args) {
return Collections.singletonList("§4<" + path + "§4>"); if (TabooLibAPI.isDependTabooLib(plugin)) {
return TLocaleLoader.asStringList(TabooLib.getPlugin(), path, args);
} else {
return Collections.singletonList("§8Notfound: " + path);
}
} }
}; };
} }

View File

@ -33,11 +33,11 @@ public class TLogger {
} }
public static TLogger getUnformatted(Plugin plugin) { public static TLogger getUnformatted(Plugin plugin) {
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.FINE); return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.VERBOSE);
} }
public static TLogger getUnformatted(String name) { public static TLogger getUnformatted(String name) {
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.FINE); return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.VERBOSE);
} }
public String getPattern() { public String getPattern() {

View File

@ -2,23 +2,14 @@ package io.izzel.taboolib.module.locale.logger;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class TLoggerManager { public class TLoggerManager {
private static final Map<Plugin, TLogger> map = new HashMap<>(); private static final Map<String, TLogger> map = new ConcurrentHashMap<>();
public static void setDefaultLogger(Plugin plugin, TLogger logger) {
map.put(plugin, logger);
}
public static TLogger getLogger(Plugin plugin) { public static TLogger getLogger(Plugin plugin) {
TLogger logger = map.get(plugin); return map.computeIfAbsent(plugin.getName(), n -> TLogger.getUnformatted(plugin));
if (logger == null) {
logger = TLogger.getUnformatted(plugin);
map.put(plugin, logger);
}
return logger;
} }
} }

View File

@ -2,15 +2,18 @@ package io.izzel.taboolib.util;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import io.izzel.taboolib.TabooLib; import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.TabooLibAPI;
import io.izzel.taboolib.util.asm.AsmAnalyser; import io.izzel.taboolib.util.asm.AsmAnalyser;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import sun.misc.Unsafe;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -20,9 +23,21 @@ import java.util.stream.Collectors;
public class Ref { public class Ref {
private static final Map<String, List<Field>> cachedFields = new ConcurrentHashMap<>(); private static final Map<String, List<Field>> cachedFields = new ConcurrentHashMap<>();
private static final Map<String, List<Method>> cacheMethods = new ConcurrentHashMap<>();
private static final Map<String, Plugin> cachePlugin = new ConcurrentHashMap<>();
public static final int ACC_BRIDGE = 0x0040; public static final int ACC_BRIDGE = 0x0040;
public static final int ACC_SYNTHETIC = 0x1000; public static final int ACC_SYNTHETIC = 0x1000;
public static final Unsafe UNSAFE = getUnsafe();
static Unsafe getUnsafe() {
try {
return (Unsafe) io.izzel.taboolib.util.Reflection.getValue(null, Unsafe.class, true, "theUnsafe");
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static List<Field> getDeclaredFields(Class<?> clazz) { public static List<Field> getDeclaredFields(Class<?> clazz) {
return getDeclaredFields(clazz, 0, true); return getDeclaredFields(clazz, 0, true);
@ -68,6 +83,50 @@ public class Ref {
} }
} }
public static List<Method> getDeclaredMethods(Class<?> clazz) {
return getDeclaredMethods(clazz, 0, true);
}
public static List<Method> getDeclaredMethods(String clazz, int excludeModifiers, boolean cache) {
try {
return getDeclaredMethods(Class.forName(clazz), excludeModifiers, cache);
} catch (ClassNotFoundException e) {
return Collections.emptyList();
}
}
public static List<Method> getDeclaredMethods(Class<?> clazz, int excludeModifiers, boolean cache) {
try {
List<Method> methods;
if ((methods = cacheMethods.get(clazz.getName())) != null) {
return methods;
}
ClassReader classReader = new ClassReader(clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class"));
AsmAnalyser analyser = new AsmAnalyser(new ClassWriter(ClassWriter.COMPUTE_MAXS), excludeModifiers);
classReader.accept(analyser, ClassReader.SKIP_DEBUG);
methods = analyser.getMethods().stream().map(name -> {
try {
return clazz.getDeclaredMethod(name);
} catch (Throwable ignored) {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
if (cache) {
cacheMethods.putIfAbsent(clazz.getName(), methods);
}
return methods;
} catch (Exception | Error e) {
try {
List<Method> list = Arrays.stream(clazz.getDeclaredMethods())
.filter(field -> (field.getModifiers() & excludeModifiers) == 0).collect(Collectors.toList());
cacheMethods.putIfAbsent(clazz.getName(), list);
return list;
} catch (Error err) {
return Collections.emptyList();
}
}
}
public static Optional<Class<?>> getCallerClass(int depth) { public static Optional<Class<?>> getCallerClass(int depth) {
return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1)); return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1));
} }
@ -93,23 +152,43 @@ public class Ref {
return Optional.empty(); return Optional.empty();
} }
public static Plugin getCallerPlugin() {
return getCallerPlugin(getCallerClass());
}
public static Plugin getCallerPlugin(Class<?> callerClass) { public static Plugin getCallerPlugin(Class<?> callerClass) {
if (callerClass.getName().startsWith("io.izzel.taboolib") || callerClass.getName().startsWith("io.izzel.tlibscala")) { if (callerClass.getName().startsWith("io.izzel.taboolib") || callerClass.getName().startsWith("io.izzel.tlibscala")) {
return TabooLib.getPlugin(); return TabooLib.getPlugin();
} }
try { try {
return JavaPlugin.getProvidingPlugin(callerClass); return cachePlugin.computeIfAbsent(callerClass.getName(), n -> JavaPlugin.getProvidingPlugin(callerClass));
} catch (Exception ignored) { } catch (Exception ignored) {
return cachePlugin.computeIfAbsent(callerClass.getName(), n -> {
try {
ClassLoader loader = callerClass.getClassLoader();
Field pluginF = loader.getClass().getDeclaredField("plugin");
pluginF.setAccessible(true);
Object o = pluginF.get(loader);
return (JavaPlugin) o;
} catch (Exception e) {
return TabooLib.getPlugin();
}
});
}
}
public static Class<?> getCallerClass() {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : elements) {
try { try {
ClassLoader loader = callerClass.getClassLoader(); Class<?> clazz = TabooLibAPI.getPluginBridge().getClass(element.getClassName());
Field pluginF = loader.getClass().getDeclaredField("plugin"); if (TabooLibAPI.isDependTabooLib(getCallerPlugin(clazz))) {
pluginF.setAccessible(true); return clazz;
Object o = pluginF.get(loader); }
return (JavaPlugin) o; } catch (Throwable ignored) {
} catch (Exception e) {
return TabooLib.getPlugin();
} }
} }
return TabooLib.class;
} }
public static void forcedAccess(Field field) { public static void forcedAccess(Field field) {
@ -160,5 +239,4 @@ public class Ref {
} }
} }
} }
} }

View File

@ -2,6 +2,7 @@ package io.izzel.taboolib.util.asm;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
@ -10,6 +11,7 @@ import java.util.List;
public class AsmAnalyser extends ClassVisitor implements Opcodes { public class AsmAnalyser extends ClassVisitor implements Opcodes {
private final List<String> fields = new ArrayList<>(); private final List<String> fields = new ArrayList<>();
private final List<String> methods = new ArrayList<>();
private final int excludeModifier; private final int excludeModifier;
@ -26,7 +28,19 @@ public class AsmAnalyser extends ClassVisitor implements Opcodes {
return super.visitField(access, name, descriptor, signature, value); return super.visitField(access, name, descriptor, signature, value);
} }
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if ((access & excludeModifier) == 0) {
methods.add(name);
}
return super.visitMethod(access, name, descriptor, signature, exceptions);
}
public List<String> getFields() { public List<String> getFields() {
return fields; return fields;
} }
public List<String> getMethods() {
return methods;
}
} }