Moving accessor methods to a separate "Accessors" factory class.
Dieser Commit ist enthalten in:
Ursprung
b70c7fa775
Commit
143ed2ff02
@ -36,8 +36,9 @@ import com.comphenix.protocol.injector.server.SocketInjector;
|
|||||||
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.VolatileField;
|
import com.comphenix.protocol.reflect.VolatileField;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||||
import com.comphenix.protocol.utility.MinecraftFields;
|
import com.comphenix.protocol.utility.MinecraftFields;
|
||||||
import com.comphenix.protocol.utility.MinecraftMethods;
|
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
@ -213,10 +214,10 @@ class ChannelInjector extends ByteToMessageDecoder {
|
|||||||
patchEncoder(vanillaEncoder);
|
patchEncoder(vanillaEncoder);
|
||||||
|
|
||||||
if (DECODE_BUFFER == null)
|
if (DECODE_BUFFER == null)
|
||||||
DECODE_BUFFER = FuzzyReflection.getMethodAccessor(vanillaDecoder.getClass(),
|
DECODE_BUFFER = Accessors.getMethodAccessor(vanillaDecoder.getClass(),
|
||||||
"decode", ChannelHandlerContext.class, ByteBuf.class, List.class);
|
"decode", ChannelHandlerContext.class, ByteBuf.class, List.class);
|
||||||
if (ENCODE_BUFFER == null)
|
if (ENCODE_BUFFER == null)
|
||||||
ENCODE_BUFFER = FuzzyReflection.getMethodAccessor(vanillaEncoder.getClass(),
|
ENCODE_BUFFER = Accessors.getMethodAccessor(vanillaEncoder.getClass(),
|
||||||
"encode", ChannelHandlerContext.class, Object.class, ByteBuf.class);
|
"encode", ChannelHandlerContext.class, Object.class, ByteBuf.class);
|
||||||
|
|
||||||
// Intercept sent packets
|
// Intercept sent packets
|
||||||
@ -265,7 +266,7 @@ class ChannelInjector extends ByteToMessageDecoder {
|
|||||||
*/
|
*/
|
||||||
private void patchEncoder(MessageToByteEncoder<Object> encoder) {
|
private void patchEncoder(MessageToByteEncoder<Object> encoder) {
|
||||||
if (ENCODER_TYPE_MATCHER == null) {
|
if (ENCODER_TYPE_MATCHER == null) {
|
||||||
ENCODER_TYPE_MATCHER = FuzzyReflection.getFieldAccessor(encoder.getClass(), "matcher", true);
|
ENCODER_TYPE_MATCHER = Accessors.getFieldAccessor(encoder.getClass(), "matcher", true);
|
||||||
}
|
}
|
||||||
ENCODER_TYPE_MATCHER.set(encoder, TypeParameterMatcher.get(MinecraftReflection.getPacketClass()));
|
ENCODER_TYPE_MATCHER.set(encoder, TypeParameterMatcher.get(MinecraftReflection.getPacketClass()));
|
||||||
}
|
}
|
||||||
@ -490,7 +491,7 @@ class ChannelInjector extends ByteToMessageDecoder {
|
|||||||
*/
|
*/
|
||||||
public Protocol getCurrentProtocol() {
|
public Protocol getCurrentProtocol() {
|
||||||
if (PROTOCOL_ACCESSOR == null) {
|
if (PROTOCOL_ACCESSOR == null) {
|
||||||
PROTOCOL_ACCESSOR = FuzzyReflection.getFieldAccessor(
|
PROTOCOL_ACCESSOR = Accessors.getFieldAccessor(
|
||||||
networkManager.getClass(), MinecraftReflection.getEnumProtocolClass(), true);
|
networkManager.getClass(), MinecraftReflection.getEnumProtocolClass(), true);
|
||||||
}
|
}
|
||||||
return Protocol.fromVanilla((Enum<?>) PROTOCOL_ACCESSOR.get(networkManager));
|
return Protocol.fromVanilla((Enum<?>) PROTOCOL_ACCESSOR.get(networkManager));
|
||||||
|
@ -5,8 +5,8 @@ import java.net.SocketAddress;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import net.minecraft.util.io.netty.buffer.ByteBufAllocator;
|
import net.minecraft.util.io.netty.buffer.ByteBufAllocator;
|
||||||
@ -128,7 +128,7 @@ abstract class ChannelProxy implements Channel {
|
|||||||
|
|
||||||
if (accessor == null) {
|
if (accessor == null) {
|
||||||
try {
|
try {
|
||||||
accessor = FuzzyReflection.getFieldAccessor(clazz, messageClass, true);
|
accessor = Accessors.getFieldAccessor(clazz, messageClass, true);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
accessor = MARK_NO_MESSAGE;
|
accessor = MARK_NO_MESSAGE;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import net.sf.cglib.asm.ClassReader;
|
import net.sf.cglib.asm.ClassReader;
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.comphenix.protocol.reflect;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
public class ExactReflection {
|
||||||
|
// The class we're actually representing
|
||||||
|
private Class<?> source;
|
||||||
|
private boolean forceAccess;
|
||||||
|
|
||||||
|
private ExactReflection(Class<?> source, boolean forceAccess) {
|
||||||
|
this.source = Preconditions.checkNotNull(source, "source class cannot be NULL");
|
||||||
|
this.forceAccess = forceAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an exact reflection instance from a given class.
|
||||||
|
* @param source - the class we'll use.
|
||||||
|
* @return A fuzzy reflection instance.
|
||||||
|
*/
|
||||||
|
public static ExactReflection fromClass(Class<?> source) {
|
||||||
|
return fromClass(source, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an exact reflection instance from a given class.
|
||||||
|
* @param source - the class we'll use.
|
||||||
|
* @param forceAccess - whether or not to override scope restrictions.
|
||||||
|
* @return A fuzzy reflection instance.
|
||||||
|
*/
|
||||||
|
public static ExactReflection fromClass(Class<?> source, boolean forceAccess) {
|
||||||
|
return new ExactReflection(source, forceAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an exact reflection instance from an object.
|
||||||
|
* @param reference - the object we'll use.
|
||||||
|
* @return A fuzzy reflection instance that uses the class of the given object.
|
||||||
|
*/
|
||||||
|
public static ExactReflection fromObject(Object reference) {
|
||||||
|
return new ExactReflection(reference.getClass(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an exact reflection instance from an object.
|
||||||
|
* @param reference - the object we'll use.
|
||||||
|
* @param forceAccess - whether or not to override scope restrictions.
|
||||||
|
* @return A fuzzy reflection instance that uses the class of the given object.
|
||||||
|
*/
|
||||||
|
public static ExactReflection fromObject(Object reference, boolean forceAccess) {
|
||||||
|
return new ExactReflection(reference.getClass(), forceAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the first method in the class hierachy with the given name and parameters.
|
||||||
|
* <p>
|
||||||
|
* If {@link #isForceAccess()} is TRUE, we will also search for protected and private methods.
|
||||||
|
* @param methodName - the method name to find, or NULL to look for everything.
|
||||||
|
* @param parameters - the parameters.
|
||||||
|
* @return The first matched method.
|
||||||
|
* @throws IllegalArgumentException If we cannot find a method by this name.
|
||||||
|
*/
|
||||||
|
public Method getMethod(String methodName, Class<?>... parameters) {
|
||||||
|
return getMethod(source, methodName, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For recursion
|
||||||
|
private Method getMethod(Class<?> instanceClass, String methodName, Class<?>... parameters) {
|
||||||
|
for (Method method : instanceClass.getDeclaredMethods()) {
|
||||||
|
if ((forceAccess || Modifier.isPublic(method.getModifiers())) &&
|
||||||
|
(methodName == null || method.getName().equals(methodName)) &&
|
||||||
|
Arrays.equals(method.getParameterTypes(), parameters)) {
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Search in every superclass
|
||||||
|
if (instanceClass.getSuperclass() != null)
|
||||||
|
return getMethod(instanceClass.getSuperclass(), methodName, parameters);
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Unable to find method %s (%s) in %s.", methodName, Arrays.asList(parameters), source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a field in the class hierachy by the given name.
|
||||||
|
* <p>
|
||||||
|
* If {@link #isForceAccess()} is TRUE, we will also search for protected and private fields.
|
||||||
|
* @param fieldName - the field name. Cannot be NULL.
|
||||||
|
* @return The first matched field.
|
||||||
|
*/
|
||||||
|
public Field getField(String fieldName) {
|
||||||
|
return getField(source, fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For recursion
|
||||||
|
private Field getField(Class<?> instanceClass, @Nonnull String fieldName) {
|
||||||
|
// Ignore access rules
|
||||||
|
for (Field field : instanceClass.getDeclaredFields()) {
|
||||||
|
if (field.getName().equals(fieldName)) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively fild the correct field
|
||||||
|
if (instanceClass.getSuperclass() != null)
|
||||||
|
return getField(instanceClass.getSuperclass(), fieldName);
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Unable to find field %s in %s.", fieldName, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an {@link ExactReflection} object where scope restrictions are ignored.
|
||||||
|
* @return A copy of the current object.
|
||||||
|
*/
|
||||||
|
public ExactReflection forceAccess() {
|
||||||
|
return new ExactReflection(source, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if we are overriding scope restrictions and will also find
|
||||||
|
* private, protected or package members.
|
||||||
|
* @return TRUE if we are, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isForceAccess() {
|
||||||
|
return forceAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the source class we are searching.
|
||||||
|
* @return The source.
|
||||||
|
*/
|
||||||
|
public Class<?> getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
@ -29,9 +29,9 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@ -42,85 +42,6 @@ import com.google.common.collect.Sets;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class FuzzyReflection {
|
public class FuzzyReflection {
|
||||||
/**
|
|
||||||
* Represents an interface for accessing a field.
|
|
||||||
* @author Kristian
|
|
||||||
*/
|
|
||||||
public interface FieldAccessor {
|
|
||||||
/**
|
|
||||||
* Retrieve the value of a field for a particular instance.
|
|
||||||
* @param instance - the instance, or NULL for a static field.
|
|
||||||
* @return The value of the field.
|
|
||||||
* @throws IllegalStateException If the current security context prohibits reflection.
|
|
||||||
*/
|
|
||||||
public Object get(Object instance);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of a field for a particular instance.
|
|
||||||
* @param instance - the instance, or NULL for a static field.
|
|
||||||
* @param value - the new value of the field.
|
|
||||||
*/
|
|
||||||
public void set(Object instance, Object value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying field.
|
|
||||||
* @return The field.
|
|
||||||
*/
|
|
||||||
public Field getField();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an interface for invoking a method.
|
|
||||||
* @author Kristian
|
|
||||||
*/
|
|
||||||
public interface MethodAccessor {
|
|
||||||
/**
|
|
||||||
* Invoke the underlying method.
|
|
||||||
* @param target - the target instance, or NULL for a static method.
|
|
||||||
* @param args - the arguments to pass to the method.
|
|
||||||
* @return The return value, or NULL for void methods.
|
|
||||||
*/
|
|
||||||
public Object invoke(Object target, Object... args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying method.
|
|
||||||
* @return The method.
|
|
||||||
*/
|
|
||||||
public Method getMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a field accessor that synchronizes access to the underlying field.
|
|
||||||
* @author Kristian
|
|
||||||
*/
|
|
||||||
private static final class SynchronizedFieldAccessor implements FieldAccessor {
|
|
||||||
private final FieldAccessor accessor;
|
|
||||||
private SynchronizedFieldAccessor(FieldAccessor accessor) {
|
|
||||||
this.accessor = accessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(Object instance, Object value) {
|
|
||||||
Object lock = accessor.get(instance);
|
|
||||||
|
|
||||||
if (lock != null) {
|
|
||||||
synchronized (lock) {
|
|
||||||
accessor.set(instance, value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
accessor.set(instance, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Object get(Object instance) {
|
|
||||||
return accessor.get(instance);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Field getField() {
|
|
||||||
return accessor.getField();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The class we're actually representing
|
// The class we're actually representing
|
||||||
private Class<?> source;
|
private Class<?> source;
|
||||||
|
|
||||||
@ -170,107 +91,6 @@ public class FuzzyReflection {
|
|||||||
return new FuzzyReflection(reference.getClass(), forceAccess);
|
return new FuzzyReflection(reference.getClass(), forceAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve an accessor for the first field of the given type.
|
|
||||||
* @param instanceClass - the type of the instance to retrieve.
|
|
||||||
* @param fieldClass - type of the field to retrieve.
|
|
||||||
* @param forceAccess - whether or not to look for private and protected fields.
|
|
||||||
* @return The value of that field.
|
|
||||||
* @throws IllegalArgumentException If the field cannot be found.
|
|
||||||
*/
|
|
||||||
public static FieldAccessor getFieldAccessor(Class<?> instanceClass, Class<?> fieldClass, boolean forceAccess) {
|
|
||||||
// Get a field accessor
|
|
||||||
Field field = FuzzyReflection.fromClass(instanceClass, forceAccess).getFieldByType(null, fieldClass);
|
|
||||||
return getFieldAccessor(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve an accessor for the first field of the given type.
|
|
||||||
* @param instanceClass - the type of the instance to retrieve.
|
|
||||||
* @param fieldClass - type of the field to retrieve.
|
|
||||||
* @param forceAccess - whether or not to look for private and protected fields.
|
|
||||||
* @return The value of that field.
|
|
||||||
* @throws IllegalArgumentException If the field cannot be found.
|
|
||||||
*/
|
|
||||||
public static FieldAccessor getFieldAccessor(Class<?> instanceClass, String fieldName, boolean forceAccess) {
|
|
||||||
return getFieldAccessor(FieldUtils.getField(instanceClass, fieldName, forceAccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a field accessor from a given field that uses unchecked exceptions.
|
|
||||||
* @param field - the field.
|
|
||||||
* @return The field accessor.
|
|
||||||
*/
|
|
||||||
public static FieldAccessor getFieldAccessor(final Field field) {
|
|
||||||
return getFieldAccessor(field, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a field accessor from a given field that uses unchecked exceptions.
|
|
||||||
* @param field - the field.
|
|
||||||
* @param forceAccess - whether or not to skip Java access checking.
|
|
||||||
* @return The field accessor.
|
|
||||||
*/
|
|
||||||
public static FieldAccessor getFieldAccessor(final Field field, boolean forceAccess) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
return new DefaultFieldAccessor(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a field accessor where the write operation is synchronized on the current field value.
|
|
||||||
* @param accessor - the accessor.
|
|
||||||
* @return The field accessor.
|
|
||||||
*/
|
|
||||||
public static FieldAccessor getSynchronized(final FieldAccessor accessor) {
|
|
||||||
// Only wrap once
|
|
||||||
if (accessor instanceof SynchronizedFieldAccessor)
|
|
||||||
return accessor;
|
|
||||||
return new SynchronizedFieldAccessor(accessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a method accessor for a method with the given name and signature.
|
|
||||||
* @param instanceClass - the parent class.
|
|
||||||
* @param name - the method name.
|
|
||||||
* @param parameters - the parameters.
|
|
||||||
* @return The method accessor.
|
|
||||||
*/
|
|
||||||
public static MethodAccessor getMethodAccessor(Class<?> instanceClass, String name, Class<?>... parameters) {
|
|
||||||
return getMethodAccessor(instanceClass, instanceClass, name, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method
|
|
||||||
private static MethodAccessor getMethodAccessor(
|
|
||||||
Class<?> initialClass, Class<?> instanceClass, String name, Class<?>... parameters) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
Method method = instanceClass.getDeclaredMethod(name, parameters);
|
|
||||||
method.setAccessible(true);
|
|
||||||
return getMethodAccessor(method);
|
|
||||||
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
// Search for a private method in the superclass
|
|
||||||
if (initialClass.getSuperclass() != null)
|
|
||||||
return getMethodAccessor(initialClass, instanceClass.getSuperclass(), name, parameters);
|
|
||||||
|
|
||||||
// Unable to find it
|
|
||||||
throw new IllegalArgumentException("Unable to find method " + name +
|
|
||||||
"(" + Joiner.on(", ").join(parameters) +") in " + initialClass);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to retrieve methods.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a method accessor for a particular method, avoding checked exceptions.
|
|
||||||
* @param method - the method to access.
|
|
||||||
* @return The method accessor.
|
|
||||||
*/
|
|
||||||
public static MethodAccessor getMethodAccessor(final Method method) {
|
|
||||||
return new DefaultMethodAccessor(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the value of the first field of the given type.
|
* Retrieve the value of the first field of the given type.
|
||||||
* @param instance - the instance to retrieve from.
|
* @param instance - the instance to retrieve from.
|
||||||
@ -281,7 +101,7 @@ public class FuzzyReflection {
|
|||||||
*/
|
*/
|
||||||
public static <T> T getFieldValue(Object instance, Class<T> fieldClass, boolean forceAccess) {
|
public static <T> T getFieldValue(Object instance, Class<T> fieldClass, boolean forceAccess) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T result = (T) getFieldAccessor(instance.getClass(), fieldClass, forceAccess).get(instance);
|
T result = (T) Accessors.getFieldAccessor(instance.getClass(), fieldClass, forceAccess).get(instance);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ package com.comphenix.protocol.reflect;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +49,7 @@ public class VolatileField {
|
|||||||
* @param container - the object this field belongs to.
|
* @param container - the object this field belongs to.
|
||||||
*/
|
*/
|
||||||
public VolatileField(Field field, Object container) {
|
public VolatileField(Field field, Object container) {
|
||||||
this.accessor = FuzzyReflection.getFieldAccessor(field);
|
this.accessor = Accessors.getFieldAccessor(field);
|
||||||
this.container = container;
|
this.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ public class VolatileField {
|
|||||||
* @param forceAccess - whether or not to override any scope restrictions.
|
* @param forceAccess - whether or not to override any scope restrictions.
|
||||||
*/
|
*/
|
||||||
public VolatileField(Field field, Object container, boolean forceAccess) {
|
public VolatileField(Field field, Object container, boolean forceAccess) {
|
||||||
this.accessor = FuzzyReflection.getFieldAccessor(field, true);
|
this.accessor = Accessors.getFieldAccessor(field, true);
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.forceAccess = forceAccess;
|
this.forceAccess = forceAccess;
|
||||||
}
|
}
|
||||||
@ -193,7 +194,7 @@ public class VolatileField {
|
|||||||
* @return A synchronized volatile field.
|
* @return A synchronized volatile field.
|
||||||
*/
|
*/
|
||||||
public VolatileField toSynchronized() {
|
public VolatileField toSynchronized() {
|
||||||
return new VolatileField(FuzzyReflection.getSynchronized(accessor), container);
|
return new VolatileField(Accessors.getSynchronized(accessor), container);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,125 @@
|
|||||||
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.reflect.ExactReflection;
|
||||||
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
|
|
||||||
|
public final class Accessors {
|
||||||
|
/**
|
||||||
|
* Represents a field accessor that synchronizes access to the underlying field.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public static final class SynchronizedFieldAccessor implements FieldAccessor {
|
||||||
|
private final FieldAccessor accessor;
|
||||||
|
private SynchronizedFieldAccessor(FieldAccessor accessor) {
|
||||||
|
this.accessor = accessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object instance, Object value) {
|
||||||
|
Object lock = accessor.get(instance);
|
||||||
|
|
||||||
|
if (lock != null) {
|
||||||
|
synchronized (lock) {
|
||||||
|
accessor.set(instance, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
accessor.set(instance, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Object instance) {
|
||||||
|
return accessor.get(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Field getField() {
|
||||||
|
return accessor.getField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an accessor for the first field of the given type.
|
||||||
|
* @param instanceClass - the type of the instance to retrieve.
|
||||||
|
* @param fieldClass - type of the field to retrieve.
|
||||||
|
* @param forceAccess - whether or not to look for private and protected fields.
|
||||||
|
* @return The value of that field.
|
||||||
|
* @throws IllegalArgumentException If the field cannot be found.
|
||||||
|
*/
|
||||||
|
public static FieldAccessor getFieldAccessor(Class<?> instanceClass, Class<?> fieldClass, boolean forceAccess) {
|
||||||
|
// Get a field accessor
|
||||||
|
Field field = FuzzyReflection.fromClass(instanceClass, forceAccess).getFieldByType(null, fieldClass);
|
||||||
|
return Accessors.getFieldAccessor(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an accessor for the first field of the given type.
|
||||||
|
* @param instanceClass - the type of the instance to retrieve.
|
||||||
|
* @param fieldClass - type of the field to retrieve.
|
||||||
|
* @param forceAccess - whether or not to look for private and protected fields.
|
||||||
|
* @return The value of that field.
|
||||||
|
* @throws IllegalArgumentException If the field cannot be found.
|
||||||
|
*/
|
||||||
|
public static FieldAccessor getFieldAccessor(Class<?> instanceClass, String fieldName, boolean forceAccess) {
|
||||||
|
return Accessors.getFieldAccessor(ExactReflection.fromClass(instanceClass, true).getField(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a field accessor from a given field that uses unchecked exceptions.
|
||||||
|
* @param field - the field.
|
||||||
|
* @return The field accessor.
|
||||||
|
*/
|
||||||
|
public static FieldAccessor getFieldAccessor(final Field field) {
|
||||||
|
return Accessors.getFieldAccessor(field, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a field accessor from a given field that uses unchecked exceptions.
|
||||||
|
* @param field - the field.
|
||||||
|
* @param forceAccess - whether or not to skip Java access checking.
|
||||||
|
* @return The field accessor.
|
||||||
|
*/
|
||||||
|
public static FieldAccessor getFieldAccessor(final Field field, boolean forceAccess) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return new DefaultFieldAccessor(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a field accessor where the write operation is synchronized on the current field value.
|
||||||
|
* @param accessor - the accessor.
|
||||||
|
* @return The field accessor.
|
||||||
|
*/
|
||||||
|
public static FieldAccessor getSynchronized(final FieldAccessor accessor) {
|
||||||
|
// Only wrap once
|
||||||
|
if (accessor instanceof SynchronizedFieldAccessor)
|
||||||
|
return accessor;
|
||||||
|
return new SynchronizedFieldAccessor(accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a method accessor for a method with the given name and signature.
|
||||||
|
* @param instanceClass - the parent class.
|
||||||
|
* @param methodName - the method name.
|
||||||
|
* @param parameters - the parameters.
|
||||||
|
* @return The method accessor.
|
||||||
|
*/
|
||||||
|
public static MethodAccessor getMethodAccessor(Class<?> instanceClass, String methodName, Class<?>... parameters) {
|
||||||
|
return new DefaultMethodAccessor(ExactReflection.fromClass(instanceClass, true).getMethod(methodName, parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a method accessor for a particular method, avoding checked exceptions.
|
||||||
|
* @param method - the method to access.
|
||||||
|
* @return The method accessor.
|
||||||
|
*/
|
||||||
|
public static MethodAccessor getMethodAccessor(final Method method) {
|
||||||
|
return new DefaultMethodAccessor(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seal this class
|
||||||
|
private Accessors() {
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
package com.comphenix.protocol.reflect;
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
|
||||||
|
|
||||||
final class DefaultFieldAccessor implements FieldAccessor {
|
final class DefaultFieldAccessor implements FieldAccessor {
|
||||||
private final Field field;
|
private final Field field;
|
||||||
|
|
@ -1,10 +1,8 @@
|
|||||||
package com.comphenix.protocol.reflect;
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
|
||||||
|
|
||||||
final class DefaultMethodAccessor implements MethodAccessor {
|
final class DefaultMethodAccessor implements MethodAccessor {
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an interface for accessing a field.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public interface FieldAccessor {
|
||||||
|
/**
|
||||||
|
* Retrieve the value of a field for a particular instance.
|
||||||
|
* @param instance - the instance, or NULL for a static field.
|
||||||
|
* @return The value of the field.
|
||||||
|
* @throws IllegalStateException If the current security context prohibits reflection.
|
||||||
|
*/
|
||||||
|
public Object get(Object instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of a field for a particular instance.
|
||||||
|
* @param instance - the instance, or NULL for a static field.
|
||||||
|
* @param value - the new value of the field.
|
||||||
|
*/
|
||||||
|
public void set(Object instance, Object value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the underlying field.
|
||||||
|
* @return The field.
|
||||||
|
*/
|
||||||
|
public Field getField();
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an interface for invoking a method.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public interface MethodAccessor {
|
||||||
|
/**
|
||||||
|
* Invoke the underlying method.
|
||||||
|
* @param target - the target instance, or NULL for a static method.
|
||||||
|
* @param args - the arguments to pass to the method.
|
||||||
|
* @return The return value, or NULL for void methods.
|
||||||
|
*/
|
||||||
|
public Object invoke(Object target, Object... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the underlying method.
|
||||||
|
* @return The method.
|
||||||
|
*/
|
||||||
|
public Method getMethod();
|
||||||
|
}
|
@ -12,8 +12,8 @@ import java.nio.channels.GatheringByteChannel;
|
|||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.common.io.LimitInputStream;
|
import com.google.common.io.LimitInputStream;
|
||||||
|
|
||||||
@ -47,10 +47,10 @@ class ByteBufAdapter extends AbstractByteBuf {
|
|||||||
// Prepare accessors
|
// Prepare accessors
|
||||||
try {
|
try {
|
||||||
if (READER_INDEX == null) {
|
if (READER_INDEX == null) {
|
||||||
READER_INDEX = FuzzyReflection.getFieldAccessor(AbstractByteBuf.class.getDeclaredField("readerIndex"));
|
READER_INDEX = Accessors.getFieldAccessor(AbstractByteBuf.class.getDeclaredField("readerIndex"));
|
||||||
}
|
}
|
||||||
if (WRITER_INDEX == null) {
|
if (WRITER_INDEX == null) {
|
||||||
WRITER_INDEX = FuzzyReflection.getFieldAccessor(AbstractByteBuf.class.getDeclaredField("writerIndex"));
|
WRITER_INDEX = Accessors.getFieldAccessor(AbstractByteBuf.class.getDeclaredField("writerIndex"));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Cannot initialize ByteBufAdapter.", e);
|
throw new RuntimeException("Cannot initialize ByteBufAdapter.", e);
|
||||||
|
@ -33,7 +33,8 @@ import com.comphenix.protocol.injector.PacketConstructor;
|
|||||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
@ -108,10 +109,10 @@ public class ChatExtensions {
|
|||||||
|
|
||||||
// Try one of the string constructors
|
// Try one of the string constructors
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
messageFactory = FuzzyReflection.getMethodAccessor(
|
messageFactory = Accessors.getMethodAccessor(
|
||||||
MinecraftReflection.getCraftMessageClass(), "fromString", String.class);
|
MinecraftReflection.getCraftMessageClass(), "fromString", String.class);
|
||||||
} else {
|
} else {
|
||||||
messageFactory = FuzzyReflection.getMethodAccessor(
|
messageFactory = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(messageClass).getMethod(
|
FuzzyReflection.fromClass(messageClass).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
requireModifier(Modifier.STATIC).
|
requireModifier(Modifier.STATIC).
|
||||||
|
@ -3,8 +3,8 @@ package com.comphenix.protocol.utility;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.FieldAccessor;
|
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the content of well-known fields in Minecraft.
|
* Retrieve the content of well-known fields in Minecraft.
|
||||||
@ -30,7 +30,7 @@ public class MinecraftFields {
|
|||||||
if (NETWORK_ACCESSOR == null) {
|
if (NETWORK_ACCESSOR == null) {
|
||||||
Class<?> networkClass = MinecraftReflection.getNetworkManagerClass();
|
Class<?> networkClass = MinecraftReflection.getNetworkManagerClass();
|
||||||
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
|
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
|
||||||
NETWORK_ACCESSOR = FuzzyReflection.getFieldAccessor(connectionClass, networkClass, true);
|
NETWORK_ACCESSOR = Accessors.getFieldAccessor(connectionClass, networkClass, true);
|
||||||
}
|
}
|
||||||
// Retrieve the network manager
|
// Retrieve the network manager
|
||||||
return NETWORK_ACCESSOR.get(getPlayerConnection(nmsPlayer));
|
return NETWORK_ACCESSOR.get(getPlayerConnection(nmsPlayer));
|
||||||
@ -49,7 +49,7 @@ public class MinecraftFields {
|
|||||||
private static Object getPlayerConnection(Object nmsPlayer) {
|
private static Object getPlayerConnection(Object nmsPlayer) {
|
||||||
if (CONNECTION_ACCESSOR == null) {
|
if (CONNECTION_ACCESSOR == null) {
|
||||||
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
|
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
|
||||||
CONNECTION_ACCESSOR = FuzzyReflection.getFieldAccessor(nmsPlayer.getClass(), connectionClass, true);
|
CONNECTION_ACCESSOR = Accessors.getFieldAccessor(nmsPlayer.getClass(), connectionClass, true);
|
||||||
}
|
}
|
||||||
return CONNECTION_ACCESSOR.get(nmsPlayer);
|
return CONNECTION_ACCESSOR.get(nmsPlayer);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ import com.comphenix.protocol.injector.packet.PacketRegistry;
|
|||||||
import com.comphenix.protocol.reflect.ClassAnalyser;
|
import com.comphenix.protocol.reflect.ClassAnalyser;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
|
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||||
@ -654,7 +655,7 @@ public class MinecraftReflection {
|
|||||||
return getMinecraftClass("IChatBaseComponent");
|
return getMinecraftClass("IChatBaseComponent");
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
return setMinecraftClass("IChatBaseComponent",
|
return setMinecraftClass("IChatBaseComponent",
|
||||||
FuzzyReflection.getMethodAccessor(getCraftChatMessage(), "fromString", String.class).
|
Accessors.getMethodAccessor(getCraftChatMessage(), "fromString", String.class).
|
||||||
getMethod().getReturnType().getComponentType()
|
getMethod().getReturnType().getComponentType()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||||
@ -100,7 +101,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (READ_ITEM_METHOD == null) {
|
if (READ_ITEM_METHOD == null) {
|
||||||
READ_ITEM_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_ITEM_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("readItemStack",
|
getMethodByParameters("readItemStack",
|
||||||
MinecraftReflection.getItemStackClass(), new Class<?>[0])
|
MinecraftReflection.getItemStackClass(), new Class<?>[0])
|
||||||
@ -110,7 +111,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (READ_ITEM_METHOD == null) {
|
if (READ_ITEM_METHOD == null) {
|
||||||
READ_ITEM_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_ITEM_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(1).
|
parameterCount(1).
|
||||||
@ -143,7 +144,7 @@ public class StreamSerializer {
|
|||||||
// Invoke the correct method
|
// Invoke the correct method
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (READ_NBT_METHOD == null) {
|
if (READ_NBT_METHOD == null) {
|
||||||
READ_NBT_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_NBT_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("readNbtCompound",
|
getMethodByParameters("readNbtCompound",
|
||||||
MinecraftReflection.getNBTCompoundClass(), new Class<?>[0])
|
MinecraftReflection.getNBTCompoundClass(), new Class<?>[0])
|
||||||
@ -153,7 +154,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (READ_NBT_METHOD == null) {
|
if (READ_NBT_METHOD == null) {
|
||||||
READ_NBT_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_NBT_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(1).
|
parameterCount(1).
|
||||||
@ -196,7 +197,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (READ_STRING_METHOD == null) {
|
if (READ_STRING_METHOD == null) {
|
||||||
READ_STRING_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_STRING_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("readString", String.class, new Class<?>[] { int.class })
|
getMethodByParameters("readString", String.class, new Class<?>[] { int.class })
|
||||||
);
|
);
|
||||||
@ -205,7 +206,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (READ_STRING_METHOD == null) {
|
if (READ_STRING_METHOD == null) {
|
||||||
READ_STRING_METHOD = FuzzyReflection.getMethodAccessor(
|
READ_STRING_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
@ -254,7 +255,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (WRITE_ITEM_METHOD == null) {
|
if (WRITE_ITEM_METHOD == null) {
|
||||||
WRITE_ITEM_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_ITEM_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("writeStack", MinecraftReflection.getItemStackClass())
|
getMethodByParameters("writeStack", MinecraftReflection.getItemStackClass())
|
||||||
);
|
);
|
||||||
@ -263,7 +264,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (WRITE_ITEM_METHOD == null)
|
if (WRITE_ITEM_METHOD == null)
|
||||||
WRITE_ITEM_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_ITEM_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
@ -293,7 +294,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (WRITE_NBT_METHOD == null) {
|
if (WRITE_NBT_METHOD == null) {
|
||||||
WRITE_NBT_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_NBT_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("writeNbtCompound", MinecraftReflection.getNBTCompoundClass())
|
getMethodByParameters("writeNbtCompound", MinecraftReflection.getNBTCompoundClass())
|
||||||
);
|
);
|
||||||
@ -302,7 +303,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (WRITE_NBT_METHOD == null) {
|
if (WRITE_NBT_METHOD == null) {
|
||||||
WRITE_NBT_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_NBT_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
@ -332,7 +333,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
if (WRITE_STRING_METHOD == null) {
|
if (WRITE_STRING_METHOD == null) {
|
||||||
WRITE_STRING_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_STRING_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true).
|
||||||
getMethodByParameters("writeString", String.class)
|
getMethodByParameters("writeString", String.class)
|
||||||
);
|
);
|
||||||
@ -341,7 +342,7 @@ public class StreamSerializer {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (WRITE_STRING_METHOD == null) {
|
if (WRITE_STRING_METHOD == null) {
|
||||||
WRITE_STRING_METHOD = FuzzyReflection.getMethodAccessor(
|
WRITE_STRING_METHOD = Accessors.getMethodAccessor(
|
||||||
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
|
@ -3,7 +3,8 @@ package com.comphenix.protocol.wrappers;
|
|||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,13 +22,13 @@ public class WrappedChatComponent {
|
|||||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER);
|
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER);
|
||||||
|
|
||||||
// Retrieve the correct methods
|
// Retrieve the correct methods
|
||||||
SERIALIZE_COMPONENT = FuzzyReflection.getMethodAccessor(
|
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(
|
||||||
fuzzy.getMethodByParameters("serialize", String.class, new Class<?>[] { COMPONENT }));
|
fuzzy.getMethodByParameters("serialize", String.class, new Class<?>[] { COMPONENT }));
|
||||||
DESERIALIZE_COMPONENT = FuzzyReflection.getMethodAccessor(
|
DESERIALIZE_COMPONENT = Accessors.getMethodAccessor(
|
||||||
fuzzy.getMethodByParameters("serialize", COMPONENT, new Class<?>[] { String.class }));
|
fuzzy.getMethodByParameters("serialize", COMPONENT, new Class<?>[] { String.class }));
|
||||||
|
|
||||||
// Get a component from a standard Minecraft message
|
// Get a component from a standard Minecraft message
|
||||||
CONSTRUCT_COMPONENT = FuzzyReflection.getMethodAccessor(
|
CONSTRUCT_COMPONENT = Accessors.getMethodAccessor(
|
||||||
MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.comphenix.protocol.reflect.accessors;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AccessorsTest {
|
||||||
|
// --- Some classes we can use for testing ---
|
||||||
|
private static class Entity {
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
public Entity(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void setId(int value) {
|
||||||
|
this.id = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Player extends Entity {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Player(int id, String name) {
|
||||||
|
super(id);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- Test classes ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testField() {
|
||||||
|
Player player = new Player(123, "ABC");
|
||||||
|
|
||||||
|
Accessors.getFieldAccessor(player.getClass(), "id", true).set(player, 0);
|
||||||
|
Accessors.getFieldAccessor(player.getClass(), "name", true).set(player, "MODIFIED");
|
||||||
|
assertEquals(0, player.getId());
|
||||||
|
assertEquals("MODIFIED", player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMethod() {
|
||||||
|
Player player = new Player(123, "ABC");
|
||||||
|
|
||||||
|
Accessors.getMethodAccessor(player.getClass(), "setId", int.class).invoke(player, 0);
|
||||||
|
assertEquals(0, player.getId());
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren