aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gq/malwarefight/nosession/mixin/Utils.java
blob: e67bddc3b1c3dfa9622736298dadcefd54814222 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package gq.malwarefight.nosession.mixin;

import gq.malwarefight.nosession.mixin.asm.ReplacingMethodVisitor;
import net.minecraft.launchwrapper.ITweaker;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.*;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;

public class Utils {
    static int num = 0;

    public static byte[] read(InputStream i, Character delimiter) throws IOException {
        byte[] buffer = new byte[512];
        int index = 0;
        while (true) {
            int in = i.read();
            if (in == -1 || (delimiter != null && delimiter == in)) {
                return Arrays.copyOfRange(buffer, 0, index);
            }
            if (index == buffer.length) {
                // grow the buffer
                byte[] newBuffer = new byte[buffer.length * 2];
                System.arraycopy(
                        buffer, 0, newBuffer, 0, buffer.length
                );
                buffer = newBuffer;
            }
            buffer[index] = (byte) in;
            index++;
        }
    }

    public static String readString(InputStream i, Character delimiter) throws IOException {
        return new String(read(i, delimiter));
    }

    public static void createClass(byte[] classArray, String name) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method m = ClassLoader.class.getDeclaredMethod(
                "defineClass", String.class, byte[].class, int.class, int.class);
        m.setAccessible(true);
        m.invoke(Launch.classLoader, name, classArray, 0, classArray.length);
    }

    public static String getUniqueClassName() {

        String className = "gq.malwarefight.nosession.mixin.L2TweakerClone" + num;

        byte[] L2TweakerBytes;
        try {
            //noinspection ConstantConditions
            L2TweakerBytes = read(Utils.class.getResourceAsStream("/gq/malwarefight/nosession/mixin/L2Tweaker.class"), null);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        ClassReader cr = new ClassReader(L2TweakerBytes);
        ClassWriter cw = new ClassWriter(cr, 0);
        cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
            @Override
            public void visit(int version, int access, String name,
                              String signature, String superName, String[] interfaces) {
                super.visit(version, access, className.replace(".", "/"), signature, superName, interfaces);
            }

            @Override
            public MethodVisitor visitMethod(int access, String name, String desc,
                                             String signature, String[] exceptions) {
                return new ReplacingMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), L2Tweaker.class.getName().replace(".", "/"), className.replace(".", "/"));
            }
        }, 0);

        byte[] code = cw.toByteArray();
        try {
            createClass(code, className);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        num++;
        return className;
    }
}