+ 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
|
* @Author sky
|
||||||
* @Since 2018-08-22 13:41
|
* @Since 2018-08-22 13:41
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.TYPE)
|
@Target({ElementType.TYPE, ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface THook {
|
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.TabooLibAPI;
|
||||||
import io.izzel.taboolib.TabooLibLoader;
|
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 org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author sky
|
* @Author sky
|
||||||
* @Since 2019-08-17 22:32
|
* @Since 2019-08-17 22:32
|
||||||
@ -18,5 +25,29 @@ public class THookLoader implements TabooLibLoader.Loader {
|
|||||||
TabooLibAPI.getPluginBridge().registerExpansion(pluginClass);
|
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 parent;
|
||||||
private Class type;
|
private Class type;
|
||||||
|
@ -2,6 +2,7 @@ package io.izzel.taboolib.module.lite;
|
|||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import io.izzel.taboolib.TabooLibAPI;
|
import io.izzel.taboolib.TabooLibAPI;
|
||||||
|
import io.izzel.taboolib.util.Ref;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
@ -29,12 +30,20 @@ public class SimpleReflection {
|
|||||||
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap()).get(fieldName);
|
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) {
|
public static void checkAndSave(Class<?> nmsClass) {
|
||||||
if (!isExists(nmsClass)) {
|
if (!isExists(nmsClass)) {
|
||||||
saveField(nmsClass);
|
saveField(nmsClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void saveField(Class<?>... nmsClass) {
|
||||||
|
Arrays.stream(nmsClass).forEach(SimpleReflection::saveField);
|
||||||
|
}
|
||||||
|
|
||||||
public static void saveField(Class<?> nmsClass) {
|
public static void saveField(Class<?> nmsClass) {
|
||||||
try {
|
try {
|
||||||
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
|
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) {
|
public static void saveField(Class<?> nmsClass, String fieldName) {
|
||||||
try {
|
try {
|
||||||
Field declaredField = nmsClass.getDeclaredField(fieldName);
|
Field declaredField = nmsClass.getDeclaredField(fieldName);
|
||||||
declaredField.setAccessible(true);
|
Ref.forcedAccess(declaredField);
|
||||||
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
|
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean onSend(Player player, Packet packet) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean onReceive(Player player, Object packet) {
|
public boolean onReceive(Player player, Object packet) {
|
||||||
return true;
|
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;
|
package io.izzel.taboolib.module.packet.channel;
|
||||||
|
|
||||||
|
import io.izzel.taboolib.module.packet.Packet;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelDuplexHandler;
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@ -50,7 +51,7 @@ public abstract class ChannelExecutor {
|
|||||||
@Override
|
@Override
|
||||||
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
|
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
|
||||||
try {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -62,7 +63,7 @@ public abstract class ChannelExecutor {
|
|||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
|
public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
|
||||||
try {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user