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

Версия Minecraft
1.7.10
235
3
21
добрый день
использую хук-либу от 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
 

tox1cozZ

aka Agravaine
8,454
598
2,890
Я понял. У тебя какая-то фигня случилась с инициализацией класса.
1555170067952.png
Вот это вот поле не инициализировалось, из-за этого вылетел краш:
Java:
Caused by: java.lang.NullPointerException
    at net.minecraft.world.biome.BiomeGenBase.addDefaultFlowers(BiomeGenBase.java:642)
 
7,099
324
1,509
нужно полностью его заменить
Плохая идея - в конструкторе есть еще много обязательных инструкций, вроде инициализация финальных полей, который тебе тоже нужно будет как-то воспроизвести(а это не получится, потому что поле финальное)
"зачем так делать" мне не интересны
Тыж пользуешься инструментом, значит, лучше учитывать его особенности

Пока смотрел код BiomeGenBase, Агравэйн уже ответил про неинициализированное поле)
 
235
3
21
не прокатило, 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/:?]
 

tox1cozZ

aka Agravaine
8,454
598
2,890
1555184383174.png
Ну, массив. Он не заполнен весь, а значит остальные элементы нулл. Тебе нужен массив без нуллов. Можешь получить его любым способом, самый простой - сделай лист, пробежись по массиву, проверь не нулл ли элемент, добавь в лист. Потом лист.toArray() и передай в removeSpawn.
 
235
3
21
да это то уже понятно, я в любом случае придумал как хук сделать, я вставил его в конец конструктора
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));
    }
 
3,005
192
592
Делаешь мод в паблик - хуки удаляешь к ***м.
Делаешь мод на свой "мега" проект - добавляй ЕЩЕ БОЛЬШЕ ХУКОВ!
Спасибо за внимание.
~~~
а тут через forge пройдет еще несколько этапов
О да, целых несколько этапов! Это спасет жизни людей!
 
808
3
124
В принципе все уже сказали и всё решили, но для пущей убедительности повторюсь. Заменять целиком конструкторы больших классов хуками это такая себе затея. Код инициализации полей на самом деле копируется в начало каждого конструктора, то есть заменяете целиком код конструктора - надо как-то самому делать и инициализацию полей. У ОПа хорошее решение в итоге (насколько хуки в принципе могут быть хорошим решением), влезть в конец конструктора и поверх инициализированного объекта накостылить то что тебе нужно намного лучше чем заменять весь конструктор.
 
Сверху