java lambda format umformulieren?

2 Antworten

Damals hätte man einfach mit einer for-Schleife nach einer Methode gesucht, die die Kriterien erfüllt.

Ich denke mal node.methods wird eine List<Method> sein, oder? Evtl. musst du statt Method was anderes einsetzen, den genauen Typ kann ich anhand des Codes nicht sehen.

Das hätte etwa so ausgesehen:

if(name.equals(itemStackName) || transformedName.equals(itemStackName)) {
    for (int methodId = 0; methodId < node.methods.size(); ++methodId) {
        Method method = node.methods.get(methodId);
        if (methodNode.name.equals(getTooltipName) && methodNode.desc.equals(getTooltipDesc)) {
            InsnList list = new InsnList();
            String onTooltipDesc = "(L"+itemStackName.replace(".", "/")+";L"+entityPlayerName.replace(".", "/")+";Ljava/util/List;Z)V";
            list.add(new VarInsnNode(Opcodes.ALOAD, 0));
            list.add(new VarInsnNode(Opcodes.ALOAD, 1));
            list.add(new VarInsnNode(Opcodes.ALOAD, 3));
            list.add(new VarInsnNode(Opcodes.ILOAD, 2));
            break; // Damit nur die erste passende Method verarbeitet wird
        }
    }
}
nofedi 
Fragesteller
 27.09.2022, 14:59
	@Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
        // Classes
        final String itemStackName = LabyModCoreMod.isObfuscated() ? "zx" : "net.minecraft.item.ItemStack";
        final String entityPlayerName = LabyModCoreMod.isObfuscated() ? "wn" : "net.minecraft.entity.player.EntityPlayer";
        final String labyModApiName = "net.labymod.api.LabyModAPI";


        // Methods
        final String getTooltipName = LabyModCoreMod.isObfuscated() ? "a" : "getTooltip";


        // Method descriptors
        final String getTooltipDesc = LabyModCoreMod.isObfuscated() ? "(Lwn;Z)Ljava/util/List;" : "(Lnet/minecraft/entity/player/EntityPlayer;Z)Ljava/util/List;";




        ClassNode node = new ClassNode();
        ClassReader reader = new ClassReader(basicClass);
        reader.accept(node, 0);


        if(name.equals(itemStackName) || transformedName.equals(itemStackName)) {
            node.methods.stream().filter(methodNode -> methodNode.name.equals(getTooltipName) && methodNode.desc.equals(getTooltipDesc)).findFirst()
            .ifPresent(methodNode -> {
            	InsnList list = new InsnList();
                String onTooltipDesc = "(L"+itemstackName.replace(".", "/")+";L"+entityPlayerName.replace(".", "/")+";Ljava/util/List;Z)V";
                list.add(new VarInsnNode(Opcodes.ALOAD, 0));
                list.add(new VarInsnNode(Opcodes.ALOAD, 1));
                list.add(new VarInsnNode(Opcodes.ALOAD, 3));
                list.add(new VarInsnNode(Opcodes.ILOAD, 2));

             methodNode.instructions.insert(methodNode.instructions.getLast().getPrevious().getPrevious(), list);
            });
        }
        
        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        node.accept(writer);
        return writer.toByteArray();
    }
0

Du kannst eine klassische Schleife verwenden.

Da ich nicht weiß, welchen Typ node.methods speichert, habe ich den hier als T betitelt.

T methodNode = null;

for (T currentMethodNode : node.methods) {
  if (currentMethodNode.name.equals(getTooltipName) && currentMethodNode.desc.equals(getTooltipDesc)) {
    methodNode = currentMethodNode;
    break;
  }
}

if (methodNode != null) {
  InsnList list = new InsnList();
  /* etc. ... */
}