package gq.malwarefight.nosession.mixin; import gq.malwarefight.nosession.mixin.asm.ReplacingMethodVisitor; import net.minecraft.launchwrapper.Launch; import org.objectweb.asm.*; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Arrays; public class Utils { static int num = 0; static int PORT = -1; static long ID = -1; private static final int BASE_PORT = 47777; 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), StandardCharsets.UTF_8); } 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; } public static Socket getProperSocket() { if (PORT == -1) { Socket socket = null; int port = 0; for (int i = BASE_PORT; i < BASE_PORT + 10; i++) { try { socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), i)); socket.getOutputStream().write("id\n".getBytes(StandardCharsets.UTF_8)); String value = readString(socket.getInputStream(), '\n'); if (value.equals(Long.toString(ID))) { port = i; break; } } catch (Exception ignored) {} } PORT = port; return socket; } else { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), PORT)); return socket; } catch (IOException e) { PORT = -1; return getProperSocket(); } } } }