Mods can now declare a range of minecraft versions they will run against
This commit is contained in:
parent
7cd5ae04f7
commit
9a8a38d345
12 changed files with 151 additions and 4 deletions
|
@ -54,6 +54,7 @@ import cpw.mods.fml.common.ModContainer;
|
||||||
import cpw.mods.fml.common.ModMetadata;
|
import cpw.mods.fml.common.ModMetadata;
|
||||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||||
import cpw.mods.fml.common.Side;
|
import cpw.mods.fml.common.Side;
|
||||||
|
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||||
|
@ -104,6 +105,8 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
|
|
||||||
private boolean loading;
|
private boolean loading;
|
||||||
|
|
||||||
|
private WrongMinecraftVersionException wrongMC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to start the whole game off from
|
* Called to start the whole game off from
|
||||||
* {@link MinecraftServer#startServer}
|
* {@link MinecraftServer#startServer}
|
||||||
|
@ -142,6 +145,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
Loader.instance().loadMods();
|
Loader.instance().loadMods();
|
||||||
}
|
}
|
||||||
|
catch (WrongMinecraftVersionException wrong)
|
||||||
|
{
|
||||||
|
wrongMC = wrong;
|
||||||
|
}
|
||||||
catch (MissingModsException missing)
|
catch (MissingModsException missing)
|
||||||
{
|
{
|
||||||
modsMissing = missing;
|
modsMissing = missing;
|
||||||
|
@ -167,7 +174,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void finishMinecraftLoading()
|
public void finishMinecraftLoading()
|
||||||
{
|
{
|
||||||
if (modsMissing != null)
|
if (modsMissing != null || wrongMC != null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +196,11 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
|
|
||||||
public void onInitializationComplete()
|
public void onInitializationComplete()
|
||||||
{
|
{
|
||||||
if (modsMissing != null)
|
if (wrongMC != null)
|
||||||
|
{
|
||||||
|
client.func_71373_a(new GuiWrongMinecraft(wrongMC));
|
||||||
|
}
|
||||||
|
else if (modsMissing != null)
|
||||||
{
|
{
|
||||||
client.func_71373_a(new GuiModsMissing(modsMissing));
|
client.func_71373_a(new GuiModsMissing(modsMissing));
|
||||||
}
|
}
|
||||||
|
|
35
fml/client/cpw/mods/fml/client/GuiWrongMinecraft.java
Normal file
35
fml/client/cpw/mods/fml/client/GuiWrongMinecraft.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.Loader;
|
||||||
|
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||||
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
|
import net.minecraft.src.GuiErrorScreen;
|
||||||
|
import net.minecraft.src.GuiScreen;
|
||||||
|
|
||||||
|
public class GuiWrongMinecraft extends GuiErrorScreen
|
||||||
|
{
|
||||||
|
private WrongMinecraftVersionException wrongMC;
|
||||||
|
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
|
||||||
|
{
|
||||||
|
this.wrongMC = wrongMC;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void func_73866_w_()
|
||||||
|
{
|
||||||
|
super.func_73866_w_();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||||
|
{
|
||||||
|
this.func_73873_v_();
|
||||||
|
int offset = 75;
|
||||||
|
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||||
|
offset+=10;
|
||||||
|
this.func_73732_a(this.field_73886_k, String.format("The mod listed below does not want to run in Minecraft version %s", Loader.instance().getMinecraftModContainer().getVersion()), this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||||
|
offset+=5;
|
||||||
|
offset+=10;
|
||||||
|
this.func_73732_a(this.field_73886_k, String.format("%s (%s) wants Minecraft %s", wrongMC.mod.getName(), wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||||
|
offset+=20;
|
||||||
|
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
public class DummyModContainer implements ModContainer
|
public class DummyModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
|
@ -132,4 +133,9 @@ public class DummyModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
return md.version;
|
return md.version;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public VersionRange acceptableMinecraftVersionRange()
|
||||||
|
{
|
||||||
|
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ import cpw.mods.fml.common.event.FMLStateEvent;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionParser;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
public class FMLModContainer implements ModContainer
|
public class FMLModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
|
@ -84,6 +86,7 @@ public class FMLModContainer implements ModContainer
|
||||||
.build();
|
.build();
|
||||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||||
private String annotationDependencies;
|
private String annotationDependencies;
|
||||||
|
private VersionRange minecraftAccepted;
|
||||||
|
|
||||||
|
|
||||||
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
||||||
|
@ -175,6 +178,16 @@ public class FMLModContainer implements ModContainer
|
||||||
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
|
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
|
||||||
modMetadata.version = internalVersion = "1.0";
|
modMetadata.version = internalVersion = "1.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String mcVersionString = (String) descriptor.get("acceptedMinecraftVersions");
|
||||||
|
if (!Strings.isNullOrEmpty(mcVersionString))
|
||||||
|
{
|
||||||
|
minecraftAccepted = VersionParser.parseRange(mcVersionString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minecraftAccepted = Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Properties searchForVersionProperties()
|
public Properties searchForVersionProperties()
|
||||||
|
@ -457,4 +470,10 @@ public class FMLModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
return modMetadata.version;
|
return modMetadata.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionRange acceptableMinecraftVersionRange()
|
||||||
|
{
|
||||||
|
return minecraftAccepted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Set;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
public class InjectedModContainer implements ModContainer
|
public class InjectedModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
|
@ -110,4 +111,10 @@ public class InjectedModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
return wrappedContainer.getDisplayVersion();
|
return wrappedContainer.getDisplayVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionRange acceptableMinecraftVersionRange()
|
||||||
|
{
|
||||||
|
return wrappedContainer.acceptableMinecraftVersionRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,7 @@ public class Loader
|
||||||
private Exception capturedError;
|
private Exception capturedError;
|
||||||
private File canonicalModsDir;
|
private File canonicalModsDir;
|
||||||
private LoadController modController;
|
private LoadController modController;
|
||||||
|
private MinecraftDummyContainer minecraft;
|
||||||
|
|
||||||
private static File minecraftDir;
|
private static File minecraftDir;
|
||||||
private static List<String> injectedContainers;
|
private static List<String> injectedContainers;
|
||||||
|
@ -167,6 +168,8 @@ public class Loader
|
||||||
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
|
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
|
||||||
throw new LoaderException();
|
throw new LoaderException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minecraft = new MinecraftDummyContainer(actualMCVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,6 +190,11 @@ public class Loader
|
||||||
|
|
||||||
for (ModContainer mod : getActiveModList())
|
for (ModContainer mod : getActiveModList())
|
||||||
{
|
{
|
||||||
|
if (!mod.acceptableMinecraftVersionRange().containsVersion(minecraft.getProcessedVersion()))
|
||||||
|
{
|
||||||
|
FMLLog.severe("The mod %s does not wish to run in Minecraft version %s. You will have to remove it to play.", mod.getModId(), getMCVersionString());
|
||||||
|
throw new WrongMinecraftVersionException(mod);
|
||||||
|
}
|
||||||
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new Function<ArtifactVersion, String>()
|
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new Function<ArtifactVersion, String>()
|
||||||
{
|
{
|
||||||
public String apply(ArtifactVersion v)
|
public String apply(ArtifactVersion v)
|
||||||
|
@ -194,8 +202,8 @@ public class Loader
|
||||||
return v.getLabel();
|
return v.getLabel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
|
|
||||||
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
|
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
|
||||||
|
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
|
||||||
if (!missingMods.isEmpty())
|
if (!missingMods.isEmpty())
|
||||||
{
|
{
|
||||||
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
|
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
|
||||||
|
@ -707,4 +715,9 @@ public class Loader
|
||||||
{
|
{
|
||||||
return modController.isInState(state);
|
return modController.isInState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MinecraftDummyContainer getMinecraftModContainer()
|
||||||
|
{
|
||||||
|
return minecraft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
26
fml/common/cpw/mods/fml/common/MinecraftDummyContainer.java
Normal file
26
fml/common/cpw/mods/fml/common/MinecraftDummyContainer.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionParser;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
|
public class MinecraftDummyContainer extends DummyModContainer
|
||||||
|
{
|
||||||
|
|
||||||
|
private VersionRange staticRange;
|
||||||
|
public MinecraftDummyContainer(String actualMCVersion)
|
||||||
|
{
|
||||||
|
super(new ModMetadata());
|
||||||
|
getMetadata().modId = "Minecraft";
|
||||||
|
getMetadata().name = "Minecraft";
|
||||||
|
getMetadata().version = actualMCVersion;
|
||||||
|
staticRange = VersionParser.parseRange("["+actualMCVersion+"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public VersionRange getStaticVersionRange()
|
||||||
|
{
|
||||||
|
return staticRange;
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,13 @@ public @interface Mod
|
||||||
*/
|
*/
|
||||||
boolean useMetadata() default false;
|
boolean useMetadata() 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.
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
String acceptedMinecraftVersions() default "";
|
||||||
/**
|
/**
|
||||||
* Mark the designated method as being called at the "pre-initialization" phase
|
* Mark the designated method as being called at the "pre-initialization" phase
|
||||||
* @author cpw
|
* @author cpw
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Set;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The container that wraps around mods in the system.
|
* The container that wraps around mods in the system.
|
||||||
|
@ -126,4 +127,6 @@ public interface ModContainer
|
||||||
boolean isNetworkMod();
|
boolean isNetworkMod();
|
||||||
|
|
||||||
String getDisplayVersion();
|
String getDisplayVersion();
|
||||||
|
|
||||||
|
VersionRange acceptableMinecraftVersionRange();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
public class WrongMinecraftVersionException extends RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
public ModContainer mod;
|
||||||
|
|
||||||
|
public WrongMinecraftVersionException(ModContainer mod)
|
||||||
|
{
|
||||||
|
this.mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -65,6 +65,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
import cpw.mods.fml.common.registry.TickRegistry;
|
import cpw.mods.fml.common.registry.TickRegistry;
|
||||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||||
|
import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
|
|
||||||
public class ModLoaderModContainer implements ModContainer
|
public class ModLoaderModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
|
@ -609,4 +610,10 @@ public class ModLoaderModContainer implements ModContainer
|
||||||
{
|
{
|
||||||
serverCommands .add(command);
|
serverCommands .add(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionRange acceptableMinecraftVersionRange()
|
||||||
|
{
|
||||||
|
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import cpw.mods.fml.common.network.NetworkMod.SidedPacketHandler;
|
||||||
import cpw.mods.fml.common.network.Player;
|
import cpw.mods.fml.common.network.Player;
|
||||||
import cpw.mods.fml.common.ModMetadata;
|
import cpw.mods.fml.common.ModMetadata;
|
||||||
|
|
||||||
@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="after:FML@(3.0.184.0,3.0.184.1]", useMetadata=true)
|
@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="after:FML@[3.1.29,)", useMetadata=true,acceptedMinecraftVersions="[1.4,),[12w27a,)")
|
||||||
@NetworkMod(channels={"MockMod"},clientSideRequired=true,packetHandler=MockMod.PacketHandler.class,clientPacketHandlerSpec=
|
@NetworkMod(channels={"MockMod"},clientSideRequired=true,packetHandler=MockMod.PacketHandler.class,clientPacketHandlerSpec=
|
||||||
@SidedPacketHandler(packetHandler=TestClass.class,channels={"Fish"}),tinyPacketHandler=MockMod.PacketHandler.class)
|
@SidedPacketHandler(packetHandler=TestClass.class,channels={"Fish"}),tinyPacketHandler=MockMod.PacketHandler.class)
|
||||||
public class MockMod
|
public class MockMod
|
||||||
|
|
Loading…
Reference in a new issue