Fix up versioned dependencies so they work a lot better, also add in a missing mods screen
This commit is contained in:
parent
e6dce6cdbc
commit
4b6b090712
13 changed files with 148 additions and 24 deletions
|
@ -46,6 +46,7 @@ import cpw.mods.fml.common.IFMLSidedHandler;
|
|||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
|
@ -102,6 +103,8 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
|
||||
private boolean serverIsRunning;
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
public void beginMinecraftLoading(Minecraft minecraft)
|
||||
{
|
||||
if (minecraft.func_71355_q())
|
||||
|
@ -133,6 +136,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
{
|
||||
Loader.instance().loadMods();
|
||||
}
|
||||
catch (MissingModsException missing)
|
||||
{
|
||||
modsMissing = missing;
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
|
||||
|
@ -154,6 +161,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
@SuppressWarnings("deprecation")
|
||||
public void finishMinecraftLoading()
|
||||
{
|
||||
if (modsMissing != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Loader.instance().initializeMods();
|
||||
|
@ -169,9 +180,16 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
KeyBindingRegistry.instance().uploadKeyBindingsToGame(client.field_71474_y);
|
||||
}
|
||||
|
||||
public void reloadTextureFX()
|
||||
public void onInitializationComplete()
|
||||
{
|
||||
TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
|
||||
if (modsMissing != null)
|
||||
{
|
||||
client.func_71373_a(new ModsMissingGuiScreen(modsMissing));
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the server instance
|
||||
|
|
34
fml/client/cpw/mods/fml/client/ModsMissingGuiScreen.java
Normal file
34
fml/client/cpw/mods/fml/client/ModsMissingGuiScreen.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package cpw.mods.fml.client;
|
||||
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
public class ModsMissingGuiScreen extends GuiErrorScreen
|
||||
{
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
public ModsMissingGuiScreen(MissingModsException modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = 85 - modsMissing.missingMods.size() * 10;
|
||||
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, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=5;
|
||||
for (ArtifactVersion v : modsMissing.missingMods)
|
||||
{
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getVersionString()), 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);
|
||||
}
|
||||
}
|
|
@ -3,14 +3,17 @@ package cpw.mods.fml.common;
|
|||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
|
||||
public class DummyModContainer implements ModContainer
|
||||
{
|
||||
private ModMetadata md;
|
||||
private ArtifactVersion processedVersion;
|
||||
|
||||
public DummyModContainer(ModMetadata md)
|
||||
{
|
||||
|
@ -39,9 +42,9 @@ public class DummyModContainer implements ModContainer
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,7 +108,11 @@ public class DummyModContainer implements ModContainer
|
|||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
return null;
|
||||
if (processedVersion == null)
|
||||
{
|
||||
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
|
||||
}
|
||||
return processedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
|
@ -27,6 +28,7 @@ import com.google.common.collect.BiMap;
|
|||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
|
@ -125,7 +127,7 @@ public class FMLModContainer implements ModContainer
|
|||
|
||||
if (overridesMetadata || !modMetadata.useDependencyInformation)
|
||||
{
|
||||
List<ArtifactVersion> requirements = Lists.newArrayList();
|
||||
Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
List<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
List<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
annotationDependencies = (String) descriptor.get("dependencies");
|
||||
|
@ -133,11 +135,18 @@ public class FMLModContainer implements ModContainer
|
|||
modMetadata.requiredMods = requirements;
|
||||
modMetadata.dependencies = dependencies;
|
||||
modMetadata.dependants = dependants;
|
||||
FMLLog.finest("Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
|
||||
}
|
||||
if (Strings.isNullOrEmpty(modMetadata.name))
|
||||
{
|
||||
FMLLog.info("Mod %s is missing a required element, name. Substituting %s", getModId(), getModId());
|
||||
modMetadata.name = getModId();
|
||||
}
|
||||
if (Strings.isNullOrEmpty(modMetadata.version))
|
||||
{
|
||||
FMLLog.warning("Mod %s is missing a required element, version. Substituting 1", getModId());
|
||||
modMetadata.version = "1";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -147,7 +156,7 @@ public class FMLModContainer implements ModContainer
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return modMetadata.requiredMods;
|
||||
}
|
||||
|
@ -167,7 +176,7 @@ public class FMLModContainer implements ModContainer
|
|||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
return (overridesMetadata ? annotationDependencies : modMetadata.printableSortingRules());
|
||||
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? annotationDependencies : modMetadata.printableSortingRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,6 +2,7 @@ package cpw.mods.fml.common;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
|
@ -53,7 +54,7 @@ public class InjectedModContainer implements ModContainer
|
|||
wrappedContainer.setEnabledState(enabled);
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return wrappedContainer.getRequirements();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
@ -30,14 +31,17 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Multiset.Entry;
|
||||
import com.google.common.collect.Multisets;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
@ -173,7 +177,7 @@ public class Loader
|
|||
FMLLog.fine("Verifying mod requirements are satisfied");
|
||||
try
|
||||
{
|
||||
Map<String, ArtifactVersion> modVersions = Maps.newHashMap();
|
||||
BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
|
||||
for (ModContainer mod : mods)
|
||||
{
|
||||
modVersions.put(mod.getModId(), mod.getProcessedVersion());
|
||||
|
@ -181,18 +185,29 @@ public class Loader
|
|||
|
||||
for (ModContainer mod : mods)
|
||||
{
|
||||
Set<ArtifactVersion> missingMods = Sets.difference(mod.getRequirements(), modVersions.values());
|
||||
if (!missingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
|
||||
throw new MissingModsException(missingMods);
|
||||
}
|
||||
ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
|
||||
for (ArtifactVersion v : allDeps)
|
||||
{
|
||||
missingMods = Sets.newHashSet();
|
||||
if (modVersions.containsKey(v.getLabel()))
|
||||
{
|
||||
if (!v.containsVersion(modVersions.get(v.getLabel())))
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), allDeps);
|
||||
throw new LoaderException();
|
||||
missingMods.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!missingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), missingMods);
|
||||
throw new MissingModsException(missingMods);
|
||||
}
|
||||
}
|
||||
|
||||
FMLLog.fine("All mod requirements are satisfied");
|
||||
|
@ -506,7 +521,7 @@ public class Loader
|
|||
return modClassLoader;
|
||||
}
|
||||
|
||||
public void computeDependencies(String dependencyString, List<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
public void computeDependencies(String dependencyString, Set<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
{
|
||||
if (dependencyString == null || dependencyString.length() == 0)
|
||||
{
|
||||
|
|
19
fml/common/cpw/mods/fml/common/MissingModsException.java
Normal file
19
fml/common/cpw/mods/fml/common/MissingModsException.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class MissingModsException extends RuntimeException
|
||||
{
|
||||
|
||||
public Set<ArtifactVersion> missingMods;
|
||||
|
||||
public MissingModsException(Set<ArtifactVersion> missingMods)
|
||||
{
|
||||
this.missingMods = missingMods;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ package cpw.mods.fml.common;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
|
@ -90,7 +91,7 @@ public interface ModContainer
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
List<ArtifactVersion> getRequirements();
|
||||
Set<ArtifactVersion> getRequirements();
|
||||
|
||||
/**
|
||||
* A list of modids that should be loaded prior to this one. The special
|
||||
|
|
|
@ -16,8 +16,10 @@ package cpw.mods.fml.common;
|
|||
|
||||
import static argo.jdom.JsonNodeBuilders.aStringBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import argo.jdom.JsonNode;
|
||||
|
@ -82,7 +84,7 @@ public class ModMetadata
|
|||
public List<ModContainer> childMods = Lists.newArrayList();
|
||||
|
||||
public boolean useDependencyInformation;
|
||||
public List<ArtifactVersion> requiredMods;
|
||||
public Set<ArtifactVersion> requiredMods;
|
||||
public List<ArtifactVersion> dependencies;
|
||||
public List<ArtifactVersion> dependants;
|
||||
public boolean autogenerated;
|
||||
|
@ -109,9 +111,9 @@ public class ModMetadata
|
|||
credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
|
||||
parent = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
|
||||
authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
|
||||
requiredMods = processReferences((List<String>)processedFields.get(aStringBuilder("requiredMods")));
|
||||
dependencies = processReferences((List<String>)processedFields.get(aStringBuilder("dependencies")));
|
||||
dependants = processReferences((List<String>)processedFields.get(aStringBuilder("dependants")));
|
||||
requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), Set.class);
|
||||
dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), List.class);
|
||||
dependants = processReferences(processedFields.get(aStringBuilder("dependants")), List.class);
|
||||
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
|
||||
}
|
||||
|
||||
|
@ -119,14 +121,23 @@ public class ModMetadata
|
|||
{
|
||||
}
|
||||
|
||||
private List<ArtifactVersion> processReferences(List<String> refs)
|
||||
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
|
||||
{
|
||||
List<ArtifactVersion> res = Lists.newArrayList();
|
||||
T res = null;
|
||||
try
|
||||
{
|
||||
res = retType.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// unpossible
|
||||
}
|
||||
|
||||
if (refs == null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
for (String ref : refs)
|
||||
for (String ref : ((List<String>)refs))
|
||||
{
|
||||
res.add(VersionParser.parseVersionReference(ref));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.EnumSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
@ -65,7 +66,7 @@ public class ModLoaderModContainer implements ModContainer
|
|||
{
|
||||
public BaseModProxy mod;
|
||||
private File modSource;
|
||||
public List<ArtifactVersion> requirements = Lists.newArrayList();
|
||||
public Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
public ArrayList<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
public ArrayList<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
private ContainerType sourceType;
|
||||
|
@ -381,7 +382,7 @@ public class ModLoaderModContainer implements ModContainer
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return requirements;
|
||||
}
|
||||
|
|
|
@ -30,5 +30,7 @@ public interface ArtifactVersion
|
|||
{
|
||||
String getLabel();
|
||||
|
||||
String getVersionString();
|
||||
|
||||
boolean containsVersion(ArtifactVersion source);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,12 @@ public class DefaultArtifactVersion implements ArtifactVersion
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString()
|
||||
{
|
||||
return comparableVersion==null ? "any" : comparableVersion.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
{
|
||||
this.func_71352_k();
|
||||
}
|
||||
+ FMLClientHandler.instance().reloadTextureFX();
|
||||
+ FMLClientHandler.instance().onInitializationComplete();
|
||||
}
|
||||
|
||||
private void func_71357_I() throws LWJGLException
|
||||
|
|
Loading…
Reference in a new issue