From 7269d2244914700dd5a7970a728bd043132f8746 Mon Sep 17 00:00:00 2001 From: Lex Manos Date: Sat, 21 Feb 2015 18:33:30 -0800 Subject: [PATCH] New @Mod properties to define which environment to load the mod on. clientSideOnly will only be loaded in the Client environment. serverSideOnly will only be loaded in the Dedicated server environment. Combine with acceptedMinecraftVersions to prevent users from loading the mod in the incorrect environment. --- .../fml/common/DummyModContainer.java | 6 +++++ .../fml/common/FMLModContainer.java | 27 +++++++++++++++++++ .../fml/common/InjectedModContainer.java | 6 +++++ .../net/minecraftforge/fml/common/Mod.java | 15 ++++++++++- .../fml/common/ModContainer.java | 2 ++ .../fml/common/ModContainerFactory.java | 12 ++++++--- 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/fml/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java b/fml/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java index d2c567ff0..88b171c36 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java @@ -200,4 +200,10 @@ public class DummyModContainer implements ModContainer { return ImmutableList.of(); } + + @Override + public boolean shouldLoadInEnvironment() + { + return true; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java index e4e6ae441..1b6bb1914 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java @@ -39,6 +39,7 @@ import net.minecraftforge.fml.common.versioning.ArtifactVersion; import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; import net.minecraftforge.fml.common.versioning.VersionParser; import net.minecraftforge.fml.common.versioning.VersionRange; +import net.minecraftforge.fml.relauncher.Side; import org.apache.logging.log4j.Level; @@ -611,4 +612,30 @@ public class FMLModContainer implements ModContainer { return candidate.getContainedPackages(); } + + @Override + public boolean shouldLoadInEnvironment() + { + boolean clientSideOnly = (Boolean)this.descriptor.get("clientSideOnly"); + boolean serverSideOnly = (Boolean)this.descriptor.get("serverSideOnly"); + + if (clientSideOnly && serverSideOnly) + throw new RuntimeException("Mod annotation claims to be both client and server side only!"); + + Side side = FMLCommonHandler.instance().getSide(); + + if (clientSideOnly && side != Side.CLIENT) + { + FMLLog.info("Disabling mod %d it is client side only.", getModId()); + return false; + } + + if (serverSideOnly && side != Side.SERVER) + { + FMLLog.info("Disabling mod %d it is server side only.", getModId()); + return false; + } + + return true; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java b/fml/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java index f5e6e8d56..af91db153 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java @@ -201,4 +201,10 @@ public class InjectedModContainer implements ModContainer { return wrappedContainer.getOwnedPackages(); } + + @Override + public boolean shouldLoadInEnvironment() + { + return true; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/Mod.java b/fml/src/main/java/net/minecraftforge/fml/common/Mod.java index de2925556..ac51b406a 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/Mod.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/Mod.java @@ -89,9 +89,22 @@ public @interface Mod */ boolean useMetadata() default false; + /** + * If true, this mod will not be loaded on the Dedicated Server environment. + * Will crash if both serverSideOnly and clientSideOnly are set to true. + */ + boolean clientSideOnly() default false; + + /** + * If true, this mod will not be loaded on the Client environment. + * Will crash if both serverSideOnly and clientSideOnly are set to true. + */ + boolean serverSideOnly() default false; + /** * The acceptable range of minecraft versions that this mod will load and run in - * The default ("empty string") indicates that only the current minecraft version is acceptable. + * The default ("empty string") indicates that the currently RUNNING minecraft version is acceptable. + * This means ANY version that the end user adds the mod to. Modders PLEASS set this. * FML will refuse to run with an error if the minecraft version is not in this range across all mods. * @return A version range as specified by the maven version range specification or the empty string */ diff --git a/fml/src/main/java/net/minecraftforge/fml/common/ModContainer.java b/fml/src/main/java/net/minecraftforge/fml/common/ModContainer.java index 984b89993..dde8ddef5 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/ModContainer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/ModContainer.java @@ -147,4 +147,6 @@ public interface ModContainer String getGuiClassName(); List getOwnedPackages(); + + boolean shouldLoadInEnvironment(); } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java b/fml/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java index db2cd064e..6b1a1240a 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java @@ -32,7 +32,7 @@ public class ModContainerFactory public static Map> modTypes = Maps.newHashMap(); private static Pattern modClass = Pattern.compile(".*(\\.|)(mod\\_[^\\s$]+)$"); private static ModContainerFactory INSTANCE = new ModContainerFactory(); - + private ModContainerFactory() { // We always know about Mod type registerContainerType(Type.getType(Mod.class), FMLModContainer.class); @@ -40,7 +40,7 @@ public class ModContainerFactory public static ModContainerFactory instance() { return INSTANCE; } - + public void registerContainerType(Type type, Class container) { try { @@ -76,7 +76,13 @@ public class ModContainerFactory { FMLLog.fine("Identified a mod of type %s (%s) - loading", ann.getASMType(), className); try { - return modTypes.get(ann.getASMType()).newInstance(className, container, ann.getValues()); + ModContainer ret = modTypes.get(ann.getASMType()).newInstance(className, container, ann.getValues()); + if (!ret.shouldLoadInEnvironment()) + { + FMLLog.fine("Skipping mod %s, container opted to not load.", className); + return null; + } + return ret; } catch (Exception e) { FMLLog.log(Level.ERROR, e, "Unable to construct %s container", ann.getASMType().getClassName()); return null;