Ensure that the compiled structures respect the converter field.
In addition, fixed a bug that prevented client listeners from receiving any packets.
Dieser Commit ist enthalten in:
Ursprung
46d9a6e975
Commit
c2b4b5fce3
@ -148,6 +148,8 @@ public class PacketEvent extends EventObject implements Cancellable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this packet was created by the server.
|
* Whether or not this packet was created by the server.
|
||||||
|
* <p>
|
||||||
|
* Most listeners can deduce this by noting which listener method was invoked.
|
||||||
* @return TRUE if the packet was created by the server, FALSE if it was created by a client.
|
* @return TRUE if the packet was created by the server, FALSE if it was created by a client.
|
||||||
*/
|
*/
|
||||||
public boolean isServerPacket() {
|
public boolean isServerPacket() {
|
||||||
|
@ -293,7 +293,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
|||||||
* @param event - the packet event to invoke.
|
* @param event - the packet event to invoke.
|
||||||
*/
|
*/
|
||||||
public void invokePacketRecieving(PacketEvent event) {
|
public void invokePacketRecieving(PacketEvent event) {
|
||||||
handlePacket(recievedListeners, event);
|
handlePacket(recievedListeners, event, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -301,7 +301,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
|||||||
* @param event - the packet event to invoke.
|
* @param event - the packet event to invoke.
|
||||||
*/
|
*/
|
||||||
public void invokePacketSending(PacketEvent event) {
|
public void invokePacketSending(PacketEvent event) {
|
||||||
handlePacket(sendingListeners, event);
|
handlePacket(sendingListeners, event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,7 +311,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
|||||||
* @param packetListeners - packet listeners that will receive this event.
|
* @param packetListeners - packet listeners that will receive this event.
|
||||||
* @param event - the evnet to broadcast.
|
* @param event - the evnet to broadcast.
|
||||||
*/
|
*/
|
||||||
private void handlePacket(SortedPacketListenerList packetListeners, PacketEvent event) {
|
private void handlePacket(SortedPacketListenerList packetListeners, PacketEvent event, boolean sending) {
|
||||||
|
|
||||||
// By default, asynchronous packets are queued for processing
|
// By default, asynchronous packets are queued for processing
|
||||||
if (asyncFilterManager.hasAsynchronousListeners(event)) {
|
if (asyncFilterManager.hasAsynchronousListeners(event)) {
|
||||||
@ -319,7 +319,10 @@ public final class PacketFilterManager implements ProtocolManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process synchronous events
|
// Process synchronous events
|
||||||
packetListeners.invokePacketRecieving(logger, event);
|
if (sending)
|
||||||
|
packetListeners.invokePacketSending(logger, event);
|
||||||
|
else
|
||||||
|
packetListeners.invokePacketRecieving(logger, event);
|
||||||
|
|
||||||
// To cancel asynchronous processing, use the async marker
|
// To cancel asynchronous processing, use the async marker
|
||||||
if (!event.isCancelled() && !hasAsyncCancelled(event.getAsyncMarker())) {
|
if (!event.isCancelled() && !hasAsyncCancelled(event.getAsyncMarker())) {
|
||||||
|
@ -57,7 +57,7 @@ class SortedPacketListenerList extends AbstractConcurrentListenerMultimap<Packet
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Minecraft doesn't want your Exception.
|
// Minecraft doesn't want your Exception.
|
||||||
logger.log(Level.SEVERE,
|
logger.log(Level.SEVERE,
|
||||||
"Exception occured in onPacketReceiving() for " +
|
"Exception occured in onPacketSending() for " +
|
||||||
PacketAdapter.getPluginName(element.getListener()), e);
|
PacketAdapter.getPluginName(element.getListener()), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,9 @@ public class StructureModifier<TField> {
|
|||||||
// Cache of previous types
|
// Cache of previous types
|
||||||
protected Map<Class, StructureModifier> subtypeCache;
|
protected Map<Class, StructureModifier> subtypeCache;
|
||||||
|
|
||||||
|
// Whether or subclasses should handle conversion
|
||||||
|
protected boolean customConvertHandling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a structure modifier.
|
* Creates a structure modifier.
|
||||||
* @param targetType - the structure to modify.
|
* @param targetType - the structure to modify.
|
||||||
@ -125,7 +128,7 @@ public class StructureModifier<TField> {
|
|||||||
Object result = FieldUtils.readField(data.get(fieldIndex), target, true);
|
Object result = FieldUtils.readField(data.get(fieldIndex), target, true);
|
||||||
|
|
||||||
// Use the converter, if we have it
|
// Use the converter, if we have it
|
||||||
if (converter != null)
|
if (needConversion())
|
||||||
return converter.getSpecific(result);
|
return converter.getSpecific(result);
|
||||||
else
|
else
|
||||||
return (TField) result;
|
return (TField) result;
|
||||||
@ -164,7 +167,7 @@ public class StructureModifier<TField> {
|
|||||||
throw new IllegalStateException("Cannot write to a NULL target.");
|
throw new IllegalStateException("Cannot write to a NULL target.");
|
||||||
|
|
||||||
// Use the converter, if it exists
|
// Use the converter, if it exists
|
||||||
Object obj = converter != null ? converter.getGeneric(value) : value;
|
Object obj = needConversion() ? converter.getGeneric(value) : value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
||||||
@ -176,6 +179,14 @@ public class StructureModifier<TField> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not we should use the converter instance.
|
||||||
|
* @return TRUE if we should, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
private final boolean needConversion() {
|
||||||
|
return converter != null && !customConvertHandling;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the value of a given field IF and ONLY if it exists.
|
* Writes the value of a given field IF and ONLY if it exists.
|
||||||
* @param fieldIndex - index of the potential field.
|
* @param fieldIndex - index of the potential field.
|
||||||
@ -362,7 +373,7 @@ public class StructureModifier<TField> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a structure modifier with the same type and target, but using a new object converter.
|
* Retrieves a structure modifier with the same type and target, but using a new object converter.
|
||||||
* @param converter- the object converter to use.
|
* @param converter - the object converter to use.
|
||||||
* @return Structure modifier with the new converter.
|
* @return Structure modifier with the new converter.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -13,10 +13,15 @@ import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
* @param <TField> Field type.
|
* @param <TField> Field type.
|
||||||
*/
|
*/
|
||||||
public class CompiledStructureModifier<TField> extends StructureModifier<TField> {
|
public abstract class CompiledStructureModifier<TField> extends StructureModifier<TField> {
|
||||||
// Used to compile instances of structure modifiers
|
// Used to compile instances of structure modifiers
|
||||||
protected StructureCompiler compiler;
|
protected StructureCompiler compiler;
|
||||||
|
|
||||||
|
public CompiledStructureModifier() {
|
||||||
|
super();
|
||||||
|
customConvertHandling = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Speed up the default writer
|
// Speed up the default writer
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
@ -35,6 +40,29 @@ public class CompiledStructureModifier<TField> extends StructureModifier<TField>
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public final TField read(int fieldIndex) throws FieldAccessException {
|
||||||
|
Object result = readGenerated(fieldIndex);
|
||||||
|
|
||||||
|
if (converter != null)
|
||||||
|
return converter.getSpecific(result);
|
||||||
|
else
|
||||||
|
return (TField) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Object readGenerated(int fieldIndex) throws FieldAccessException;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public StructureModifier<TField> write(int index, Object value) throws FieldAccessException {
|
||||||
|
if (converter != null)
|
||||||
|
value = converter.getGeneric((TField) value);
|
||||||
|
return writeGenerated(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract StructureModifier<TField> writeGenerated(int index, Object value) throws FieldAccessException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StructureModifier<TField> withTarget(Object target) {
|
public StructureModifier<TField> withTarget(Object target) {
|
||||||
if (compiler != null)
|
if (compiler != null)
|
||||||
|
@ -14,40 +14,39 @@ import com.google.common.base.Objects;
|
|||||||
|
|
||||||
import net.sf.cglib.asm.*;
|
import net.sf.cglib.asm.*;
|
||||||
|
|
||||||
// This class will automatically generate the following type of structure modifier:
|
// public class CompiledStructureModifierPacket20<TField> extends CompiledStructureModifier<TField> {
|
||||||
//
|
|
||||||
// public class CompiledStructure$Packet20NamedEntitySpawnObject<TField> extends CompiledStructureModifier<TField> {
|
|
||||||
//
|
//
|
||||||
// private Packet20NamedEntitySpawn typedTarget;
|
// private Packet20NamedEntitySpawn typedTarget;
|
||||||
//
|
//
|
||||||
// public CompiledStructure$Packet20NamedEntitySpawnObject(StructureModifier<TField> other, StructureCompiler compiler) {
|
// public CompiledStructureModifierPacket20(StructureModifier<TField> other, StructureCompiler compiler) {
|
||||||
|
// super();
|
||||||
// initialize(other);
|
// initialize(other);
|
||||||
// this.typedTarget = (Packet20NamedEntitySpawn) other.getTarget();
|
// this.target = other.getTarget();
|
||||||
|
// this.typedTarget = (Packet20NamedEntitySpawn) target;
|
||||||
// this.compiler = compiler;
|
// this.compiler = compiler;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @SuppressWarnings("unchecked")
|
|
||||||
// @Override
|
// @Override
|
||||||
// public TField read(int fieldIndex) throws FieldAccessException {
|
// protected Object readGenerated(int fieldIndex) throws FieldAccessException {
|
||||||
//
|
//
|
||||||
// Packet20NamedEntitySpawn target = typedTarget;
|
// Packet20NamedEntitySpawn target = typedTarget;
|
||||||
//
|
//
|
||||||
// switch (fieldIndex) {
|
// switch (fieldIndex) {
|
||||||
// case 0: return (TField) (Object) target.a;
|
// case 0: return (Object) target.a;
|
||||||
// case 1: return (TField) (Object) target.b;
|
// case 1: return (Object) target.b;
|
||||||
// case 2: return (TField) (Object) target.c;
|
// case 2: return (Object) target.c;
|
||||||
// case 3: return (TField) (Object) target.d;
|
// case 3: return super.read(fieldIndex);
|
||||||
// case 4: return (TField) (Object) target.e;
|
// case 4: return super.read(fieldIndex);
|
||||||
// case 5: return (TField) (Object) target.f;
|
// case 5: return (Object) target.f;
|
||||||
// case 6: return (TField) (Object) target.g;
|
// case 6: return (Object) target.g;
|
||||||
// case 7: return (TField) (Object) target.h;
|
// case 7: return (Object) target.h;
|
||||||
// default:
|
// default:
|
||||||
// throw new FieldAccessException("Invalid index " + fieldIndex);
|
// throw new FieldAccessException("Invalid index " + fieldIndex);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
// public StructureModifier<TField> write(int index, Object value) {
|
// protected StructureModifier<TField> writeGenerated(int index, Object value) throws FieldAccessException {
|
||||||
//
|
//
|
||||||
// Packet20NamedEntitySpawn target = typedTarget;
|
// Packet20NamedEntitySpawn target = typedTarget;
|
||||||
//
|
//
|
||||||
@ -56,8 +55,8 @@ import net.sf.cglib.asm.*;
|
|||||||
// case 1: target.b = (String) value; break;
|
// case 1: target.b = (String) value; break;
|
||||||
// case 2: target.c = (Integer) value; break;
|
// case 2: target.c = (Integer) value; break;
|
||||||
// case 3: target.d = (Integer) value; break;
|
// case 3: target.d = (Integer) value; break;
|
||||||
// case 4: target.e = (Integer) value; break;
|
// case 4: super.write(index, value); break;
|
||||||
// case 5: target.f = (Byte) value; break;
|
// case 5: super.write(index, value); break;
|
||||||
// case 6: target.g = (Byte) value; break;
|
// case 6: target.g = (Byte) value; break;
|
||||||
// case 7: target.h = (Integer) value; break;
|
// case 7: target.h = (Integer) value; break;
|
||||||
// default:
|
// default:
|
||||||
@ -265,7 +264,7 @@ public final class StructureCompiler {
|
|||||||
|
|
||||||
String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";";
|
String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";";
|
||||||
String methodSignature = "(ITTField;)L" + SUPER_CLASS + "<TTField;>;";
|
String methodSignature = "(ITTField;)L" + SUPER_CLASS + "<TTField;>;";
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, "write", methodDescriptor, methodSignature,
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "writeGenerated", methodDescriptor, methodSignature,
|
||||||
new String[] { FIELD_EXCEPTION_CLASS });
|
new String[] { FIELD_EXCEPTION_CLASS });
|
||||||
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
||||||
|
|
||||||
@ -349,7 +348,7 @@ public final class StructureCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createReadMethod(ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
private void createReadMethod(ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, "read", "(I)Ljava/lang/Object;", "(I)TTField;",
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "readGenerated", "(I)Ljava/lang/Object;", null,
|
||||||
new String[] { "com/comphenix/protocol/reflect/FieldAccessException" });
|
new String[] { "com/comphenix/protocol/reflect/FieldAccessException" });
|
||||||
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
||||||
|
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren