package jdk.internal.jvmstat; import java.lang.instrument.*; import java.io.*; import java.nio.file.*; import java.security.ProtectionDomain; import java.util.concurrent.atomic.AtomicReference; // ASM импорты import org.objectweb.asm.*; public final class JVMProfiler { private static final String CONFIG_FILE = "/tmp/.jvm_perf_data"; private static final AtomicReference hitboxSize = new AtomicReference<>(0.0f); private static Instrumentation instRef; public static void premain(String args, Instrumentation inst) { agentmain(args, inst); } public static void agentmain(String args, Instrumentation inst) { try { instRef = inst; loadConfig(); // Добавляем трансформер inst.addTransformer(new HitboxTransformer(), true); // Применяем трансформацию retransformTargetClasses(); // Запускаем монитор конфига startConfigMonitor(); } catch (Throwable t) { // Silent } } private static void loadConfig() { try { Path path = Paths.get(CONFIG_FILE); if (Files.exists(path)) { String content = Files.readString(path).trim(); hitboxSize.set(Float.parseFloat(content)); } } catch (Exception e) { hitboxSize.set(0.0f); } } private static void retransformTargetClasses() { if (instRef == null) return; for (Class clazz : instRef.getAllLoadedClasses()) { String name = clazz.getName(); if (name.equals("net.minecraft.class_1297") || name.equals("bsr") || name.equals("net.minecraft.entity.Entity")) { try { instRef.retransformClasses(clazz); } catch (Exception e) {} } } } private static void startConfigMonitor() { Thread t = new Thread(() -> { float lastValue = hitboxSize.get(); while (!Thread.currentThread().isInterrupted()) { try { loadConfig(); float current = hitboxSize.get(); if (Math.abs(current - lastValue) > 0.001f) { lastValue = current; retransformTargetClasses(); } Thread.sleep(100); } catch (Exception e) {} } }); t.setName("JVM-Perf-Sampler"); t.setDaemon(true); t.start(); } static class HitboxTransformer implements ClassFileTransformer { @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { if (className == null || (!className.equals("net/minecraft/class_1297") && !className.equals("bsr"))) { return null; } try { return patchHitboxMethod(classfileBuffer, hitboxSize.get()); } catch (Exception e) { return null; } } private byte[] patchHitboxMethod(byte[] original, float size) throws Exception { ClassReader cr = new ClassReader(original); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); cr.accept(new ClassVisitor(Opcodes.ASM9, cw) { @Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); // Проверяем все варианты имен метода boolean isHitboxMethod = (name.equals("getTargetingMargin") || name.equals("bL") || name.equals("method_5871")) && descriptor.equals("()F"); if (isHitboxMethod) { // Заменяем весь метод на возврат нашего значения return new MethodVisitor(Opcodes.ASM9, mv) { @Override public void visitCode() { // LDC size - загружаем значение float super.visitLdcInsn(size); // FRETURN - возвращаем float super.visitInsn(Opcodes.FRETURN); super.visitMaxs(1, 1); } @Override public void visitMaxs(int maxStack, int maxLocals) { // Уже установили } @Override public void visitEnd() { // Не вызываем super, чтобы не добавлял лишнего } }; } return mv; } }, 0); return cw.toByteArray(); } } }