[1.7.10]ASM - как заменить класс?

771
5
Никогда это не делал.Как заменить класс на свой? Нужно проправить ItemStack.
Как вы знаете, в 1.7 нельзя изменять исходники.
Нужно для проекта, так что о совместимости думать не стоит =)
P.S Равен как-то выкладывал тутор, но его удалили..
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
Majestic написал(а):
Плохой вариант, зачем же заменять если тебе там только чего поправить надо?
А чего поправить надо кстати? Может можно и без ASM(если это не какое-то тупое увеличение размера стака, тогда слот надо патчить).
 
2,955
12
Ну... Вообще слот берет макс стак сайз с инвентаря к которому привязан.
 
2,955
12
Вот пример трансформера. Думаю как зарегать его ты сообразишь.
Код:
import net.minecraft.item.ItemSword;
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.ClassNode;
import org.objectweb.asm.tree.MethodNode;

//Это айда няшка написала, не стал убирать.
/**
 * Created by Dragon2488 on 04.09.2014.
 */

public class Transformer implements IClassTransformer {
    @Override
    public byte[] transform(String s, String s2, byte[] bytes) {
        //Если класс наш - делаем с ним все что надо, а если нет - нафиг его.
        //Type.getInternalName дает нам путь к классу, в скомпилированной среде. То есть в эклипсе прокатит net.minecraft.item.ItemSword, а в скомпилированном только net/minecraft/item/ItemSword.
        if (s.equals(Type.getInternalName(ItemSword.class)) || s2.equals(Type.getInternalName(ItemSword.class)) || s.equals("net.minecraft.item.ItemSword") || s2.equals("net.minecraft.item.ItemSword")) {
            //Создаем считыватель классов из байтов.
            ClassReader reader = new ClassReader(bytes);
            //Создаем, так сказать 'класс'.
            ClassNode clazz = new ClassNode();
            //Реадер передает этому классу инфу у том что он считал. То есть сейчас clazz это класс net.minecraft.item.ItemSword
            reader.accept(clazz, 0);

            //Тут мы и будем мутить то что нам надо.
            //Перебераем методы из класса.
            for(MethodNode method : clazz.methods) {
                //Если имя метода addInformation, то делаем то что нам надо.
                //Тут еще должно быть егюалс на обфуцированное имя метода, но мне лень искать обфуцированное имя метода addInformation
                if(method.name.equals("addInformation")) {
                    //Удалем метод из класса.
                    clazz.methods.remove(method);
                }
            }

            //Создаем того кто пишет наш класс обратно в байты и не даем ему никаких флагов.
            ClassWriter writer = new ClassWriter(0);
            //Говорим ему трансформировать наш класс назад в байты.
            clazz.accept(writer);
            //Возвращаем наши байты.
            return writer.toByteArray();
            
        } else {
            return bytes;
        }
    }
}
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
Dragon2488 написал(а):
Вот пример трансформера. Думаю как зарегать его ты сообразишь.
Код:
import net.minecraft.item.ItemSword;
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.ClassNode;
import org.objectweb.asm.tree.MethodNode;

//Это айда няшка написала, не стал убирать.
/**
 * Created by Dragon2488 on 04.09.2014.
 */

public class Transformer implements IClassTransformer {
    @Override
    public byte[] transform(String s, String s2, byte[] bytes) {
        //Если класс наш - делаем с ним все что надо, а если нет - нафиг его.
        //Type.getInternalName дает нам путь к классу, в скомпилированной среде. То есть в эклипсе прокатит net.minecraft.item.ItemSword, а в скомпилированном только net/minecraft/item/ItemSword.
        if (s.equals(Type.getInternalName(ItemSword.class)) || s2.equals(Type.getInternalName(ItemSword.class)) || s.equals("net.minecraft.item.ItemSword") || s2.equals("net.minecraft.item.ItemSword")) {
            //Создаем считыватель классов из байтов.
            ClassReader reader = new ClassReader(bytes);
            //Создаем, так сказать 'класс'.
            ClassNode clazz = new ClassNode();
            //Реадер передает этому классу инфу у том что он считал. То есть сейчас clazz это класс net.minecraft.item.ItemSword
            reader.accept(clazz, 0);

            //Тут мы и будем мутить то что нам надо.
            //Перебераем методы из класса.
            for(MethodNode method : clazz.methods) {
                //Если имя метода addInformation, то делаем то что нам надо.
                //Тут еще должно быть егюалс на обфуцированное имя метода, но мне лень искать обфуцированное имя метода addInformation
                if(method.name.equals("addInformation")) {
                    //Удалем метод из класса.
                    clazz.methods.remove(method);
                }
            }

            //Создаем того кто пишет наш класс обратно в байты и не даем ему никаких флагов.
            ClassWriter writer = new ClassWriter(0);
            //Говорим ему трансформировать наш класс назад в байты.
            clazz.accept(writer);
            //Возвращаем наши байты.
            return writer.toByteArray();
            
        } else {
            return bytes;
        }
    }
}
Ты не представляешь, насколько ты увеличил моё знание ASM только-что.
[merge_posts_bbcode]Добавлено: 04.09.2014 17:58:18[/merge_posts_bbcode]

И ты забыл, что классы тоже обфусцируются.
 
771
5
anti344 написал(а):
Ты не представляешь, насколько ты увеличил моё знание ASM только-что.
Сарказм?
[merge_posts_bbcode]Добавлено: 04.09.2014 21:12:54[/merge_posts_bbcode]

Вопрос немного не по теме.Почему когда я пишу null вот тут, то у меня крашит?
ObfuscationReflectionHelper.setPrivateValue(clazz, null, 2.0F, "field_150934_a");
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
1,990
18
105
Majestic написал(а):
Вопрос немного не по теме.Почему когда я пишу null вот тут, то у меня крашит?
ObfuscationReflectionHelper.setPrivateValue(clazz, null, 2.0F, "field_150934_a");
Мимо-без-знания-ASM-попробую-угадать.
Эта фигня требует обьект, у которого надо изменить переменную, а ты передаешь вместо ссылки на обьект ссылку на пустоту?
Или та переменная статичная?
 
771
5
Да я уже понял.
Переменная инициализируется в конструкторе, а так как нету инстанса, значит конструктор не вызывался.
 
2,955
12
Думаю ты сам найдешь обфуцированное имя метода и класса. Аль мне все же найти?
P.S Я тоже сначала подумал, что то что сказал анти - сарказм, но потом вспомнил о том когда он писал что нифига не знает ASM.
 
771
5
Имена нашел, но я не могу его зарегать.
 
Сверху