snowstep115 Posted August 25, 2019 Share Posted August 25, 2019 When I called ChannelBuilder.simpleChannel on FMLCommonSetupEvent, it caused below exception. [modloading-worker-2/ERROR] [ne.mi.fm.ja.FMLModContainer/]: Exception caught during firing event: 14 Index: 1 Listeners: 0: NORMAL 1: net.minecraftforge.eventbus.EventBus$$Lambda$2647/1527166994@1a39a848 java.lang.ArrayIndexOutOfBoundsException: 14 at net.minecraftforge.eventbus.ListenerList.register(ListenerList.java:125) at net.minecraftforge.eventbus.EventBus.addToListeners(EventBus.java:229) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:204) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:200) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:161) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:156) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:151) at net.minecraftforge.fml.network.NetworkInstance.addListener(NetworkInstance.java:63) at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:49) at net.minecraftforge.fml.network.NetworkRegistry$ChannelBuilder.simpleChannel(NetworkRegistry.java:409) What event should I depend to create a channel? Quote Link to comment Share on other sites More sharing options...
loordgek Posted August 25, 2019 Share Posted August 25, 2019 post code Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 25, 2019 Author Share Posted August 25, 2019 private void commonSetup(final FMLCommonSetupEvent event) { PacketHandler.init(); PacketHandler.registerMessages(); } and private static SimpleChannel HANDLER; public static void init() { HANDLER = NetworkRegistry.ChannelBuilder.named(NAME).clientAcceptedVersions(PROTOCOL_VERSION::equals) .serverAcceptedVersions(PROTOCOL_VERSION::equals).networkProtocolVersion(() -> PROTOCOL_VERSION) .simpleChannel(); } public static void registerMessages() { int index = 0; HANDLER.registerMessage(index++, ExampleMessage.class, ExampleMessage::encode, ExampleMessage::decode, ExampleMessage::handle); } Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 25, 2019 Author Share Posted August 25, 2019 [modloading-worker-2/ERROR] [ne.mi.fm.ja.FMLModContainer/]: Exception caught during firing event: 14 Index: 1 Listeners: 0: NORMAL 1: net.minecraftforge.eventbus.EventBus$$Lambda$2647/1527166994@1a39a848 java.lang.ArrayIndexOutOfBoundsException: 14 at net.minecraftforge.eventbus.ListenerList.register(ListenerList.java:125) at net.minecraftforge.eventbus.EventBus.addToListeners(EventBus.java:229) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:204) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:200) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:161) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:156) at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:151) at net.minecraftforge.fml.network.NetworkInstance.addListener(NetworkInstance.java:63) at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:49) at net.minecraftforge.fml.network.NetworkRegistry$ChannelBuilder.simpleChannel(NetworkRegistry.java:409) at com.snowstep115.ssench.network.PacketHandler.init(PacketHandler.java:24) at com.snowstep115.ssench.SSEnchMod.commonSetup(SSEnchMod.java:77) at net.minecraftforge.eventbus.EventBus.doCastFilter(EventBus.java:212) at net.minecraftforge.eventbus.EventBus.lambda$addListener$11(EventBus.java:204) at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258) at net.minecraftforge.fml.javafmlmod.FMLModContainer.fireEvent(FMLModContainer.java:106) at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65) at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65) at net.minecraftforge.fml.ModContainer.transitionState(ModContainer.java:112) at net.minecraftforge.fml.ModList.lambda$null$10(ModList.java:133) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290) at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 I made three mods which have same initialization code for simple channel, and they run simultaneously. I've just made them create a same temporary directory during ChannelBuilder.simpleChannel in order to avoid this problem. It seems to work well now. Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 Although I really want to have something like an inter-mod mutex, I used stupidly temporary directory instead. It works well if only my initialization codes run. public static void init() { File file = new File("config" + File.separator + "snowstep115"); while (file.exists() || !file.mkdir()) { try { Thread.sleep(10); } catch (InterruptedException exception) { } } try { HANDLER = NetworkRegistry.ChannelBuilder.named(NAME) .clientAcceptedVersions(PROTOCOL_VERSION::equals) .serverAcceptedVersions(PROTOCOL_VERSION::equals) .networkProtocolVersion(() -> PROTOCOL_VERSION) .simpleChannel(); } finally { file.delete(); } } Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 You know I'm afraid that ChannelBuilder.simpleChannel, or more deep method, is not threadsafe. Actually, the exception has never caused by this way. Yes, I know this is stupid. Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 Umm, here is main mod class. Quote @ObjectHolder(MODID + ":craftable") public static ContainerType<CraftableContainer> CRAFTABLE_CONTAINER_TYPE; @ObjectHolder(MODID + ":storage_m") public static ContainerType<StorageContainer> STORAGE_CONTAINER_TYPE_M; @ObjectHolder(MODID + ":storage_o") public static ContainerType<StorageContainer> STORAGE_CONTAINER_TYPE_O; public static SSEnchMod INSTANCE; private static void registerClientFactories() { ScreenManager.registerFactory(CRAFTABLE_CONTAINER_TYPE, GuiCraftableContainer::new); ScreenManager.registerFactory(STORAGE_CONTAINER_TYPE_M, GuiStorageContainer::new); ScreenManager.registerFactory(STORAGE_CONTAINER_TYPE_O, GuiStorageContainer::new); } private MinecraftServer server; public SSEnchMod() { INSTANCE = this; IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener(this::clientSetup); bus.addListener(this::commonSetup); MinecraftForge.EVENT_BUS.register(this); } private void clientSetup(final FMLClientSetupEvent event) { registerClientFactories(); } private void commonSetup(final FMLCommonSetupEvent event) { PacketHandler.init(); PacketHandler.registerMessages(); } @SubscribeEvent public void serverStarting(final FMLServerStartingEvent event) { this.server = event.getServer(); } And event handler class. Quote @EventBusSubscriber(bus = Bus.MOD, modid = SSEnchMod.MODID) public final class RegistryEventHandler { private static <T extends Container> ContainerType<T> build(IFactory<T> factory, String name) { ContainerType<T> type = new ContainerType<T>(factory); type.setRegistryName(SSEnchMod.MODID, name); return type; } @SubscribeEvent public static void registerContainerTypes(final Register<ContainerType<?>> event) { IForgeRegistry<ContainerType<?>> registry = event.getRegistry(); registry.register(build(CraftableContainer::create, "craftable")); registry.register(build(StorageContainer::createMainHand, "storage_m")); registry.register(build(StorageContainer::createOffHand, "storage_o")); } @SubscribeEvent public static void registerEnchantments(final Register<Enchantment> event) { IForgeRegistry<Enchantment> registry = event.getRegistry(); registry.register(Enchantments.CRAFTABLE); registry.register(Enchantments.STORAGE); registry.register(Enchantments.TELEPORT); } } Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 (edited) In order to separate simpleChannel call and others. Quote public static void init() { File file = new File("config" + File.separator + "snowstep115"); while (file.exists() || !file.mkdir()) try { Thread.sleep(10); } catch (InterruptedException exception) { } try { HANDLER = NetworkRegistry.ChannelBuilder.named(NAME).clientAcceptedVersions(PROTOCOL_VERSION::equals) .serverAcceptedVersions(PROTOCOL_VERSION::equals).networkProtocolVersion(() -> PROTOCOL_VERSION) .simpleChannel(); } finally { file.delete(); } } public static void registerMessages() { int index = 0; HANDLER.registerMessage(index++, CraftMatrixChangedMessage.class, CraftMatrixChangedMessage::encode, CraftMatrixChangedMessage::decode, CraftMatrixChangedMessage::handle); HANDLER.registerMessage(index++, InitializeStorageMessage.class, InitializeStorageMessage::encode, InitializeStorageMessage::decode, InitializeStorageMessage::handle); HANDLER.registerMessage(index++, SetCraftResultMessage.class, SetCraftResultMessage::encode, SetCraftResultMessage::decode, SetCraftResultMessage::handle); HANDLER.registerMessage(index++, TransferCraftResultMessage.class, TransferCraftResultMessage::encode, TransferCraftResultMessage::decode, TransferCraftResultMessage::handle); HANDLER.registerMessage(index++, TransferReplyMessage.class, TransferReplyMessage::encode, TransferReplyMessage::decode, TransferReplyMessage::handle); } Other two mods have same initialization codes, they also set up channels by FMLCommonSetupEvent. I want to make other two mods stop setting up their channels during the one mod is setting up the channel. Edited August 28, 2019 by snowstep115 Quote Link to comment Share on other sites More sharing options...
loordgek Posted August 28, 2019 Share Posted August 28, 2019 (edited) 13 minutes ago, snowstep115 said: File file = new File("config" + File.separator + "snowstep115"); while (file.exists() || !file.mkdir()) try { Thread.sleep(10); } catch (InterruptedException exception) { } try { } finally { file.delete(); } what is this doing ????? i can read i promise ? do it like so https://github.com/cpw/inventorysorter/blob/master/src/main/java/cpw/mods/inventorysorter/Network.java#L68-L80 Edited August 28, 2019 by loordgek Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 2 minutes ago, loordgek said: what is this doing ????? Just not to call simpleChannel simultaneously. Quote Link to comment Share on other sites More sharing options...
loordgek Posted August 28, 2019 Share Posted August 28, 2019 a i see. you should never do that 1 simpleChannel for each mod do it like so https://github.com/cpw/inventorysorter/blob/master/src/main/java/cpw/mods/inventorysorter/Network.java#L68-L80 Quote Link to comment Share on other sites More sharing options...
snowstep115 Posted August 28, 2019 Author Share Posted August 28, 2019 3 minutes ago, loordgek said: a i see. you should never do that 1 simpleChannel for each mod do it like so https://github.com/cpw/inventorysorter/blob/master/src/main/java/cpw/mods/inventorysorter/Network.java#L68-L80 Thank you. I understand that code. I should not use SimpleChannel.registerMessage. Quote Link to comment Share on other sites More sharing options...
loordgek Posted August 28, 2019 Share Posted August 28, 2019 yes Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.