1.2
This commit is contained in:
parent
9101db3075
commit
9b37d2a330
|
@ -3,7 +3,10 @@ package com.io.yutian.elementoriginlib.util;
|
|||
import org.bukkit.Bukkit;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
@ -178,4 +181,138 @@ public class ReflectionUtil {
|
|||
}
|
||||
}
|
||||
|
||||
private static Field MODIFIERS_FIELD;
|
||||
private static Object UNSAFE;
|
||||
private static MethodHandle UNSAFE_FIELD_OFFSET;
|
||||
private static MethodHandle UNSAFE_PUT_BOOLEAN;
|
||||
private static MethodHandle UNSAFE_PUT_DOUBLE;
|
||||
private static MethodHandle UNSAFE_PUT_FLOAT;
|
||||
private static MethodHandle UNSAFE_PUT_INT;
|
||||
private static MethodHandle UNSAFE_PUT_LONG;
|
||||
private static MethodHandle UNSAFE_PUT_OBJECT;
|
||||
private static MethodHandle UNSAFE_STATIC_FIELD_OFFSET;
|
||||
|
||||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
public static MethodHandle getFieldGetter(Class<?> clazz, String name) {
|
||||
return getField(clazz, name, true);
|
||||
}
|
||||
|
||||
public static MethodHandle getFieldSetter(Class<?> clazz, String name) {
|
||||
return getField(clazz, name, false);
|
||||
}
|
||||
|
||||
public static MethodHandle getField(Class<?> clazz, String name, boolean isGetter) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
|
||||
if (isGetter) return LOOKUP.unreflectGetter(field);
|
||||
return LOOKUP.unreflectSetter(field);
|
||||
} catch (ReflectiveOperationException exception) {
|
||||
exception.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> clazz, String field) {
|
||||
if (clazz == null)
|
||||
return null;
|
||||
Field f = null;
|
||||
try {
|
||||
f = clazz.getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String method, Class<?>... params) {
|
||||
if (clazz == null)
|
||||
return null;
|
||||
Method f = null;
|
||||
try {
|
||||
f = clazz.getDeclaredMethod(method, params);
|
||||
f.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
public static MethodHandle getMethodHandle(Class<?> clazz, String method, Class<?>... params) {
|
||||
if (clazz == null)
|
||||
return null;
|
||||
try {
|
||||
return LOOKUP.unreflect(getMethod(clazz, method, params));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MethodHandle getFinalSetter(Class<?> clazz, String field) {
|
||||
return getFinalSetter(getField(clazz, field));
|
||||
}
|
||||
|
||||
public static MethodHandle getFinalSetter(Field field) {
|
||||
if (field == null)
|
||||
return null;
|
||||
if (MODIFIERS_FIELD == null) {
|
||||
if (UNSAFE == null) {
|
||||
try {
|
||||
UNSAFE = getField(Class.forName("sun.misc.Unsafe"), "theUnsafe").get(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
UNSAFE_STATIC_FIELD_OFFSET = getMethodHandle(UNSAFE.getClass(), "staticFieldOffset", Field.class)
|
||||
.bindTo(UNSAFE);
|
||||
UNSAFE_FIELD_OFFSET = getMethodHandle(UNSAFE.getClass(), "objectFieldOffset", Field.class)
|
||||
.bindTo(UNSAFE);
|
||||
UNSAFE_PUT_OBJECT = getMethodHandle(UNSAFE.getClass(), "putObject", Object.class, long.class,
|
||||
Object.class).bindTo(UNSAFE);
|
||||
UNSAFE_PUT_INT = getMethodHandle(UNSAFE.getClass(), "putInt", Object.class, long.class, int.class)
|
||||
.bindTo(UNSAFE);
|
||||
UNSAFE_PUT_FLOAT = getMethodHandle(UNSAFE.getClass(), "putFloat", Object.class, long.class,
|
||||
float.class).bindTo(UNSAFE);
|
||||
UNSAFE_PUT_DOUBLE = getMethodHandle(UNSAFE.getClass(), "putDouble", Object.class, long.class,
|
||||
double.class).bindTo(UNSAFE);
|
||||
UNSAFE_PUT_BOOLEAN = getMethodHandle(UNSAFE.getClass(), "putBoolean", Object.class, long.class,
|
||||
boolean.class).bindTo(UNSAFE);
|
||||
UNSAFE_PUT_LONG = getMethodHandle(UNSAFE.getClass(), "putLong", Object.class, long.class,
|
||||
long.class).bindTo(UNSAFE);
|
||||
}
|
||||
try {
|
||||
boolean isStatic = Modifier.isStatic(field.getModifiers());
|
||||
long offset = (long) (isStatic ? UNSAFE_STATIC_FIELD_OFFSET.invoke(field)
|
||||
: UNSAFE_FIELD_OFFSET.invoke(field));
|
||||
MethodHandle mh = field.getType() == int.class ? UNSAFE_PUT_INT
|
||||
: field.getType() == boolean.class ? UNSAFE_PUT_BOOLEAN
|
||||
: field.getType() == double.class ? UNSAFE_PUT_DOUBLE
|
||||
: field.getType() == float.class ? UNSAFE_PUT_FLOAT
|
||||
: field.getType() == long.class ? UNSAFE_PUT_LONG : UNSAFE_PUT_OBJECT;
|
||||
return isStatic ? MethodHandles.insertArguments(mh, 0, field.getDeclaringClass(), offset)
|
||||
: MethodHandles.insertArguments(mh, 1, offset);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
MODIFIERS_FIELD.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return LOOKUP.unreflectSetter(field);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: ElementOriginLib
|
||||
version: '1.1'
|
||||
version: '1.2'
|
||||
main: com.io.yutian.elementoriginlib.ElementOriginLib
|
||||
api-version: '1.20'
|
||||
authors: [ SuperYuTian ]
|
||||
|
|
Loading…
Reference in New Issue
Block a user