|ASM| Почему этот код не работает? (можно закрывать)

1,239
2
24
Привет всем.Есть несколько классов
1)
Код:
package com.vikestep.anticacti;

import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;

import static org.objectweb.asm.Opcodes.*;

import java.util.Arrays;

public class AntiCactiClassTransformer implements IClassTransformer
{
    private static final String[] classesBeingTransformed =
            {
                    "net.minecraft.block.BlockCactus"
            };

    private static final boolean isBadMethod = false;

    @Override
    public byte[] transform(String name, String transformedName, byte[] classBeingTransformed)
    {
        boolean isObfuscated = !name.equals(transformedName);
        int index = Arrays.asList(classesBeingTransformed).indexOf(transformedName);
        return index != -1 ? transform(index, classBeingTransformed, isObfuscated) : classBeingTransformed;
    }

    private static byte[] transform(int index, byte[] classBeingTransformed, boolean isObfuscated)
    {
        System.out.println("Transforming: " + classesBeingTransformed[index]);
        try
        {
            ClassNode classNode = new ClassNode();
            ClassReader classReader = new ClassReader(classBeingTransformed);
            classReader.accept(classNode, 0);

            switch(index)
            {
                case 0:
                    transformBlockCactus(classNode, isObfuscated);
                    break;
            }

            ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
            classNode.accept(classWriter);
            return classWriter.toByteArray();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return classBeingTransformed;
    }

    private static void transformBlockCactus(ClassNode blockCactusClass, boolean isObfuscated)
    {
        final String ENTITY_COLLIDE = isObfuscated ? "a" : "onEntityCollidedWithBlock";
        final String ENTITY_COLLIDE_DESC = isObfuscated ? "(Lahb;IIILsa;)V" : "(Lnet/minecraft/world/World;IIILnet/minecraft/entity/Entity;)V";

        for (MethodNode method : blockCactusClass.methods)
        {
            if (method.name.equals(ENTITY_COLLIDE) && method.desc.equals(ENTITY_COLLIDE_DESC))
            {
                AbstractInsnNode targetNode = null;
                for (AbstractInsnNode instruction : method.instructions.toArray())
                {
                    if (instruction.getOpcode() == ALOAD)
                    {
                        if (((VarInsnNode) instruction).var == 5 && instruction.getNext().getOpcode() == GETSTATIC)
                        {
                            targetNode = instruction;
                            break;
                        }
                    }
                }
                if (targetNode != null && isBadMethod)
                {
                    /*
                    REMOVING:
                    mv.visitVarInsn(ALOAD, 5);
                    mv.visitFieldInsn(GETSTATIC, "net/minecraft/util/DamageSource", "cactus", "Lnet/minecraft/util/DamageSource;");
                    mv.visitInsn(FCONST_1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/Entity", "attackEntityFrom", "(Lnet/minecraft/util/DamageSource;F)Z", false);
                    mv.visitInsn(POP);
                     */

                    for (int i = 0; i < 5; i++)
                    {
                        targetNode = targetNode.getNext();
                        method.instructions.remove(targetNode.getPrevious());
                    }

                    //Wrapping this in a conditional
                }
                else if (targetNode != null)
                {
                    /*
                    Replacing:
                        p_149670_5_.attackEntityFrom(DamageSource.cactus, 1.0F);
                    With:
                        if (Hooks.cactusDoesDamage(p_149670_5_))
                        {
                            p_149670_5_.attackEntityFrom(DamageSource.cactus, 1.0F);
                        }

                    BYTECODE

                    Replacing:
                        mv.visitVarInsn(ALOAD, 5);
                        mv.visitFieldInsn(GETSTATIC, "net/minecraft/util/DamageSource", "cactus", "Lnet/minecraft/util/DamageSource;");
                        mv.visitInsn(FCONST_1);
                        mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/Entity", "attackEntityFrom", "(Lnet/minecraft/util/DamageSource;F)Z", false);
                        mv.visitInsn(POP);
                    With:
                        ALOAD 5
                        INVOKEVIRTUAL Hooks.cactusDoesDamage(net/minecraft/entity/Entity)
                        IFEQ newLabelNode
                        mv.visitVarInsn(ALOAD, 5);
                        mv.visitFieldInsn(GETSTATIC, "net/minecraft/util/DamageSource", "cactus", "Lnet/minecraft/util/DamageSource;");
                        mv.visitInsn(FCONST_1);
                        mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/Entity", "attackEntityFrom", "(Lnet/minecraft/util/DamageSource;F)Z", false);
                        mv.visitInsn(POP);
                        LABEL newLabelNode
                     */

                    AbstractInsnNode popNode = targetNode;
                    for (int i = 0; i < 4; i++)
                    {
                        popNode = popNode.getNext();
                    }

                    LabelNode newLabelNode = new LabelNode();

                    InsnList toInsert = new InsnList();
                    toInsert.add(new VarInsnNode(ALOAD, 5));
                    toInsert.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Hooks.class), "cactusDoesDamage", isObfuscated ? "(Lsa;)Z" : "(Lnet/minecraft/entity/Entity;)Z", false));
                    toInsert.add(new JumpInsnNode(IFEQ, newLabelNode));

                    method.instructions.insertBefore(targetNode, toInsert);
                    method.instructions.insert(popNode, newLabelNode);
                }
                else
                {
                    System.out.println("Something went wrong transforming BlockCactus!");
                }
            }
        }
    }
}

