+ update packet api
+ update reflect api
This commit is contained in:
parent
fe0efbf297
commit
e3daaf0162
@ -9,7 +9,9 @@ import java.lang.annotation.Target;
|
||||
* @Author sky
|
||||
* @Since 2018-08-22 13:41
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Target({ElementType.TYPE, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface THook {
|
||||
|
||||
String plugin() default "";
|
||||
}
|
@ -2,8 +2,15 @@ package io.izzel.taboolib.module.inject;
|
||||
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.locale.logger.TLogger;
|
||||
import io.izzel.taboolib.util.Ref;
|
||||
import io.izzel.taboolib.util.Strings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2019-08-17 22:32
|
||||
@ -18,5 +25,29 @@ public class THookLoader implements TabooLibLoader.Loader {
|
||||
TabooLibAPI.getPluginBridge().registerExpansion(pluginClass);
|
||||
}
|
||||
}
|
||||
for (Field declaredField : pluginClass.getDeclaredFields()) {
|
||||
if (Plugin.class.isAssignableFrom(declaredField.getType()) && declaredField.isAnnotationPresent(THook.class)) {
|
||||
THook hook = declaredField.getAnnotation(THook.class);
|
||||
if (Strings.nonEmpty(hook.plugin())) {
|
||||
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. (" + pluginClass.getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ref.forcedAccess(declaredField);
|
||||
try {
|
||||
declaredField.set(instance, Bukkit.getPluginManager().getPlugin(hook.plugin()));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public class TInjectCreator implements TabooLibLoader.Loader {
|
||||
/**
|
||||
* 用于防止多个类使用同一个类型
|
||||
*/
|
||||
public class ClassData {
|
||||
public static class ClassData {
|
||||
|
||||
private Class parent;
|
||||
private Class type;
|
||||
|
@ -2,6 +2,7 @@ package io.izzel.taboolib.module.lite;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.util.Ref;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@ -29,12 +30,20 @@ public class SimpleReflection {
|
||||
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap()).get(fieldName);
|
||||
}
|
||||
|
||||
public static void checkAndSave(Class<?>... nmsClass) {
|
||||
Arrays.stream(nmsClass).forEach(SimpleReflection::checkAndSave);
|
||||
}
|
||||
|
||||
public static void checkAndSave(Class<?> nmsClass) {
|
||||
if (!isExists(nmsClass)) {
|
||||
saveField(nmsClass);
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveField(Class<?>... nmsClass) {
|
||||
Arrays.stream(nmsClass).forEach(SimpleReflection::saveField);
|
||||
}
|
||||
|
||||
public static void saveField(Class<?> nmsClass) {
|
||||
try {
|
||||
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
|
||||
@ -46,7 +55,7 @@ public class SimpleReflection {
|
||||
public static void saveField(Class<?> nmsClass, String fieldName) {
|
||||
try {
|
||||
Field declaredField = nmsClass.getDeclaredField(fieldName);
|
||||
declaredField.setAccessible(true);
|
||||
Ref.forcedAccess(declaredField);
|
||||
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
58
src/main/scala/io/izzel/taboolib/module/packet/Packet.java
Normal file
58
src/main/scala/io/izzel/taboolib/module/packet/Packet.java
Normal file
@ -0,0 +1,58 @@
|
||||
package io.izzel.taboolib.module.packet;
|
||||
|
||||
import io.izzel.taboolib.module.lite.SimpleReflection;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2019-10-25 22:52
|
||||
*/
|
||||
public class Packet {
|
||||
|
||||
private Object origin;
|
||||
private Class<?> packetClass;
|
||||
|
||||
public Packet(Object origin) {
|
||||
this.origin = origin;
|
||||
this.packetClass = origin.getClass();
|
||||
SimpleReflection.checkAndSave(this.packetClass);
|
||||
}
|
||||
|
||||
public boolean is(Class<?> packetClass) {
|
||||
return this.packetClass.equals(packetClass);
|
||||
}
|
||||
|
||||
public boolean is(String packetName) {
|
||||
return this.packetClass.getSimpleName().equalsIgnoreCase(packetName);
|
||||
}
|
||||
|
||||
public boolean any(Class<?>... packetClass) {
|
||||
return Arrays.stream(packetClass).anyMatch(this::is);
|
||||
}
|
||||
|
||||
public boolean any(String... packetClass) {
|
||||
return Arrays.stream(packetClass).anyMatch(this::is);
|
||||
}
|
||||
|
||||
public Object read(String key) {
|
||||
return SimpleReflection.getFieldValue(this.packetClass, origin, key);
|
||||
}
|
||||
|
||||
public <T> T read(String key, T def) {
|
||||
return SimpleReflection.getFieldValue(this.packetClass, origin, key, def);
|
||||
}
|
||||
|
||||
public <T> T read(String key, Class<? extends T> type) {
|
||||
Object value = SimpleReflection.getFieldValue(this.packetClass, origin, key);
|
||||
return value == null ? null : (T) value;
|
||||
}
|
||||
|
||||
public void write(String key, Object value) {
|
||||
SimpleReflection.setFieldValue(this.packetClass, origin, key, value);
|
||||
}
|
||||
|
||||
public Object get() {
|
||||
return origin;
|
||||
}
|
||||
}
|
22
src/main/scala/io/izzel/taboolib/module/packet/TPacket.java
Normal file
22
src/main/scala/io/izzel/taboolib/module/packet/TPacket.java
Normal file
@ -0,0 +1,22 @@
|
||||
package io.izzel.taboolib.module.packet;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-14 23:45
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TPacket {
|
||||
|
||||
Type type();
|
||||
|
||||
enum Type {
|
||||
|
||||
SEND, RECEIVE
|
||||
}
|
||||
}
|
@ -12,8 +12,15 @@ public abstract class TPacketListener {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onSend(Player player, Packet packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onReceive(Player player, Object packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onReceive(Player player, Packet packet) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
package io.izzel.taboolib.module.packet;
|
||||
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.module.locale.logger.TLogger;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2019-10-25 22:50
|
||||
*/
|
||||
public class TPacketLoader implements TabooLibLoader.Loader {
|
||||
|
||||
@Override
|
||||
public void activeLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Method method : pluginClass.getDeclaredMethods()) {
|
||||
if (method.isAnnotationPresent(TPacket.class)) {
|
||||
Object instance = null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
// 是否为主类
|
||||
if (pluginClass.equals(plugin.getClass())) {
|
||||
instance = plugin;
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method. (" + pluginClass.getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
method.setAccessible(true);
|
||||
TPacket packet = method.getAnnotation(TPacket.class);
|
||||
boolean packetType = method.getReturnType().equals(Boolean.TYPE) || method.getReturnType().equals(Boolean.class);
|
||||
// object type
|
||||
if (Arrays.equals(method.getParameterTypes(), new Class[] {Player.class, Object.class})) {
|
||||
Object finalInstance = instance;
|
||||
TPacketHandler.addListener(plugin, new TPacketListener() {
|
||||
@Override
|
||||
public boolean onSend(Player player, Object p) {
|
||||
return eval(finalInstance, packet, TPacket.Type.SEND, packetType, method, player, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onReceive(Player player, Object p) {
|
||||
return eval(finalInstance, packet, TPacket.Type.RECEIVE, packetType, method, player, p);
|
||||
}
|
||||
});
|
||||
}
|
||||
// packet type
|
||||
else if (Arrays.equals(method.getParameterTypes(), new Class[] {Player.class, Packet.class})) {
|
||||
Object finalInstance1 = instance;
|
||||
TPacketHandler.addListener(plugin, new TPacketListener() {
|
||||
@Override
|
||||
public boolean onSend(Player player, Packet p) {
|
||||
return eval(finalInstance1, packet, TPacket.Type.SEND, packetType, method, player, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onReceive(Player player, Packet p) {
|
||||
return eval(finalInstance1, packet, TPacket.Type.RECEIVE, packetType, method, player, p);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is an invalid packet listener. (" + pluginClass.getName() + ")");
|
||||
TLogger.getGlobalLogger().error("Usage: boolean fun(Player player, Object packet) { ... }");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean eval(Object instance, TPacket packet, TPacket.Type type, boolean packetType, Method method, Player player, Object obj) {
|
||||
if (packet.type() == type) {
|
||||
try {
|
||||
return !packetType || (boolean) method.invoke(instance, player, obj);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package io.izzel.taboolib.module.packet.channel;
|
||||
|
||||
import io.izzel.taboolib.module.packet.Packet;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -50,7 +51,7 @@ public abstract class ChannelExecutor {
|
||||
@Override
|
||||
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
|
||||
try {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onSend(player, o))) {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onSend(player, o) || !packetListener.onSend(player, new Packet(o)))) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -62,7 +63,7 @@ public abstract class ChannelExecutor {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
|
||||
try {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onReceive(player, o))) {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onReceive(player, o) || !packetListener.onReceive(player, new Packet(o)))) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
Loading…
Reference in New Issue
Block a user