All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.fierioziy.asm.ServerConnectionASM Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package com.github.fierioziy.asm;

import com.github.fierioziy.api.PlayerConnection;
import com.github.fierioziy.api.ServerConnection;
import org.objectweb.asm.*;

/**
 * 

Class responsible for providing bytecode of ServerConnection * and PlayerConnection classes.

*/ public class ServerConnectionASM extends BaseASM { /** *

A Type object representing ServerConnection class.

*/ private Type serverConnType = Type.getType(ServerConnection.class); /** *

A Type object representing PlayerConnection class.

*/ private Type playerConnType = Type.getType(PlayerConnection.class); /** *

A Type object representing implementation * of ServerConnection class.

*/ private Type serverConnTypeImpl = getTypeImpl(serverConnType); /** *

A Type object representing implementation * of PlayerConnection class.

*/ private Type playerConnTypeImpl = getTypeImpl(playerConnType); public ServerConnectionASM(String version) { super(version); } /** *

Gets a Type object representing an implementation * of class represented by parameter Type object.

* * @param superType a Type object associated * with base class. * @return a Type object representing class * extending or implementing parameter's class represented * by Type object. */ private Type getTypeImpl(Type superType) { return getTypeImpl(superType, "_Impl"); } /** *

Creates a bytecode of class implementing ServerConnection * interface. * * @return a {@code byte[]} array containing bytecode of class * implementing ServerConnection interface. * @see ServerConnection */ public byte[] createServerConnection() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, serverConnTypeImpl.getInternalName(), null, "java/lang/Object", new String[] { serverConnType.getInternalName() }); /* Generates default constructor. */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } /* Generates method that instantiates PlayerConnection interface implementation. */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "createPlayerConnection", "(Lorg/bukkit/entity/Player;)" + playerConnType.getDescriptor(), null, null); mv.visitCode(); mv.visitTypeInsn(NEW, playerConnTypeImpl.getInternalName()); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, playerConnTypeImpl.getInternalName(), "", "(Lorg/bukkit/entity/Player;)V", false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } /* Generates method that extracts NMS PlayerConnection from Player and sends packet object (cast from Object to Packet is performed). */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sendPacket", "(Lorg/bukkit/entity/Player;Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, OBC + "/entity/CraftPlayer"); mv.visitMethodInsn(INVOKEVIRTUAL, OBC + "/entity/CraftPlayer", "getHandle", "()" + desc(NMS + "/EntityPlayer"), false); mv.visitFieldInsn(GETFIELD, NMS + "/EntityPlayer", "playerConnection", desc(NMS + "/PlayerConnection")); mv.visitVarInsn(ALOAD, 2); mv.visitTypeInsn(CHECKCAST, NMS + "/Packet"); mv.visitMethodInsn(INVOKEVIRTUAL, NMS + "/PlayerConnection", "sendPacket", "(" + desc(NMS + "/Packet") + ")V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } /* Generates method that extracts NMS PlayerConnection from each Player and sends packet object (cast from Object to Packet is performed before loop). */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sendPacket", "(Ljava/util/Collection;Ljava/lang/Object;)V", "(Ljava/util/Collection;Ljava/lang/Object;)V", null); mv.visitCode(); // Packet nmsPacket = (Packet) packet; mv.visitVarInsn(ALOAD, 2); mv.visitTypeInsn(CHECKCAST, NMS + "/Packet"); mv.visitVarInsn(ASTORE, 3); // int length = player.size(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "size", "()I", true); mv.visitVarInsn(ISTORE, 4); // Iterator it = players.iterator(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "iterator", "()Ljava/util/Iterator;", true); mv.visitVarInsn(ASTORE, 5); // for (int i = 0 mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 6); Label loopBegin = new Label(); Label loopEnd = new Label(); // i < length mv.visitLabel(loopBegin); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 4); mv.visitJumpInsn(IF_ICMPGE, loopEnd); // ((CraftPlayer) it.next()).getHandle() mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); mv.visitTypeInsn(CHECKCAST, OBC + "/entity/CraftPlayer"); mv.visitMethodInsn(INVOKEVIRTUAL, OBC + "/entity/CraftPlayer", "getHandle", "()" + desc(NMS + "/EntityPlayer"), false); // .playerConnection mv.visitFieldInsn(GETFIELD, NMS + "/EntityPlayer", "playerConnection", desc(NMS + "/PlayerConnection")); // .sendPacket(nmsPacket); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, NMS + "/PlayerConnection", "sendPacket", "(" + desc(NMS + "/Packet") + ")V", false); // ; ++i) mv.visitIincInsn(6, 1); mv.visitJumpInsn(GOTO, loopBegin); mv.visitLabel(loopEnd); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } /* Generates method that iterates over players from Location's world and checks, if player is within range. A NMS PlayerConnection is then extracted and used to send packet object (casted from Object to Packet before entering loop). */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sendPacket", "(Lorg/bukkit/Location;DLjava/lang/Object;)V", null, null); mv.visitCode(); // radius *= radius; mv.visitVarInsn(DLOAD, 2); mv.visitVarInsn(DLOAD, 2); mv.visitInsn(DMUL); mv.visitVarInsn(DSTORE, 2); // Packet nmsPacket = (Packet) packet; mv.visitVarInsn(ALOAD, 4); mv.visitTypeInsn(CHECKCAST, NMS + "/Packet"); mv.visitVarInsn(ASTORE, 5); // double x = loc.getX(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getX", "()D", false); mv.visitVarInsn(DSTORE, 6); // double y = loc.getY(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getY", "()D", false); mv.visitVarInsn(DSTORE, 8); // double z = loc.getZ(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getZ", "()D", false); mv.visitVarInsn(DSTORE, 10); // 2x loc.getWorld().getPlayers() mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getWorld", "()Lorg/bukkit/World;", false); mv.visitMethodInsn(INVOKEINTERFACE, "org/bukkit/World", "getPlayers", "()Ljava/util/List;", true); mv.visitInsn(DUP); // int length = players.size(); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true); mv.visitVarInsn(ISTORE, 12); // Iterator it = players.iterator(); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true); mv.visitVarInsn(ASTORE, 13); // for (int i = 0 mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 14); Label loopBegin = new Label(); Label loopEnd = new Label(); // i < length mv.visitLabel(loopBegin); mv.visitVarInsn(ILOAD, 14); mv.visitVarInsn(ILOAD, 12); mv.visitJumpInsn(IF_ICMPGE, loopEnd); // CraftPlayer p = (CraftPlayer) it.next(); mv.visitVarInsn(ALOAD, 13); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); mv.visitTypeInsn(CHECKCAST, OBC + "/entity/CraftPlayer"); mv.visitVarInsn(ASTORE, 15); // Location pLoc = p.getLocation(); mv.visitVarInsn(ALOAD, 15); mv.visitMethodInsn(INVOKEVIRTUAL, OBC + "/entity/CraftPlayer", "getLocation", "()Lorg/bukkit/Location;", false); mv.visitVarInsn(ASTORE, 16); // radius if statement // (pLoc.getX() - x)^2 mv.visitVarInsn(ALOAD, 16); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getX", "()D", false); mv.visitVarInsn(DLOAD, 6); mv.visitInsn(DSUB); mv.visitInsn(DUP2); mv.visitInsn(DMUL); // + (pLoc.getY() - y)^2 mv.visitVarInsn(ALOAD, 16); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getY", "()D", false); mv.visitVarInsn(DLOAD, 8); mv.visitInsn(DSUB); mv.visitInsn(DUP2); mv.visitInsn(DMUL); mv.visitInsn(DADD); // + (pLoc.getZ() - z)^2) mv.visitVarInsn(ALOAD, 16); mv.visitMethodInsn(INVOKEVIRTUAL, "org/bukkit/Location", "getZ", "()D", false); mv.visitVarInsn(DLOAD, 10); mv.visitInsn(DSUB); mv.visitInsn(DUP2); mv.visitInsn(DMUL); mv.visitInsn(DADD); // if (distSquared <= radius) { mv.visitVarInsn(DLOAD, 2); Label notSendLabel = new Label(); mv.visitInsn(DCMPL); mv.visitJumpInsn(IFGT, notSendLabel); // p.getHandle().playerConnection mv.visitVarInsn(ALOAD, 15); mv.visitMethodInsn(INVOKEVIRTUAL, OBC + "/entity/CraftPlayer", "getHandle", "()" + desc(NMS + "/EntityPlayer"), false); mv.visitFieldInsn(GETFIELD, NMS + "/EntityPlayer", "playerConnection", desc(NMS + "/PlayerConnection")); // .sendPacket(packet); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKEVIRTUAL, NMS + "/PlayerConnection", "sendPacket", "(" + desc(NMS + "/Packet") + ")V", false); // } mv.visitLabel(notSendLabel); // ; ++i) mv.visitIincInsn(14, 1); mv.visitJumpInsn(GOTO, loopBegin); mv.visitLabel(loopEnd); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } /** *