2)
Код:
package com.vikestep.anticacti;

import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.ModMetadata;

import java.util.Arrays;

public class AntiCactiModContainer extends DummyModContainer
{
    public AntiCactiModContainer()
    {
        super(new ModMetadata());
        ModMetadata meta = getMetadata();
        meta.modId = "anticacti";
        meta.name = "AntiCacti";
        meta.description = "Stops Cactus Damage";
        meta.version = "1.7.10-1.0";
        meta.authorList = Arrays.asList("VikeStep");
    }

    @Override
    public boolean registerBus(EventBus bus, LoadController controller)
    {
        bus.register(this);
        return true;
    }
}

3)

Код:
package com.vikestep.anticacti;

import cpw.mods.fml.relauncher.IFMLLoadingPlugin;

import java.util.Map;

@IFMLLoadingPlugin.MCVersion("1.7.10")
@IFMLLoadingPlugin.TransformerExclusions({"com.vikestep.anticacti"})
public class AntiCactiPlugin implements IFMLLoadingPlugin
{
    @Override
    public String[] getASMTransformerClass()
    {
        return new String[]{"com.vikestep.anticacti.AntiCactiClassTransformer"};
    }

    @Override
    public String getModContainerClass()
    {
        return "com.vikestep.anticacti.AntiCactiModContainer";
    }

    @Override
    public String getSetupClass()
    {
        return null;
    }

    @Override
    public void injectData(Map<String, Object> data)
    {

    }

    @Override
    public String getAccessTransformerClass()
    {
        return null;
    }
}

4)

Код:
package com.vikestep.anticacti;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;

public class Hooks
{
    public static boolean cactusDoesDamage(Entity entity)
    {
        return !(entity instanceof EntityPlayer);
    }
}

Сурсы https://github.com/VikeStep/Coremod-Tutorial
Дело в том что если залить исходники ничего не изменяется,а должно быть так что кактус не наносит урон игроку.Что я неправильно делаю?
 
так стоп.Мод вообще почему то не отображается в списке активных в разделе mods .Попробуйте кто то скомпилить у себя
 
Добавил аннотацию "мод" все равно так же.У автора на видео видно в консоле что он запускается с 3 модами (mcp,forge,FML) и все работает
 
а ты видел, он добавил в запуск игры через eclipse, запуск модуля....
(я не проверял работоспособность кода, пока не до этого)
 
А теперь, внимание на экран! https://youtu.be/75_rJYLj5AU?t=2049
 
код полностью рабочий, консоль в студию.
ну и не забудь, что есть режим debug, в котором можно поставить брэекпоинты и убедится до какого места твой код работает.
(в крайнем случае натыкать System.out.println( "мы тут" ); )
 
Ребят,тема не совсем актуальна,я уже редактирую классы майнкрафта напрямую
 
Чтобы кормоды работали в IDE, их надо регистрировать в строке запуска. В VM options:
-Dfml.coreMods.load=mymod.asm.MyLoadingPlugin.
Чтобы кормоды работали в собранном виде, нужно указать в манифесте, что это кормод. В mod.zip/META-INF/MANIFEST.MF:
FMLCorePlugin: gloomyfolken.mods.effects.asm.EffectsLoadingPlugin
 
Интересное вот что: автор кода написал мод в котором можно отключать мобов,предметы,ну что то вроде конфига для майнкрафта.Я его скачал и убрал у кактуса дамаг .И даже так кактус наносил дамаг хотя с отключением мобов все работает.Может это мой майнкрафт кривой?
 
код работает как в запуске IDE так и в сборке как мод.
 
Скинте сюда собраный мод я хочу точно убедится что это проблема майнкрафта а не меня
 
Назад
Сверху