tk.wurst_client.hooks.injector.MethodHookInjector.java Source code

Java tutorial

Introduction

Here is the source code for tk.wurst_client.hooks.injector.MethodHookInjector.java

Source

/*
 * Copyright  2015 | Alexander01998 | All rights reserved.
 * 
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package tk.wurst_client.hooks.injector;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import tk.wurst_client.hooks.reader.data.HookData;
import tk.wurst_client.hooks.reader.data.HookPosition;
import tk.wurst_client.hooks.reader.data.MethodData;

public class MethodHookInjector extends MethodVisitor {
    private String methodName;
    private String className;
    private MethodData methodData;
    private int paramCount;

    public MethodHookInjector(int api, MethodVisitor mv, MethodData methodData, String className,
            String methodName) {
        super(api, mv);
        this.methodName = methodName;
        this.className = className;
        this.methodData = methodData;

        paramCount = 0;
        if (methodName.contains(";"))
            paramCount = methodName.substring(methodName.indexOf("("), methodName.lastIndexOf(")"))
                    .split(";").length;
    }

    @Override
    public void visitCode() {
        super.visitCode();
        if (methodData.hasHookAt(HookPosition.METHOD_START)) {
            HookData hookData = methodData.getHook(HookPosition.METHOD_START);
            super.visitLdcInsn(className + "." + methodName + "|start");

            if (hookData.collectsParams()) {
                super.visitIntInsn(Opcodes.BIPUSH, paramCount);
                super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
                for (byte i = 0; i < paramCount; i++) {
                    super.visitInsn(Opcodes.DUP);
                    super.visitIntInsn(Opcodes.BIPUSH, i);
                    super.visitVarInsn(Opcodes.ALOAD, i);
                    super.visitInsn(Opcodes.AASTORE);
                }
            }

            // TODO: Custom class path
            super.visitMethodInsn(Opcodes.INVOKESTATIC, "tk/wurst_client/hooks/HookManager", "hook",
                    "(Ljava/lang/String;" + (hookData.collectsParams() ? "[Ljava/lang/Object;" : "") + ")V", false);
        }
    }

    @Override
    public void visitInsn(int opcode) {
        if (methodData.hasHookAt(HookPosition.METHOD_END) && opcode >= 172 && opcode <= 177) {
            HookData hookData = methodData.getHook(HookPosition.METHOD_END);
            super.visitLdcInsn(className + "." + methodName + "|end");

            if (hookData.collectsParams()) {

                super.visitIntInsn(Opcodes.BIPUSH, paramCount);
                super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
                for (byte i = 0; i < paramCount; i++) {
                    super.visitInsn(Opcodes.DUP);
                    super.visitIntInsn(Opcodes.BIPUSH, i);
                    super.visitVarInsn(Opcodes.ALOAD, i);
                    super.visitInsn(Opcodes.AASTORE);
                }
            }

            // TODO: Custom class path
            super.visitMethodInsn(Opcodes.INVOKESTATIC, "tk/wurst_client/hooks/HookManager", "hook",
                    "(Ljava/lang/String;" + (hookData.collectsParams() ? "[Ljava/lang/Object;" : "") + ")V", false);
        }
        super.visitInsn(opcode);
    }
}