Hueihuea
本帖最后由 skpsk自己家 于 2019-3-31 18:39 编辑

http://www.mcbbs.net/thread-822754-1-1.html
该帖有这样一段代码

public class ChebishevTransformer implements IClassTransformer {
//IClassTransformer:MC自带的launchwrapper工具所提供的类转换接口
    @Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
        FMLLog.log.warn("[Transforming...]");
        //在这里输出一个告警信息,告诉大家你在做什么,可选项
        ClassNode classNode=new ClassNode(ASM5);
        //声明一个ASM5的classNode
        ClassReader classReader=new ClassReader(basicClass);
        //声明一个读取basicClass的classReader
        classReader.accept(classNode,0);
        //让classReader接收到要修改的classNode/classVisitor,以产生事件
        List<MethodNode> methodNodeList=new ArrayList<>(classNode.methods);
        //由于我们的目标是要修改方法,因此要遍历一下MethodNode,将其保存在list中
        for(MethodNode methodNode:methodNodeList){
            if (transformedName.equals("net.minecraft.util.math.MathHelper")&&methodNode.name.equals("func_76126_a(F)F")) {
            //if:transformedName是转换后的类名,因为你看到的代码是根据notch name反混淆出来的,methodName是它的srg name,    (F)F指参数为float,返回float
                methodNode.instructions.clear();
                //清除methodNode下的结构
                methodNode.instructions.add(new InsnNode(FLOAD))
                //添加你自己的实现,FLOAD代表传入float参数,其在ASM中规定的操作码(Opcode)是23
                methodNode.instructions.add(new MethodInsnNode
                        (ACC_PUBLIC + ACC_STATIC, "Lcom/forestbat/warhammer/asm/ChebishevTransformer", "sin", "(F)D", false));
                //添加上你自己的实现,ACC_PUBLIC,ACC_STATIC是ASM中public和static的操作码(分别是0x0001和0x0008);
                //“Lcom/forestbat/warhammer/asm/ChebishevTransformer”是owner参数,表明方法的源头类;
                //“sin”是name参数,表明我们的方法名;
                //“(F)D”是“float形参,返回double”的description(描述符);
                //false表明了owner类(不是)一个接口,若是,则为true
                methodNode.instructions.add(new InsnNode(DRETURN));
                //DRETURN代表返回double值,其操作码是175
            }
            ClassWriter classWriter = new ClassWriter(2);
            //声明一个classWriter写入内容,参数2的意义是COMPUTE_FRAMES,自动计算局部变量与操作数栈
            //每当方法被调用一次栈上就会生成一个帧,帧又被分为局部变量和操作数栈,COMPUTE_FRAMES会帮你自动计算,但会拖慢性能
            classNode.accept(classWriter);
            //classNode接收classWriter做参数,向方法内部生成二进制代码
            return classWriter.toByteArray();
        }
        return basicClass;
        //返回被修改的basicClass
}

这里返回的值起到什么作用呢
看错了
foreach里return也是普通的返回
哭了





2021.12 数据,可能有更多内容http://www.mcbbs.net/thread-822754-1-1.html
该帖有这样一段代码


public class ChebishevTransformer implements IClassTransformer {
//IClassTransformer:MC自带的launchwrapper工具所提供的类转换接口
    @Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
  FMLLog.log.warn(&quot;[Transforming...]&quot;);
  //在这里输出一个告警信息,告诉大家你在做什么,可选项
  ClassNode classNode=new ClassNode(ASM5);
  //声明一个ASM5的classNode
  ClassReader classReader=new ClassReader(basicClass);
  //声明一个读取basicClass的classReader
  classReader.accept(classNode,0);
  //让classReader接收到要修改的classNode/classVisitor,以产生事件
  List&lt;MethodNode&gt; methodNodeList=new ArrayList&lt;&gt;(classNode.methods);
  //由于我们的目标是要修改方法,因此要遍历一下MethodNode,将其保存在list中
  for(MethodNode methodNode:methodNodeList){
   if (transformedName.equals(&quot;net.minecraft.util.math.MathHelper&quot;)&amp;&amp;methodNode.name.equals(&quot;func_76126_a(F)F&quot;)) {
   //if:transformedName是转换后的类名,因为你看到的代码是根据notch name反混淆出来的,methodName是它的srg name,    (F)F指参数为float,返回float
    methodNode.instructions.clear();
    //清除methodNode下的结构
    methodNode.instructions.add(new InsnNode(FLOAD))
    //添加你自己的实现,FLOAD代表传入float参数,其在ASM中规定的操作码(Opcode)是23
    methodNode.instructions.add(new MethodInsnNode
   (ACC_PUBLIC + ACC_STATIC, &quot;Lcom/forestbat/warhammer/asm/ChebishevTransformer&quot;, &quot;sin&quot;, &quot;(F)D&quot;, false));
    //添加上你自己的实现,ACC_PUBLIC,ACC_STATIC是ASM中public和static的操作码(分别是0x0001和0x0008);
    //“Lcom/forestbat/warhammer/asm/ChebishevTransformer”是owner参数,表明方法的源头类;
    //“sin”是name参数,表明我们的方法名;
    //“(F)D”是“float形参,返回double”的description(描述符);
    //false表明了owner类(不是)一个接口,若是,则为true
    methodNode.instructions.add(new InsnNode(DRETURN));
    //DRETURN代表返回double值,其操作码是175
   }
   ClassWriter classWriter = new ClassWriter(2);
   //声明一个classWriter写入内容,参数2的意义是COMPUTE_FRAMES,自动计算局部变量与操作数栈
   //每当方法被调用一次栈上就会生成一个帧,帧又被分为局部变量和操作数栈,COMPUTE_FRAMES会帮你自动计算,但会拖慢性能
   classNode.accept(classWriter);
   //classNode接收classWriter做参数,向方法内部生成二进制代码
   return classWriter.toByteArray();
  }
  return basicClass;
  //返回被修改的basicClass
}


这里返回的值起到什么作用呢
看错了
foreach里return也是普通的返回
哭了



Lucky_fish0w0
这里返回的值返回的就是修改后的字节码数据, 将其提交给java进行加载.

Hueihuea
cx62d 发表于 2019-3-31 17:51
这里返回的值返回的就是修改后的字节码数据, 将其提交给java进行加载.

foreach的返回值要怎么接收呢……

森林蝙蝠
http://www.mcbbs.net/thread-822754-1-1.html
原代码有问题,for只会循环一次,已改正。