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.
|
||||
* <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.
|
||||
*/
|
||||
public boolean isServerPacket() {
|
||||
|
@ -293,7 +293,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
* @param event - the packet event to invoke.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 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
|
||||
if (asyncFilterManager.hasAsynchronousListeners(event)) {
|
||||
@ -319,7 +319,10 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
}
|
||||
|
||||
// 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
|
||||
if (!event.isCancelled() && !hasAsyncCancelled(event.getAsyncMarker())) {
|
||||
|
@ -223,7 +223,7 @@ abstract class PlayerInjector {
|
||||
Integer id = MinecraftRegistry.getPacketToID().get(packet.getClass());
|
||||
|
||||
// Make sure we're listening
|
||||
if (id != null && sendingFilters.contains(id)) {
|
||||
if (id != null && sendingFilters.contains(id)) {
|
||||
// A packet has been sent guys!
|
||||
PacketContainer container = new PacketContainer(id, packet);
|
||||
PacketEvent event = PacketEvent.fromServer(manager, container, player);
|
||||
|
@ -97,7 +97,7 @@ class ReadPacketModifier implements MethodInterceptor {
|
||||
|
||||
// We need this in order to get the correct player
|
||||
DataInputStream input = (DataInputStream) args[0];
|
||||
|
||||
|
||||
// Let the people know
|
||||
PacketContainer container = new PacketContainer(packetID, (Packet) thisObj);
|
||||
PacketEvent event = packetInjector.packetRecieved(container, input);
|
||||
|
@ -57,7 +57,7 @@ class SortedPacketListenerList extends AbstractConcurrentListenerMultimap<Packet
|
||||
} catch (Throwable e) {
|
||||
// Minecraft doesn't want your Exception.
|
||||
logger.log(Level.SEVERE,
|
||||
"Exception occured in onPacketReceiving() for " +
|
||||
"Exception occured in onPacketSending() for " +
|
||||
PacketAdapter.getPluginName(element.getListener()), e);
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,9 @@ public class StructureModifier<TField> {
|
||||
// Cache of previous types
|
||||
protected Map<Class, StructureModifier> subtypeCache;
|
||||
|
||||
// Whether or subclasses should handle conversion
|
||||
protected boolean customConvertHandling;
|
||||
|
||||
/**
|
||||
* Creates a structure modifier.
|
||||
* @param targetType - the structure to modify.
|
||||
@ -125,7 +128,7 @@ public class StructureModifier<TField> {
|
||||
Object result = FieldUtils.readField(data.get(fieldIndex), target, true);
|
||||
|
||||
// Use the converter, if we have it
|
||||
if (converter != null)
|
||||
if (needConversion())
|
||||
return converter.getSpecific(result);
|
||||
else
|
||||
return (TField) result;
|
||||
@ -164,7 +167,7 @@ public class StructureModifier<TField> {
|
||||
throw new IllegalStateException("Cannot write to a NULL target.");
|
||||
|
||||
// Use the converter, if it exists
|
||||
Object obj = converter != null ? converter.getGeneric(value) : value;
|
||||
Object obj = needConversion() ? converter.getGeneric(value) : value;
|
||||
|
||||
try {
|
||||
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
||||
@ -176,6 +179,14 @@ public class StructureModifier<TField> {
|
||||
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.
|
||||
* @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.
|
||||
* @param converter- the object converter to use.
|
||||
* @param converter - the object converter to use.
|
||||
* @return Structure modifier with the new converter.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -13,10 +13,15 @@ import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
* @author Kristian
|
||||
* @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
|
||||
protected StructureCompiler compiler;
|
||||
|
||||
public CompiledStructureModifier() {
|
||||
super();
|
||||
customConvertHandling = true;
|
||||
}
|
||||
|
||||
// Speed up the default writer
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@ -35,6 +40,29 @@ public class CompiledStructureModifier<TField> extends StructureModifier<TField>
|
||||
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
|
||||
public StructureModifier<TField> withTarget(Object target) {
|
||||
if (compiler != null)
|
||||
|
@ -14,40 +14,39 @@ import com.google.common.base.Objects;
|
||||
|
||||
import net.sf.cglib.asm.*;
|
||||
|
||||
// This class will automatically generate the following type of structure modifier:
|
||||
//
|
||||
// public class CompiledStructure$Packet20NamedEntitySpawnObject<TField> extends CompiledStructureModifier<TField> {
|
||||
// public class CompiledStructureModifierPacket20<TField> extends CompiledStructureModifier<TField> {
|
||||
//
|
||||
// private Packet20NamedEntitySpawn typedTarget;
|
||||
//
|
||||
// public CompiledStructure$Packet20NamedEntitySpawnObject(StructureModifier<TField> other, StructureCompiler compiler) {
|
||||
//
|
||||
// public CompiledStructureModifierPacket20(StructureModifier<TField> other, StructureCompiler compiler) {
|
||||
// super();
|
||||
// initialize(other);
|
||||
// this.typedTarget = (Packet20NamedEntitySpawn) other.getTarget();
|
||||
// this.target = other.getTarget();
|
||||
// this.typedTarget = (Packet20NamedEntitySpawn) target;
|
||||
// this.compiler = compiler;
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// @Override
|
||||
// public TField read(int fieldIndex) throws FieldAccessException {
|
||||
// protected Object readGenerated(int fieldIndex) throws FieldAccessException {
|
||||
//
|
||||
// Packet20NamedEntitySpawn target = typedTarget;
|
||||
//
|
||||
// switch (fieldIndex) {
|
||||
// case 0: return (TField) (Object) target.a;
|
||||
// case 1: return (TField) (Object) target.b;
|
||||
// case 2: return (TField) (Object) target.c;
|
||||
// case 3: return (TField) (Object) target.d;
|
||||
// case 4: return (TField) (Object) target.e;
|
||||
// case 5: return (TField) (Object) target.f;
|
||||
// case 6: return (TField) (Object) target.g;
|
||||
// case 7: return (TField) (Object) target.h;
|
||||
// case 0: return (Object) target.a;
|
||||
// case 1: return (Object) target.b;
|
||||
// case 2: return (Object) target.c;
|
||||
// case 3: return super.read(fieldIndex);
|
||||
// case 4: return super.read(fieldIndex);
|
||||
// case 5: return (Object) target.f;
|
||||
// case 6: return (Object) target.g;
|
||||
// case 7: return (Object) target.h;
|
||||
// default:
|
||||
// throw new FieldAccessException("Invalid index " + fieldIndex);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public StructureModifier<TField> write(int index, Object value) {
|
||||
// protected StructureModifier<TField> writeGenerated(int index, Object value) throws FieldAccessException {
|
||||
//
|
||||
// Packet20NamedEntitySpawn target = typedTarget;
|
||||
//
|
||||
@ -56,8 +55,8 @@ import net.sf.cglib.asm.*;
|
||||
// case 1: target.b = (String) value; break;
|
||||
// case 2: target.c = (Integer) value; break;
|
||||
// case 3: target.d = (Integer) value; break;
|
||||
// case 4: target.e = (Integer) value; break;
|
||||
// case 5: target.f = (Byte) value; break;
|
||||
// case 4: super.write(index, value); break;
|
||||
// case 5: super.write(index, value); break;
|
||||
// case 6: target.g = (Byte) value; break;
|
||||
// case 7: target.h = (Integer) value; break;
|
||||
// default:
|
||||
@ -265,7 +264,7 @@ public final class StructureCompiler {
|
||||
|
||||
String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";";
|
||||
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 });
|
||||
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) {
|
||||
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" });
|
||||
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
||||
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren