проблемы с хуком в конструктор

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#1
Версия Minecraft
1.7.10
Подтверждение
Я максимально подробно описал проблему, включая исходный код файлов, краш лог, изображения и другую информацию, которая может помочь пользователям форума решить мой вопрос!
добрый день
использую хук-либу от gloomyfolken
столкнулся с необходимостью хукнуть конструктор класса BiomeGenBase, нужно полностью его заменить, а не в начало или конец вставить код
мод вакумный и все нотации по типу "зачем так делать" мне не интересны
проблема в том, что я не очень понимаю, как правильно указывать все параметры в анотации и характерестики метода для хука(тип возвращаемоего значения)
при моем текущем варианте, проиходит краш при запуске

хук:
@Hook(createMethod = true, returnCondition = ReturnCondition.ALWAYS, targetMethod = "<init>")
    public static void BiomeGenBase(BiomeGenBase biomeGenBase, int p_i1971_1_, boolean register)
    {
        biomeGenBase.topBlock = Blocks.grass;
        biomeGenBase.field_150604_aj = 0;
        biomeGenBase.fillerBlock = Blocks.dirt;
        biomeGenBase.field_76754_C = 5169201;
        biomeGenBase.rootHeight = biomeGenBase.height_Default.rootHeight;
        biomeGenBase.heightVariation = biomeGenBase.height_Default.variation;
        biomeGenBase.temperature = 0.5F;
        biomeGenBase.rainfall = 0.5F;
        biomeGenBase.waterColorMultiplier = 16777215;
        biomeGenBase.spawnableMonsterList = new ArrayList();
        biomeGenBase.spawnableCreatureList = new ArrayList();
        biomeGenBase.spawnableWaterCreatureList = new ArrayList();
        biomeGenBase.spawnableCaveCreatureList = new ArrayList();
        biomeGenBase.enableRain = true;
        biomeGenBase.worldGeneratorTrees = new WorldGenTrees(false);
        biomeGenBase.worldGeneratorBigTree = new WorldGenBigTree(false);
        biomeGenBase.worldGeneratorSwamp = new WorldGenSwamp();
        biomeGenBase.biomeID = p_i1971_1_;
        if (register)
        biomeGenBase.biomeList[p_i1971_1_] = biomeGenBase;
        biomeGenBase.theBiomeDecorator = biomeGenBase.createBiomeDecorator();
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySheep.class, 12, 4, 4));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityPig.class, 10, 4, 4));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityChicken.class, 10, 4, 4));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityCow.class, 8, 4, 4));
        //biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntitySpider.class, 100, 4, 4));
        //biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntityZombie.class, 100, 4, 4));
        //biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntitySkeleton.class, 100, 4, 4));
        //biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntityCreeper.class, 100, 4, 4));
        biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntitySlime.class, 100, 4, 4));
        //biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntityEnderman.class, 10, 1, 4));
        biomeGenBase.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(EntityWitch.class, 5, 1, 1));
        //biomeGenBase.spawnableWaterCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySquid.class, 10, 4, 4));
        biomeGenBase.spawnableCaveCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityBat.class, 10, 8, 8));
        biomeGenBase.addDefaultFlowers();
    }
краш:
java.lang.ExceptionInInitializerError
    at net.minecraftforge.common.BiomeDictionary.<clinit>(BiomeDictionary.java:113)
    at net.minecraftforge.common.ForgeModContainer.postInit(ForgeModContainer.java:290)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
    at com.google.common.eventbus.EventBus.post(EventBus.java:275)
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212)
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
    at com.google.common.eventbus.EventBus.post(EventBus.java:275)
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119)
    at cpw.mods.fml.common.Loader.initializeMods(Loader.java:742)
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:311)
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:597)
    at net.minecraft.client.Minecraft.run(Minecraft.java:942)
    at net.minecraft.client.main.Main.main(Main.java:164)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
    at GradleStart.main(Unknown Source)
Caused by: java.lang.NullPointerException
    at net.minecraft.world.biome.BiomeGenBase.addDefaultFlowers(BiomeGenBase.java:642)
    at ru.Pa4ok.mod.core.hooks.BiomeGenBaseHook.BiomeGenBase(BiomeGenBaseHook.java:65)
    at net.minecraft.world.biome.BiomeGenBase.<init>(BiomeGenBase.java:170)
    at net.minecraft.world.biome.BiomeGenBase.<init>(BiomeGenBase.java:167)
    at net.minecraft.world.biome.BiomeGenOcean.<init>(BiomeGenOcean.java:13)
    at net.minecraft.world.biome.BiomeGenBase.<clinit>(BiomeGenBase.java:67)
    ... 36 more
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#2
На всякий случай скажу: удалить спавн мобов можно через EntityRegistry.removeSpawn(...).
Убери createMethod = true и должно заработать.
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#3
createMethod = true, работает же только в том случае, если нет метода с таким названием
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#4
и нет это не помогло, щас погляжу, про EntityRegistry, но все полезно будет знать как работать с конструкторами, так что вопрос по прежнему открыт
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#5
Я понял. У тебя какая-то фигня случилась с инициализацией класса.
1555170067952.png
Вот это вот поле не инициализировалось, из-за этого вылетел краш:
Java:
Caused by: java.lang.NullPointerException
    at net.minecraft.world.biome.BiomeGenBase.addDefaultFlowers(BiomeGenBase.java:642)
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#6
значит хук неправильно работает и ломает инициализацию класса, вопрос в том, как правильно сделать?
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#7
Хм, проверил у себя - тоже крашится.
Интересно... Можешь извратиться и инициализировать это поле прям в конструкторе.
@GloomyFolken
 

hohserg

Алмазная лига
Сообщения
3,455
Лучшие ответы
88
Симпатии
377
#8
нужно полностью его заменить
Плохая идея - в конструкторе есть еще много обязательных инструкций, вроде инициализация финальных полей, который тебе тоже нужно будет как-то воспроизвести(а это не получится, потому что поле финальное)
"зачем так делать" мне не интересны
Тыж пользуешься инструментом, значит, лучше учитывать его особенности

Пока смотрел код BiomeGenBase, Агравэйн уже ответил про неинициализированное поле)
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#9
финал - не проблема, at может убрать этот модификатор
 

hohserg

Алмазная лига
Сообщения
3,455
Лучшие ответы
88
Симпатии
377
#10
Верно, тогда так и сделай
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#11
не прокатило, flowers это переменна добавляемая форджем
попробовал через EntityRegistry.removeSpawn
и каждый раз ловлю краш, мжб через это нельзя удалять спавн вальных мобов?
Java:
[20:53:55] [Client thread/ERROR] [FML]: The following problems were captured during this phase
[20:53:55] [Client thread/ERROR] [FML]: Caught exception from zombieapocalypsemod
java.lang.NullPointerException
    at cpw.mods.fml.common.registry.EntityRegistry.removeSpawn(EntityRegistry.java:294) ~[forgeSrc-1.7.10-10.13.4.1614-1.7.10.jar:?]
    at ru.Pa4ok.mod.core.registers.EntityRegister.spawnRegister(EntityRegister.java:25) ~[bin/:?]
    at ru.Pa4ok.mod.core.CommonProxy.init(CommonProxy.java:40) ~[bin/:?]
    at ru.Pa4ok.mod.core.ClientProxy.init(ClientProxy.java:32) ~[bin/:?]
    at ru.Pa4ok.mod.ZombieApocalypseMod.init(ZombieApocalypseMod.java:32) ~[bin/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532) ~[forgeSrc-1.7.10-10.13.4.1614-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212) ~[forgeSrc-1.7.10-10.13.4.1614-1.7.10.jar:?]
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190) ~[forgeSrc-1.7.10-10.13.4.1614-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119) [LoadController.class:?]
    at cpw.mods.fml.common.Loader.initializeMods(Loader.java:737) [Loader.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:311) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:597) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:942) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#12
Можно, я зомбиков удалял. Ты наверное передаешь туда весь массив биомов из BiomeGenBase, но там же в нем есть и нуллы, вот тебе эксепшн и кидает.
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#13
там же массив, а не лист...
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#14
1555184383174.png
Ну, массив. Он не заполнен весь, а значит остальные элементы нулл. Тебе нужен массив без нуллов. Можешь получить его любым способом, самый простой - сделай лист, пробежись по массиву, проверь не нулл ли элемент, добавь в лист. Потом лист.toArray() и передай в removeSpawn.
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#15
да это то уже понятно, я в любом случае придумал как хук сделать, я вставил его в конец конструктора
Java:
@Hook(targetMethod = "<init>", injectOnExit = true)
    public static void BiomeGenBase(BiomeGenBase biomeGenBase, int p_i1971_1_, boolean register)
    {       
        biomeGenBase.spawnableCreatureList.clear();
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySheep.class, 5, 1, 4));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityPig.class, 4, 1, 3));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityChicken.class, 3, 1, 4));
        biomeGenBase.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityCow.class, 2, 1, 2));
        
        biomeGenBase.spawnableMonsterList.clear();
        
        biomeGenBase.spawnableWaterCreatureList.clear();
        biomeGenBase.spawnableWaterCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySquid.class, 5, 1, 3));
    }
 

Agravaine

Алмазная лига
Сообщения
4,253
Лучшие ответы
165
Симпатии
512
#16
Не нужно лепить хуки везде где только можно. Если есть возможность обойтись без хуков - сделай лучше без них.
 

Pa4ok

Каменная лига
Сообщения
52
Лучшие ответы
0
Симпатии
1
#17
как я уже писал выше - мод вакумный, разницы 0, хук намрямую делает, а тут через forge пройдет еще несколько этапов
 

Doc

Золотая лига
Сообщения
2,174
Лучшие ответы
114
Симпатии
261
#18
Делаешь мод в паблик - хуки удаляешь к ***м.
Делаешь мод на свой "мега" проект - добавляй ЕЩЕ БОЛЬШЕ ХУКОВ!
Спасибо за внимание.
~~~
а тут через forge пройдет еще несколько этапов
О да, целых несколько этапов! Это спасет жизни людей!
 

GloomyFolken

Каменная лига
Сообщения
748
Лучшие ответы
3
Симпатии
48
#19
В принципе все уже сказали и всё решили, но для пущей убедительности повторюсь. Заменять целиком конструкторы больших классов хуками это такая себе затея. Код инициализации полей на самом деле копируется в начало каждого конструктора, то есть заменяете целиком код конструктора - надо как-то самому делать и инициализацию полей. У ОПа хорошее решение в итоге (насколько хуки в принципе могут быть хорошим решением), влезть в конец конструктора и поверх инициализированного объекта накостылить то что тебе нужно намного лучше чем заменять весь конструктор.
 
Сверху