From 30bad1e26d311e5a9cc3b7e78700d457fe478921 Mon Sep 17 00:00:00 2001 From: LexManos Date: Tue, 28 Jul 2020 12:01:15 -0700 Subject: [PATCH] Properly shutdown FMLModContainer's event bus when an error in a lifecycle event is detected. --- .../net/minecraftforge/common/ForgeMod.java | 10 +--- .../fml/javafmlmod/FMLModContainer.java | 48 +++++++++++++++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index b3f1a4427..b2555c9d4 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -23,22 +23,16 @@ import net.minecraft.entity.ai.attributes.Attribute; import net.minecraft.entity.ai.attributes.RangedAttribute; import net.minecraft.util.SoundEvent; import net.minecraft.world.storage.IServerConfiguration; -import net.minecraft.world.storage.IWorldInfo; import net.minecraft.world.storage.SaveFormat; import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.*; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLModIdMappingEvent; -import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.loading.progress.StartupMessageManager; import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.server.command.ConfigCommand; -import net.minecraftforge.server.command.ForgeCommand; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; @@ -112,7 +106,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); modEventBus.addListener(this::preInit); modEventBus.addListener(this::gatherData); - modEventBus.register(this); + modEventBus.addGenericListener(IRecipeSerializer.class, this::registerRecipeSerialziers); ATTRIBUTES.register(modEventBus); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); MinecraftForge.EVENT_BUS.addGenericListener(SoundEvent.class, this::missingSoundMapping); @@ -125,7 +119,6 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook MinecraftForge.EVENT_BUS.addListener(VillagerTradingManager::loadTrades); MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER); - MinecraftForge.EVENT_BUS.register(this); } public void preInit(FMLCommonSetupEvent evt) @@ -215,7 +208,6 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook } } - @SubscribeEvent //ModBus, can't use addListener due to nested genetics. public void registerRecipeSerialziers(RegistryEvent.Register> event) { CraftingHelper.register(AndCondition.Serializer.INSTANCE); diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index 906f921b8..627196af7 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -30,13 +30,15 @@ import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModLoadingException; import net.minecraftforge.fml.ModLoadingStage; import net.minecraftforge.fml.event.lifecycle.IModBusEvent; -import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent; import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.language.ModFileScanData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; @@ -90,7 +92,7 @@ public class FMLModContainer extends ModContainer } - private Consumer dummy() { return (s) -> {}; } + private Consumer dummy() { return new ErroringConsumer<>(); } private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { @@ -118,6 +120,7 @@ public class FMLModContainer extends ModContainer private void afterEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { if (getCurrentState() == ModLoadingStage.ERROR) { LOGGER.error(LOADING,"An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId()); + this.eventBus.shutdown(); } } @@ -166,7 +169,46 @@ public class FMLModContainer extends ModContainer } @Override - protected void acceptEvent(final Event e) { + protected void acceptEvent(final Event e) + { this.eventBus.post(e); } + + private class ErroringConsumer implements Consumer + { + private List> children = new ArrayList<>(); + + @Override + public void accept(T t) + { + Throwable error = null; + for (Consumer child : children) + { + try + { + child.accept(t); + } + catch (Throwable e) + { + FMLModContainer.this.modLoadingStage = ModLoadingStage.ERROR; + error = e; + } + } + + if (error != null) + { + if (error instanceof RuntimeException) + throw (RuntimeException)error; + throw new RuntimeException(error); + } + } + + @Override + public ErroringConsumer andThen(Consumer after) + { + Objects.requireNonNull(after); + children.add(after); + return this; + } + } }