Search in sources :

Example 1 with ExtendedClassWriter

use of com.bergerkiller.mountiplex.reflection.util.ExtendedClassWriter in project BKCommonLib by bergerhealer.

the class NullPacketDataSerializerInit method initialize.

/**
 * Makes sure to initialize the NullPacketDataSerializer.
 * A new class is generated and loaded with a static field storing the instance,
 * with the correct type. Inside generated code, it can be accessed
 * the following way:<br>
 * <br>
 * <pre>com.bergerkiller.bukkit.common.internal.logic.NullPacketDataSerializer.INSTANCE</pre>
 */
public static synchronized void initialize() {
    if (is_initialized) {
        return;
    } else {
        is_initialized = true;
    }
    // Only used on 1.17 and later
    if (CommonBootstrap.evaluateMCVersion("<", "1.17")) {
        return;
    }
    // any of this library's code, so it's fine to keep using that one.
    try {
        Class.forName(CLASS_NAME);
        return;
    } catch (ClassNotFoundException ex) {
    /* expected */
    }
    try {
        Class<?> dataSerializerType = Resolver.loadClass("net.minecraft.network.PacketDataSerializer", false);
        if (dataSerializerType == null) {
            throw new IllegalStateException("PacketDataSerializer class not found in server");
        }
        final ExtendedClassWriter<Object> cw = ExtendedClassWriter.builder(dataSerializerType).setExactName(CLASS_NAME).build();
        // Add a static INSTANCE field
        {
            FieldVisitor fv;
            fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, "INSTANCE", cw.getTypeDescriptor(), null, null);
            fv.visitEnd();
        }
        // Override all non-final non-private member methods of PacketDataSerializer
        ReflectionUtil.getAllMethods(dataSerializerType).filter(m -> {
            int modifiers = m.getModifiers();
            return !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers) && !Modifier.isFinal(modifiers);
        }).forEach(m -> {
            cw.visitMethodReturnConstant(m, BoxedType.getDefaultValue(m.getReturnType()));
        });
        // Instantiate and assign to the INSTANCE field
        Object instance = cw.generateInstanceNull();
        Field f = instance.getClass().getDeclaredField("INSTANCE");
        f.set(null, instance);
    } catch (Throwable t) {
        Logging.LOGGER_REFLECTION.log(Level.SEVERE, "Failed to initialize null packet data serializer", t);
    }
}
Also used : CommonBootstrap(com.bergerkiller.bukkit.common.internal.CommonBootstrap) Opcodes(org.objectweb.asm.Opcodes) ReflectionUtil(com.bergerkiller.mountiplex.reflection.ReflectionUtil) Modifier(java.lang.reflect.Modifier) FieldVisitor(org.objectweb.asm.FieldVisitor) Resolver(com.bergerkiller.mountiplex.reflection.resolver.Resolver) ExtendedClassWriter(com.bergerkiller.mountiplex.reflection.util.ExtendedClassWriter) Logging(com.bergerkiller.bukkit.common.Logging) BoxedType(com.bergerkiller.mountiplex.reflection.util.BoxedType) Field(java.lang.reflect.Field) Level(java.util.logging.Level) Field(java.lang.reflect.Field) FieldVisitor(org.objectweb.asm.FieldVisitor)

Aggregations

Logging (com.bergerkiller.bukkit.common.Logging)1 CommonBootstrap (com.bergerkiller.bukkit.common.internal.CommonBootstrap)1 ReflectionUtil (com.bergerkiller.mountiplex.reflection.ReflectionUtil)1 Resolver (com.bergerkiller.mountiplex.reflection.resolver.Resolver)1 BoxedType (com.bergerkiller.mountiplex.reflection.util.BoxedType)1 ExtendedClassWriter (com.bergerkiller.mountiplex.reflection.util.ExtendedClassWriter)1 Field (java.lang.reflect.Field)1 Modifier (java.lang.reflect.Modifier)1 Level (java.util.logging.Level)1 FieldVisitor (org.objectweb.asm.FieldVisitor)1 Opcodes (org.objectweb.asm.Opcodes)1