From 29986615febe79843eb16b879f33282ee3225838 Mon Sep 17 00:00:00 2001 From: Paint_Ninja Date: Thu, 12 Sep 2024 14:06:42 +0100 Subject: [PATCH] Optionally supply FMLJavaModLoadingContext as a param to mod constructors (backport of #10074 to 1.20.1) (#10100) Co-authored-by: RealMangoRage --- .../minecraftforge/fml/ModLoadingContext.java | 41 ++++++++++++------ .../javafmlmod/FMLJavaModLoadingContext.java | 9 +++- .../fml/javafmlmod/FMLModContainer.java | 13 ++++-- .../com/example/examplemod/ExampleMod.java | 7 ++-- .../net/minecraftforge/common/ForgeMod.java | 12 +++--- .../minecraftforge/common/MinecraftForge.java | 42 ++----------------- 6 files changed, 59 insertions(+), 65 deletions(-) diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java index bfe5e4d248..e50f30e76d 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java @@ -8,9 +8,7 @@ package net.minecraftforge.fml; import com.mojang.logging.LogUtils; import net.minecraftforge.fml.config.IConfigSpec; import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.loading.FMLLoader; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.function.BiPredicate; import java.util.function.Supplier; @@ -19,28 +17,45 @@ public class ModLoadingContext { private static final Logger LOGGER = LogUtils.getLogger(); private static final ThreadLocal context = ThreadLocal.withInitial(ModLoadingContext::new); + private ModContainer activeContainer; private Object languageExtension; private ModLoadingStage stage; + /** + * @deprecated Use the context provided by your language loader in your mod's constructor. + */ + @Deprecated(forRemoval = true, since = "1.21.1") public static ModLoadingContext get() { return context.get(); } - private ModContainer activeContainer; - + /** + * @deprecated Going to be moved to ForgeHooks for internal use. + */ + @Deprecated(forRemoval = true, since = "1.21.1") public void setActiveContainer(final ModContainer container) { this.activeContainer = container; this.languageExtension = container == null ? null : container.contextExtension.get(); } + /** + * Going to be moved to ForgeHooks for internal use. + * @deprecated Override/Use {@link ModLoadingContext#getContainer()} + */ + @Deprecated(forRemoval = true, since = "1.21.1") public ModContainer getActiveContainer() { return activeContainer == null ? ModList.get().getModContainerById("minecraft").orElseThrow(()->new RuntimeException("Where is minecraft???!")) : activeContainer; } + @Deprecated(forRemoval = true, since = "1.21.1") public String getActiveNamespace() { return activeContainer == null ? "minecraft" : activeContainer.getNamespace(); } + public ModContainer getContainer() { + return getActiveContainer(); + } + /** * Register an {@link IExtensionPoint} with the mod container. * @param point The extension point to register @@ -48,7 +63,7 @@ public class ModLoadingContext * @param The type signature of the extension operator */ public > void registerExtensionPoint(Class> point, Supplier extension) { - getActiveContainer().registerExtensionPoint(point, extension); + getContainer().registerExtensionPoint(point, extension); } /** @@ -57,7 +72,7 @@ public class ModLoadingContext * @param displayTest The {@link IExtensionPoint.DisplayTest} to register */ public void registerDisplayTest(IExtensionPoint.DisplayTest displayTest) { - getActiveContainer().registerDisplayTest(() -> displayTest); + getContainer().registerDisplayTest(() -> displayTest); } /** @@ -66,7 +81,7 @@ public class ModLoadingContext * @param displayTest The {@link Supplier} to register */ public void registerDisplayTest(Supplier displayTest) { - getActiveContainer().registerDisplayTest(displayTest); + getContainer().registerDisplayTest(displayTest); } /** @@ -76,7 +91,7 @@ public class ModLoadingContext * @see IExtensionPoint.DisplayTest#DisplayTest(String, BiPredicate) */ public void registerDisplayTest(String version, BiPredicate remoteVersionTest) { - getActiveContainer().registerDisplayTest(new IExtensionPoint.DisplayTest(version, remoteVersionTest)); + getContainer().registerDisplayTest(new IExtensionPoint.DisplayTest(version, remoteVersionTest)); } /** @@ -86,29 +101,29 @@ public class ModLoadingContext * @see IExtensionPoint.DisplayTest#DisplayTest(Supplier, BiPredicate) */ public void registerDisplayTest(Supplier suppliedVersion, BiPredicate remoteVersionTest) { - getActiveContainer().registerDisplayTest(new IExtensionPoint.DisplayTest(suppliedVersion, remoteVersionTest)); + getContainer().registerDisplayTest(new IExtensionPoint.DisplayTest(suppliedVersion, remoteVersionTest)); } public void registerConfig(ModConfig.Type type, IConfigSpec spec) { if (spec.isEmpty()) { // This handles the case where a mod tries to register a config, without any options configured inside it. - LOGGER.debug("Attempted to register an empty config for type {} on mod {}", type, getActiveContainer().getModId()); + LOGGER.debug("Attempted to register an empty config for type {} on mod {}", type, getContainer().getModId()); return; } - getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer())); + getContainer().addConfig(new ModConfig(type, spec, getContainer())); } public void registerConfig(ModConfig.Type type, IConfigSpec spec, String fileName) { if (spec.isEmpty()) { // This handles the case where a mod tries to register a config, without any options configured inside it. - LOGGER.debug("Attempted to register an empty config for type {} on mod {} using file name {}", type, getActiveContainer().getModId(), fileName); + LOGGER.debug("Attempted to register an empty config for type {} on mod {} using file name {}", type, getContainer().getModId(), fileName); return; } - getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer(), fileName)); + getContainer().addConfig(new ModConfig(type, spec, getContainer(), fileName)); } diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLoadingContext.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLoadingContext.java index a0ab85442f..7ffb7e17e0 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLoadingContext.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLoadingContext.java @@ -8,7 +8,7 @@ package net.minecraftforge.fml.javafmlmod; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.ModLoadingContext; -public class FMLJavaModLoadingContext +public class FMLJavaModLoadingContext extends ModLoadingContext { private final FMLModContainer container; @@ -24,11 +24,18 @@ public class FMLJavaModLoadingContext return container.getEventBus(); } + @Override + public FMLModContainer getContainer() { + return container; + } /** * Helper to get the right instance from the {@link ModLoadingContext} correctly. * @return The FMLJavaMod language specific extension from the ModLoadingContext + * + * @deprecated use {@link FMLJavaModLoadingContext} in your mod constructor */ + @Deprecated(forRemoval = true, since = "1.21.1") public static FMLJavaModLoadingContext get() { return ModLoadingContext.get().extension(); } diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index e0186a00bc..d34372e188 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; +import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Objects; import java.util.Optional; @@ -33,6 +34,7 @@ public class FMLModContainer extends ModContainer private final IEventBus eventBus; private Object modInstance; private final Class modClass; + private final FMLJavaModLoadingContext context = new FMLJavaModLoadingContext(this); public FMLModContainer(IModInfo info, String className, ModFileScanData modFileScanResults, ModuleLayer gameLayer) { @@ -42,8 +44,7 @@ public class FMLModContainer extends ModContainer activityMap.put(ModLoadingStage.CONSTRUCT, this::constructMod); this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); this.configHandler = Optional.of(ce->this.eventBus.post(ce.self())); - final FMLJavaModLoadingContext contextExtension = new FMLJavaModLoadingContext(this); - this.contextExtension = () -> contextExtension; + this.contextExtension = () -> context; try { var layer = gameLayer.findModule(info.getOwningFile().moduleName()).orElseThrow(); @@ -67,7 +68,13 @@ public class FMLModContainer extends ModContainer try { LOGGER.trace(LOADING, "Loading mod instance {} of type {}", getModId(), modClass.getName()); - this.modInstance = modClass.getDeclaredConstructor().newInstance(); + Constructor constructor; + try { + constructor = modClass.getDeclaredConstructor(context.getClass()); + } catch (NoSuchMethodException | SecurityException exception) { + constructor = modClass.getDeclaredConstructor(); + } + this.modInstance = constructor.getParameterCount() == 0 ? constructor.newInstance() : constructor.newInstance(context); LOGGER.trace(LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.getName()); } catch (Throwable e) diff --git a/mdk/src/main/java/com/example/examplemod/ExampleMod.java b/mdk/src/main/java/com/example/examplemod/ExampleMod.java index 990fd6357b..987544c137 100644 --- a/mdk/src/main/java/com/example/examplemod/ExampleMod.java +++ b/mdk/src/main/java/com/example/examplemod/ExampleMod.java @@ -18,7 +18,6 @@ import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -61,9 +60,9 @@ public class ExampleMod output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event }).build()); - public ExampleMod() + public ExampleMod(FMLJavaModLoadingContext context) { - IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + IEventBus modEventBus = context.getModEventBus(); // Register the commonSetup method for modloading modEventBus.addListener(this::commonSetup); @@ -82,7 +81,7 @@ public class ExampleMod modEventBus.addListener(this::addCreative); // Register our mod's ForgeConfigSpec so that Forge can create and load the config file for us - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.SPEC); + context.registerConfig(ModConfig.Type.COMMON, Config.SPEC); } private void commonSetup(final FMLCommonSetupEvent event) diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index a0ce44dcfc..53873dede6 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -414,7 +414,7 @@ public class ForgeMod enableMilkFluid = true; } - public ForgeMod() + public ForgeMod(FMLJavaModLoadingContext context) { LOGGER.info(FORGEMOD,"Forge mod loading, version {}, for MC {} with MCP {}", ForgeVersion.getVersion(), MCPVersion.getMCVersion(), MCPVersion.getMCPVersion()); ForgeSnapshotsMod.logStartupWarning(); @@ -430,7 +430,7 @@ public class ForgeMod CrashReportCallables.registerCrashCallable("FML", ForgeVersion::getSpec); CrashReportCallables.registerCrashCallable("Forge", ()->ForgeVersion.getGroup()+":"+ForgeVersion.getVersion()); - final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + final IEventBus modEventBus = context.getModEventBus(); // Forge-provided datapack registries modEventBus.addListener((DataPackRegistryEvent.NewRegistry event) -> { event.dataPackRegistry(ForgeRegistries.Keys.BIOME_MODIFIERS, BiomeModifier.DIRECT_CODEC); @@ -452,13 +452,13 @@ public class ForgeMod VANILLA_FLUID_TYPES.register(modEventBus); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); MinecraftForge.EVENT_BUS.addListener(this::missingSoundMapping); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec); - ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ForgeConfig.serverSpec); - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ForgeConfig.commonSpec); + context.registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec); + context.registerConfig(ModConfig.Type.SERVER, ForgeConfig.serverSpec); + context.registerConfig(ModConfig.Type.COMMON, ForgeConfig.commonSpec); modEventBus.register(ForgeConfig.class); ForgeDeferredRegistriesSetup.setup(modEventBus); // Forge does not display problems when the remote is not matching. - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, ()->new IExtensionPoint.DisplayTest(()->"ANY", (remote, isServer)-> true)); + context.registerDisplayTest(IExtensionPoint.DisplayTest.IGNORE_ALL_VERSION); StartupMessageManager.addModMessage("Forge version "+ForgeVersion.getVersion()); MinecraftForge.EVENT_BUS.addListener(VillagerTradingManager::loadTrades); diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/src/main/java/net/minecraftforge/common/MinecraftForge.java index 9fa578d3eb..bdc62d510a 100644 --- a/src/main/java/net/minecraftforge/common/MinecraftForge.java +++ b/src/main/java/net/minecraftforge/common/MinecraftForge.java @@ -27,12 +27,10 @@ import java.util.function.Function; public class MinecraftForge { /** - * The core Forge EventBusses, all events for Forge will be fired on these, - * you should use this to register all your listeners. - * This replaces every register*Handler() function in the old version of Forge. - * TERRAIN_GEN_BUS for terrain gen events - * ORE_GEN_BUS for ore gen events - * EVENT_BUS for everything else + * The EventBus for all the Forge Events. + * + * Events marked with {@link net.minecraftforge.fml.event.IModBusEvent} + * belong on the ModBus and not this bus */ public static final IEventBus EVENT_BUS = BusBuilder.builder().startShutdown().useModLauncher().build(); @@ -82,36 +80,4 @@ public class MinecraftForge () -> new ConfigScreenHandler.ConfigScreenFactory(screenFunction) ); } - -/* - public static void preloadCrashClasses(ASMDataTable table, String modID, Set classes) - { - //Find all ICrashReportDetail's handlers and preload them. - List all = Lists.newArrayList(); - for (ASMData asm : table.getAll(ICrashReportDetail.class.getName().replace('.', '/'))) - all.add(asm.getClassName()); - for (ASMData asm : table.getAll(ICrashCallable.class.getName().replace('.', '/'))) - all.add(asm.getClassName()); - - all.retainAll(classes); - - if (all.size() == 0) - return; - - ForgeMod.log.debug("Preloading CrashReport Classes"); - Collections.sort(all); //Sort it because I like pretty output ;) - for (String name : all) - { - ForgeMod.log.debug("\t{}", name); - try - { - Class.forName(name.replace('/', '.'), false, MinecraftForge.class.getClassLoader()); - } - catch (Exception e) - { - LOGGER.error("Could not find class for name '{}'.", name, e); - } - } - } -*/ }