Creates a bytecode of class implementing PlayerConnection * interface. * * @return a {@code byte[]} array containing bytecode of class * implementing PlayerConnection interface. * @see PlayerConnection */ public byte[] createPlayerConnection() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, playerConnTypeImpl.getInternalName(), null, "java/lang/Object", new String[] { playerConnType.getInternalName() }); { FieldVisitor fv = cw.visitField(ACC_PRIVATE, "playerConnection", desc(NMS + "/PlayerConnection"), null, null); fv.visitEnd(); } /* Generates constructor that extracts NMS PlayerConnection from player object and stores it in field. */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "(" + desc("org/bukkit/entity/Player") + ")V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, OBC + "/entity/CraftPlayer"); mv.visitMethodInsn(INVOKEVIRTUAL, OBC + "/entity/CraftPlayer", "getHandle", "()" + desc(NMS + "/EntityPlayer"), false); mv.visitFieldInsn(GETFIELD, NMS + "/EntityPlayer", "playerConnection", desc(NMS + "/PlayerConnection")); mv.visitFieldInsn(PUTFIELD, playerConnTypeImpl.getInternalName(), "playerConnection", desc(NMS + "/PlayerConnection")); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } /* Method that casts provided object to Packet and send it using NMS PlayerConnection from field. */ { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sendPacket", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, playerConnTypeImpl.getInternalName(), "playerConnection", desc(NMS + "/PlayerConnection")); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, NMS + "/Packet"); mv.visitMethodInsn(INVOKEVIRTUAL, NMS + "/PlayerConnection", "sendPacket", "(" + desc(NMS + "/Packet") + ")V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy