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.
This commit is contained in:
Lex Manos 2015-02-21 18:33:30 -08:00
parent 0281b74c7c
commit 7269d22449
6 changed files with 64 additions and 4 deletions

View File

@ -200,4 +200,10 @@ public class DummyModContainer implements ModContainer
{
return ImmutableList.of();
}
@Override
public boolean shouldLoadInEnvironment()
{
return true;
}
}

View File

@ -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;
}
}

View File

@ -201,4 +201,10 @@ public class InjectedModContainer implements ModContainer
{
return wrappedContainer.getOwnedPackages();
}
@Override
public boolean shouldLoadInEnvironment()
{
return true;
}
}

View File

@ -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
*/

View File

@ -147,4 +147,6 @@ public interface ModContainer
String getGuiClassName();
List<String> getOwnedPackages();
boolean shouldLoadInEnvironment();
}

View File

@ -32,7 +32,7 @@ public class ModContainerFactory
public static Map<Type, Constructor<? extends ModContainer>> 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<? extends ModContainer> 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;