本帖最后由 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也是普通的返回
哭了
该帖有这样一段代码
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也是普通的返回
哭了
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("[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也是普通的返回
哭了
这里返回的值返回的就是修改后的字节码数据, 将其提交给java进行加载.
cx62d 发表于 2019-3-31 17:51
这里返回的值返回的就是修改后的字节码数据, 将其提交给java进行加载.
foreach的返回值要怎么接收呢……
http://www.mcbbs.net/thread-822754-1-1.html
原代码有问题,for只会循环一次,已改正。
原代码有问题,for只会循环一次,已改正。