Taboolib 5.0 fully refactored & Not a plugin now.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class Container {
|
||||
|
||||
private final Object container;
|
||||
private final boolean uniqueId;
|
||||
|
||||
public Container(Object container, boolean uniqueId) {
|
||||
this.container = container;
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
|
||||
public Object getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public boolean isUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
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-14 23:45
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PlayerContainer {
|
||||
|
||||
boolean uniqueId() default false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.logger.TLogger;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-14 23:45
|
||||
*/
|
||||
@TListener
|
||||
public class PlayerContainerLoader implements Listener, TabooLibLoader.Loader {
|
||||
|
||||
static Map<String, List<Container>> pluginContainer = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field field : pluginClass.getDeclaredFields()) {
|
||||
PlayerContainer annotation = field.getAnnotation(PlayerContainer.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
pluginContainer.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(new Container(field.get(pluginClass), annotation.uniqueId()));
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(Plugin plugin, Class<?> cancelClass) {
|
||||
pluginContainer.remove(plugin.getName());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
pluginContainer.values().stream().flatMap(Collection::stream).forEach(container -> {
|
||||
if (container.getContainer() instanceof Map) {
|
||||
((Map) container.getContainer()).remove(container.isUniqueId() ? e.getPlayer().getUniqueId() : e.getPlayer().getName());
|
||||
} else if (container.getContainer() instanceof Collection) {
|
||||
((Collection) container.getContainer()).remove(container.isUniqueId() ? e.getPlayer().getUniqueId() : e.getPlayer().getName());
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error("Invalid Container: " + container.getContainer().getClass().getSimpleName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 14:01
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TFunction {
|
||||
|
||||
String enable() default "onEnable";
|
||||
String disable() default "onDisable";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.logger.TLogger;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 14:00
|
||||
*/
|
||||
public class TFunctionLoader implements TabooLibLoader.Loader {
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
if (pluginClass.isAnnotationPresent(TFunction.class)) {
|
||||
TFunction function = pluginClass.getAnnotation(TFunction.class);
|
||||
try {
|
||||
Method method = pluginClass.getDeclaredMethod(function.enable());
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
return;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
TabooLibAPI.debug("Function " + pluginClass.getSimpleName() + " loaded. (" + plugin.getName() + ")");
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("TFunction load Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(Plugin plugin, Class<?> pluginClass) {
|
||||
if (pluginClass.isAnnotationPresent(TFunction.class)) {
|
||||
TFunction function = pluginClass.getAnnotation(TFunction.class);
|
||||
try {
|
||||
Method method = pluginClass.getDeclaredMethod(function.disable());
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
return;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
TabooLibAPI.debug("Function " + pluginClass.getSimpleName() + " unloaded. (" + plugin.getName() + ")");
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("TFunction unload Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/main/scala/io/izzel/taboolib/module/inject/TInject.java
Normal file
18
src/main/scala/io/izzel/taboolib/module/inject/TInject.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 12:11
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TInject {
|
||||
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.command.lite.SimpleCommandBuilder;
|
||||
import io.izzel.taboolib.module.config.TConfig;
|
||||
import io.izzel.taboolib.module.logger.TLogger;
|
||||
import io.izzel.taboolib.module.packet.TPacketHandler;
|
||||
import io.izzel.taboolib.module.packet.TPacketListener;
|
||||
import io.izzel.taboolib.origin.lite.cooldown.Cooldown;
|
||||
import io.izzel.taboolib.origin.lite.cooldown.Cooldowns;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 13:40
|
||||
*/
|
||||
public class TInjectLoader implements TabooLibLoader.Loader {
|
||||
|
||||
private static Map<Class<?>, TInjectTask> injectTypes = Maps.newLinkedHashMap();
|
||||
|
||||
static {
|
||||
// Instance Inject
|
||||
injectTypes.put(Plugin.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
field.set(instance, plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TLogger Inject
|
||||
injectTypes.put(TLogger.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
field.set(instance, args.length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args[0]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TPacketListener Inject
|
||||
injectTypes.put(TPacketListener.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
TPacketHandler.addListener(plugin, ((TPacketListener) field.get(instance)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TConfiguration Inject
|
||||
injectTypes.put(TConfig.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
field.set(instance, TConfig.create(plugin, args.length == 0 ? "config.yml" : args[0]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// SimpleCommandBuilder Inject
|
||||
injectTypes.put(SimpleCommandBuilder.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
SimpleCommandBuilder builder = (SimpleCommandBuilder) field.get(instance);
|
||||
if (builder.isBuild()) {
|
||||
TLogger.getGlobalLogger().error("Command was registered. (" + field.getType().getName() + ")");
|
||||
} else {
|
||||
if (builder.getPlugin() == null) {
|
||||
builder.plugin(plugin);
|
||||
}
|
||||
builder.build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// CooldownPack Inject
|
||||
injectTypes.put(Cooldown.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
Cooldowns.register((Cooldown) field.get(instance), plugin);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return -999;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field declaredField : pluginClass.getDeclaredFields()) {
|
||||
TInject annotation = declaredField.getAnnotation(TInject.class);
|
||||
// 是否为主类类型
|
||||
if (annotation == null || !declaredField.getType().equals(plugin.getClass())) {
|
||||
continue;
|
||||
}
|
||||
Object instance = null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(declaredField.getModifiers())) {
|
||||
// 是否为主类
|
||||
if (pluginClass.equals(plugin.getClass())) {
|
||||
instance = plugin;
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
inject(plugin, declaredField, instance, annotation, injectTypes.get(Plugin.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field declaredField : pluginClass.getDeclaredFields()) {
|
||||
TInject annotation = declaredField.getAnnotation(TInject.class);
|
||||
if (annotation == null || declaredField.getType().equals(plugin.getClass())) {
|
||||
continue;
|
||||
}
|
||||
Object instance = null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(declaredField.getModifiers())) {
|
||||
// 是否为主类
|
||||
if (pluginClass.equals(plugin.getClass())) {
|
||||
instance = plugin;
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TInjectTask tInjectTask = injectTypes.get(declaredField.getType());
|
||||
if (tInjectTask != null) {
|
||||
inject(plugin, declaredField, instance, annotation, tInjectTask);
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is an invalid inject type. (" + declaredField.getType().getName() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inject(Plugin plugin, Field field, Object instance, TInject annotation, TInjectTask injectTask) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
injectTask.run(plugin, field, annotation.value(), instance);
|
||||
TabooLibAPI.debug(field.getName() + " injected. (" + field.getType().getName() + ")");
|
||||
} catch (Throwable e) {
|
||||
TLogger.getGlobalLogger().error(field.getName() + " inject failed: " + e.getMessage() + " (" + field.getType().getName() + ")");
|
||||
if (e.getMessage() == null) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 13:41
|
||||
*/
|
||||
public interface TInjectTask {
|
||||
|
||||
void run(Plugin plugin, Field field, String[] args, Object instance);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-22 13:41
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TListener {
|
||||
|
||||
/**
|
||||
* 注册时执行的方法名
|
||||
*/
|
||||
String register() default "";
|
||||
|
||||
/**
|
||||
* 注销时执行的方法名
|
||||
*/
|
||||
String cancel() default "";
|
||||
|
||||
/**
|
||||
* 注册时判断的方法名,需返回布尔值
|
||||
*/
|
||||
String condition() default "";
|
||||
|
||||
/**
|
||||
* 注册前判断依赖插件
|
||||
*/
|
||||
String[] depend() default "";
|
||||
|
||||
/**
|
||||
* 注册前判断依赖版本
|
||||
*/
|
||||
String version() default ">0";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.Version;
|
||||
import io.izzel.taboolib.module.logger.TLogger;
|
||||
import io.izzel.taboolib.origin.cronus.util.StringExpression;
|
||||
import io.izzel.taboolib.util.Strings;
|
||||
import io.izzel.taboolib.util.Reflection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-22 13:48
|
||||
*/
|
||||
public class TListenerHandler {
|
||||
|
||||
private static HashMap<String, List<Listener>> listeners = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 初始化所有插件的所有监听器
|
||||
*/
|
||||
public static void setupListeners() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
setupListener(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件的所有监听器
|
||||
* 该操作会执行无参构造方法
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void setupListener(Plugin plugin) {
|
||||
for (Class<?> pluginClass : TabooLibLoader.getPluginClassSafely(plugin)) {
|
||||
if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
|
||||
try {
|
||||
TListener tListener = pluginClass.getAnnotation(TListener.class);
|
||||
// 检查版本
|
||||
if (!new StringExpression(tListener.version()).isSelect(Version.getCurrentVersion().getVersionInt())) {
|
||||
continue;
|
||||
}
|
||||
// 检查注册条件
|
||||
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) Reflection.instantiateObject(pluginClass);
|
||||
try {
|
||||
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
|
||||
TabooLibAPI.debug("Listener " + listener.getClass().getSimpleName() + " setup successfully. (" + plugin.getName() + ")");
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("TListener setup Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TabooLibAPI.debug("Listener " + pluginClass.getSimpleName() + "(" + plugin.getName() + ")" + " setup failed: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册所有插件的所有监听器
|
||||
*/
|
||||
public static void registerListeners() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
registerListener(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件的所有监听器
|
||||
* 该操作会执行 TListener 注解中的 register() 对应方法
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void registerListener(Plugin plugin) {
|
||||
Optional.ofNullable(listeners.get(plugin.getName())).ifPresent(listeners -> {
|
||||
for (Listener listener : listeners) {
|
||||
TListener tListener = listener.getClass().getAnnotation(TListener.class);
|
||||
// 检查注册条件
|
||||
if (!Strings.isBlank(tListener.condition())) {
|
||||
try {
|
||||
Method method = listener.getClass().getDeclaredMethod(tListener.condition());
|
||||
method.setAccessible(true);
|
||||
if (!(boolean) method.invoke(listener)) {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 执行注册方法
|
||||
if (!Strings.isBlank(tListener.register())) {
|
||||
try {
|
||||
Method method = listener.getClass().getDeclaredMethod(tListener.register());
|
||||
method.setAccessible(true);
|
||||
method.invoke(listener);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 注册监听
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin);
|
||||
TabooLibAPI.debug("Listener " + listener.getClass().getSimpleName() + " registered. (" + plugin.getName() + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销所有插件的所有监听器
|
||||
*/
|
||||
public static void cancelListeners() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
cancelListener(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销插件的所有监听器
|
||||
* 该操作会执行 TListener 注解中的 cancel() 对应方法
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void cancelListener(Plugin plugin) {
|
||||
Optional.ofNullable(listeners.remove(plugin.getName())).ifPresent(listeners -> {
|
||||
for (Listener listener : listeners) {
|
||||
HandlerList.unregisterAll(listener);
|
||||
TListener tListener = listener.getClass().getAnnotation(TListener.class);
|
||||
if (!Strings.isBlank(tListener.cancel())) {
|
||||
try {
|
||||
Method method = listener.getClass().getDeclaredMethod(tListener.cancel());
|
||||
method.setAccessible(true);
|
||||
method.invoke(listener);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static HashMap<String, List<Listener>> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:07
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TSchedule {
|
||||
|
||||
int delay() default 0;
|
||||
int period() default -1;
|
||||
|
||||
boolean async() default false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:25
|
||||
*/
|
||||
public class TScheduleData {
|
||||
|
||||
private final TSchedule annotation;
|
||||
private final BukkitRunnable runnable;
|
||||
|
||||
public TScheduleData(TSchedule annotation, BukkitRunnable runnable) {
|
||||
this.annotation = annotation;
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
public TSchedule getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public BukkitRunnable getRunnable() {
|
||||
return runnable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.izzel.taboolib.module.inject;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import io.izzel.taboolib.TabooLib;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.logger.TLogger;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:09
|
||||
*/
|
||||
public class TScheduleLoader implements TabooLibLoader.Loader {
|
||||
|
||||
static Map<String, List<TScheduleData>> schedules = Maps.newHashMap();
|
||||
|
||||
public static void run(Plugin plugin, BukkitRunnable runnable, int delay, int period, boolean async) {
|
||||
if (async) {
|
||||
runnable.runTaskTimerAsynchronously(plugin, delay, period);
|
||||
} else {
|
||||
runnable.runTaskTimer(plugin, delay, period);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> loadClass) {
|
||||
for (Method method : loadClass.getDeclaredMethods()) {
|
||||
TSchedule annotation = method.getAnnotation(TSchedule.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
Object instance = loadClass.equals(plugin.getClass()) ? plugin : null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(method.getModifiers()) && instance == null) {
|
||||
// 是否为主类
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
continue;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
// 如果是本插件
|
||||
if (plugin.equals(TabooLib.getPlugin())) {
|
||||
run(plugin, new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(instance);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, annotation.delay(), annotation.period(), annotation.async());
|
||||
}
|
||||
// 其他插件则添加到列队
|
||||
else {
|
||||
schedules.computeIfAbsent(plugin.getName(), n -> Lists.newArrayList()).add(new TScheduleData(annotation, new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(instance);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user