Improve exception messages during initialization.

This commit is contained in:
ichttt 2017-02-24 02:15:11 +01:00 committed by LexManos
parent 64c9aae0c4
commit bd4fe54753
12 changed files with 366 additions and 125 deletions

View file

@ -96,6 +96,7 @@ import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.LoaderException;
import net.minecraftforge.fml.common.MetadataCollection;
import net.minecraftforge.fml.common.MissingModsException;
import net.minecraftforge.fml.common.MultipleModsErrored;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.ModMetadata;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
@ -185,6 +186,8 @@ public class FMLClientHandler implements IFMLSidedHandler
private DuplicateModsFoundException dupesFound;
private MultipleModsErrored multipleModsErrored;
private boolean serverShouldBeKilledQuietly;
private List<IResourcePack> resourcePackList;
@ -253,6 +256,10 @@ public class FMLClientHandler implements IFMLSidedHandler
FMLLog.log(Level.ERROR, custom, "A custom exception was thrown by a mod, the game will now halt");
customError = custom;
}
catch (MultipleModsErrored multiple)
{
multipleModsErrored = multiple;
}
catch (LoaderException le)
{
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
@ -333,7 +340,7 @@ public class FMLClientHandler implements IFMLSidedHandler
*/
public void finishMinecraftLoading()
{
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null || modSorting!=null || j8onlymods!=null)
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null || modSorting!=null || j8onlymods!=null || multipleModsErrored !=null)
{
SplashProgress.finish();
return;
@ -441,6 +448,10 @@ public class FMLClientHandler implements IFMLSidedHandler
{
showGuiScreen(new GuiCustomModLoadingErrorScreen(customError));
}
else if (multipleModsErrored != null)
{
showGuiScreen(new GuiMultipleModsErrored(multipleModsErrored));
}
else
{
logMissingTextureErrors();

View file

@ -19,30 +19,22 @@
package net.minecraftforge.fml.client;
import java.io.File;
import java.util.Map.Entry;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraftforge.fml.common.DuplicateModsFoundException;
import net.minecraftforge.fml.common.ModContainer;
public class GuiDupesFound extends GuiErrorScreen
import java.io.File;
import java.util.Map.Entry;
public class GuiDupesFound extends GuiErrorBase
{
private DuplicateModsFoundException dupes;
public GuiDupesFound(DuplicateModsFoundException dupes)
{
super(null,null);
this.dupes = dupes;
}
@Override
public void initGui()
{
super.initGui();
this.buttonList.clear();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
@ -59,5 +51,6 @@ public class GuiDupesFound extends GuiErrorScreen
offset+=10;
this.drawCenteredString(this.fontRendererObj, String.format("%s : %s", mc.getKey().getModId(), mc.getValue().getName()), this.width / 2, offset, 0xEEEEEE);
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
}

View file

@ -0,0 +1,92 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Loader;
import org.apache.logging.log4j.Level;
import java.awt.*;
import java.io.File;
public class GuiErrorBase extends GuiErrorScreen
{
static final File minecraftDir = new File(Loader.instance().getConfigDir().getParent());
static final File clientLog = new File(minecraftDir, "logs/fml-client-latest.log");
public GuiErrorBase()
{
super(null, null);
}
private String translateOrDefault(String translateKey, String alternative, Object... format)
{
return I18n.hasKey(translateKey) ? I18n.format(translateKey, format) : String.format(alternative, format); //When throwing a DuplicateModsException, the translation system does not work...
}
@Override
public void initGui()
{
super.initGui();
this.buttonList.clear();
this.buttonList.add(new GuiButton(10, 50, this.height - 38, this.width / 2 - 55, 20, translateOrDefault("fml.button.open.mods.folder", "Open Mods Folder")));
String openFileText = translateOrDefault("fml.button.open.file", "Open %s", clientLog.getName());
this.buttonList.add(new GuiButton(11, this.width / 2 + 5, this.height - 38, this.width / 2 - 55, 20, openFileText));
}
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 10)
{
try
{
File modsDir = new File(minecraftDir, "mods");
Desktop.getDesktop().open(modsDir);
}
catch (Exception e)
{
FMLLog.log(Level.ERROR, e, "Problem opening mods folder");
}
}
else if (button.id == 11)
{
try
{
Desktop.getDesktop().open(clientLog);
}
catch (Exception e)
{
FMLLog.log(Level.ERROR, e, "Problem opening log file " + clientLog);
}
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
for(GuiButton button : buttonList)
{
button.drawButton(this.mc, mouseX, mouseY);
}
}
}

View file

@ -20,7 +20,6 @@
package net.minecraftforge.fml.client;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.FMLCommonHandler;
@ -32,39 +31,39 @@ import org.apache.logging.log4j.Level;
import com.google.common.collect.Lists;
import java.awt.*;
import java.io.IOException;
import java.awt.Desktop;
import java.net.URI;
import java.util.List;
public class GuiJava8Error extends GuiErrorScreen
public class GuiJava8Error extends GuiErrorBase
{
private Java8VersionException java8VersionException;
public GuiJava8Error(Java8VersionException java8VersionException)
{
super(null,null);
this.java8VersionException = java8VersionException;
}
@Override
public void initGui()
{
this.buttonList.clear();
this.buttonList.add(new GuiButton(1, 50, this.height - 38, this.width/2 -55, 20, I18n.format("fml.button.visitjavadownloads")));
super.initGui();
this.buttonList.remove(1);
if (java8VersionException.getMods().isEmpty())
{
this.buttonList.add(new GuiButton(3, this.width / 2 + 5, this.height - 38, this.width / 2 - 55, 20, I18n.format("fml.button.continue")));
}
else
{
this.buttonList.add(new GuiButton(2, this.width / 2 + 5, this.height - 38, this.width / 2 - 55, 20, I18n.format("menu.quit")));
this.buttonList.remove(0);
this.buttonList.add(new GuiButton(1, 50, this.height -38, this.width / 2 - 55, 20, I18n.format("fml.button.continue")));
}
this.buttonList.add(new GuiButton(2, this.width / 2 + 5, this.height -38, this.width/2 -55, 20, I18n.format("fml.button.visitjavadownloads")));
}
@Override
protected void actionPerformed(GuiButton button) throws IOException
protected void actionPerformed(GuiButton button)
{
if (button.id == 1)
{
FMLClientHandler.instance().showGuiScreen(null);
}
else if (button.id == 2)
{
try
{
@ -75,13 +74,9 @@ public class GuiJava8Error extends GuiErrorScreen
FMLLog.log(Level.ERROR, e, "Problem launching browser");
}
}
else if (button.id == 2)
else
{
FMLCommonHandler.instance().exitJava(1,true);
}
else if (button.id == 3)
{
FMLClientHandler.instance().showGuiScreen(null);
super.actionPerformed(button);
}
}
@ -135,13 +130,7 @@ public class GuiJava8Error extends GuiErrorScreen
this.drawString(this.fontRendererObj, line, (this.width - maxWidth) / 2, offset, 0xFFFFFF);
offset += this.fontRendererObj.FONT_HEIGHT + 2;
}
offset += 15;
}
// super.super
for (int i = 0; i < this.buttonList.size(); ++i)
{
((GuiButton)this.buttonList.get(i)).drawButton(this.mc, mouseX, mouseY);
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
}

View file

@ -19,71 +19,21 @@
package net.minecraftforge.fml.client;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.MissingModsException;
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
import org.apache.logging.log4j.Level;
public class GuiModsMissing extends GuiErrorScreen
public class GuiModsMissing extends GuiErrorBase
{
private File minecraftDir = new File(Loader.instance().getConfigDir().getParent());
private File clientLog = new File(minecraftDir, "logs/fml-client-latest.log");
private MissingModsException modsMissing;
public GuiModsMissing(MissingModsException modsMissing)
{
super(null,null);
this.modsMissing = modsMissing;
}
@Override
public void initGui()
{
super.initGui();
this.buttonList.clear();
this.buttonList.add(new GuiButton(1, 50, this.height - 38, this.width/2 -55, 20, I18n.format("fml.button.open.mods.folder")));
String openFileText = I18n.format("fml.button.open.file", clientLog.getName());
this.buttonList.add(new GuiButton(2, this.width / 2 + 5, this.height - 38, this.width / 2 - 55, 20, openFileText));
}
@Override
protected void actionPerformed(GuiButton button) throws IOException
{
if (button.id == 1)
{
try
{
File modsDir = new File(minecraftDir, "mods");
Desktop.getDesktop().open(modsDir);
}
catch (Exception e)
{
FMLLog.log(Level.ERROR, e, "Problem opening mods folder");
}
}
else if (button.id == 2)
{
try
{
Desktop.getDesktop().open(clientLog);
}
catch (Exception e)
{
FMLLog.log(Level.ERROR, e, "Problem opening log file " + clientLog);
}
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
@ -108,15 +58,11 @@ public class GuiModsMissing extends GuiErrorScreen
continue;
}
}
this.drawCenteredString(this.fontRendererObj, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.width / 2, offset, 0xEEEEEE);
this.drawCenteredString(this.fontRendererObj, String.format(TextFormatting.BOLD + "%s" + TextFormatting.RESET + " : %s", v.getLabel(), v.getRangeString()), this.width / 2, offset, 0xEEEEEE);
}
offset+=20;
String seeLogText = I18n.format("fml.messages.mod.missing.dependencies.see.log", clientLog.getName());
String seeLogText = I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.clientLog.getName());
this.drawCenteredString(this.fontRendererObj, seeLogText, this.width / 2, offset, 0xFFFFFF);
for (int i = 0; i < this.buttonList.size(); ++i)
{
this.buttonList.get(i).drawButton(this.mc, mouseX, mouseY);
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
}

View file

@ -0,0 +1,156 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.MissingModsException;
import net.minecraftforge.fml.common.MultipleModsErrored;
import net.minecraftforge.fml.common.WrongMinecraftVersionException;
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
import java.util.List;
public class GuiMultipleModsErrored extends GuiErrorBase
{
private final List<WrongMinecraftVersionException> wrongMinecraftExceptions;
private final List<MissingModsException> missingModsExceptions;
private GuiList list;
public GuiMultipleModsErrored(MultipleModsErrored exception)
{
wrongMinecraftExceptions = exception.wrongMinecraftExceptions;
missingModsExceptions = exception.missingModsExceptions;
}
@Override
public void initGui()
{
super.initGui();
int additionalSize = missingModsExceptions.isEmpty()||wrongMinecraftExceptions.isEmpty() ? 20 : 55;
for(MissingModsException exception : missingModsExceptions)
{
additionalSize+=exception.missingMods.size()*10;
}
list = new GuiList(wrongMinecraftExceptions.size()*10+missingModsExceptions.size()*15+additionalSize);
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
this.drawDefaultBackground();
this.list.drawScreen(mouseX, mouseY, partialTicks);
this.drawCenteredString(this.fontRendererObj, I18n.format("fml.messages.mod.missing.multiple", missingModsExceptions.size() + wrongMinecraftExceptions.size()), this.width/2, 10, 0xFFFFFF);
super.drawScreen(mouseX, mouseY, partialTicks);
}
@Override
public void actionPerformed(GuiButton button)
{
this.list.actionPerformed(button);
super.actionPerformed(button);
}
private class GuiList extends GuiScrollingList
{
public GuiList(int entryHeight)
{
super(GuiMultipleModsErrored.this.mc,
GuiMultipleModsErrored.this.width-20,
GuiMultipleModsErrored.this.height -30,
30, GuiMultipleModsErrored.this.height-50,
10,
entryHeight,
GuiMultipleModsErrored.this.width,
GuiMultipleModsErrored.this.height);
}
@Override
protected int getSize()
{
return 1;
}
@Override
protected void elementClicked(int index, boolean doubleClick) {}
@Override
protected boolean isSelected(int index)
{
return false;
}
@Override
protected void drawBackground()
{
drawDefaultBackground();
}
@Override
protected void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess)
{
int offset = slotTop;
FontRenderer renderer = GuiMultipleModsErrored.this.fontRendererObj;
if (!wrongMinecraftExceptions.isEmpty())
{
renderer.drawString(TextFormatting.UNDERLINE + I18n.format("fml.messages.mod.wrongminecraft", Loader.instance().getMinecraftModContainer().getVersion()), this.left, offset, 0xFFFFFF);
offset+=15;
for(WrongMinecraftVersionException exception : wrongMinecraftExceptions)
{
renderer.drawString(I18n.format("fml.messages.mod.wrongminecraft.requirement", TextFormatting.BOLD + exception.mod.getName() + TextFormatting.RESET, exception.mod.getModId(), exception.mod.acceptableMinecraftVersionRange().toStringFriendly()), this.left, offset, 0xFFFFFF);
offset += 10;
}
offset+=5;
renderer.drawString(I18n.format("fml.messages.mod.wrongminecraft.fix.multiple"), this.left, offset, 0xFFFFFF);
offset+=20;
}
if (!missingModsExceptions.isEmpty())
{
renderer.drawString(TextFormatting.UNDERLINE + I18n.format("fml.messages.mod.missing.dependencies.multiple"), this.left, offset, 0xFFFFFF);
offset+=15;
for (MissingModsException exception : missingModsExceptions)
{
renderer.drawString(I18n.format("fml.messages.mod.missing.dependencies.fix", TextFormatting.BOLD + exception.getModName() + TextFormatting.RESET), this.left, offset, 0xFFFFFF);
for (ArtifactVersion v : exception.missingMods)
{
offset+=10;
if (v instanceof DefaultArtifactVersion)
{
DefaultArtifactVersion dav = (DefaultArtifactVersion)v;
if (dav.getRange() != null)
{
String message = String.format(TextFormatting.BOLD + "%s " + TextFormatting.RESET + "%s", v.getLabel(), dav.getRange().toStringFriendly());
renderer.drawString(message, this.left, offset, 0xEEEEEE);
continue;
}
}
renderer.drawString(String.format(TextFormatting.BOLD + "%s" + TextFormatting.RESET + " : %s", v.getLabel(), v.getRangeString()), this.left, offset, 0xEEEEEE);
}
offset += 15;
}
}
}
}
}

View file

@ -19,9 +19,6 @@
package net.minecraftforge.fml.client;
import java.io.IOException;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
@ -30,10 +27,12 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
import java.util.List;
public abstract class GuiScrollingList
{
private final Minecraft client;

View file

@ -20,35 +20,32 @@
package net.minecraftforge.fml.client;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.WrongMinecraftVersionException;
public class GuiWrongMinecraft extends GuiErrorScreen
public class GuiWrongMinecraft extends GuiErrorBase
{
private WrongMinecraftVersionException wrongMC;
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
{
super(null,null);
this.wrongMC = wrongMC;
}
@Override
public void initGui()
{
super.initGui();
this.buttonList.clear();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
this.drawDefaultBackground();
int offset = 75;
this.drawCenteredString(this.fontRendererObj, "Forge Mod Loader has found a problem with your minecraft installation", this.width / 2, offset, 0xFFFFFF);
offset+=10;
this.drawCenteredString(this.fontRendererObj, String.format("The mod listed below does not want to run in Minecraft version %s", Loader.instance().getMinecraftModContainer().getVersion()), this.width / 2, offset, 0xFFFFFF);
offset+=5;
offset+=10;
this.drawCenteredString(this.fontRendererObj, String.format("%s (%s) wants Minecraft %s", wrongMC.mod.getName(), wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange()), this.width / 2, offset, 0xEEEEEE);
this.drawCenteredString(this.fontRendererObj, I18n.format("fml.messages.mod.wrongminecraft", Loader.instance().getMinecraftModContainer().getVersion()), this.width / 2, offset, 0xFFFFFF);
offset+=15;
this.drawCenteredString(this.fontRendererObj, I18n.format("fml.messages.mod.wrongminecraft.requirement", TextFormatting.BOLD + wrongMC.mod.getName() + TextFormatting.RESET, wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange().toStringFriendly()), this.width / 2, offset, 0xEEEEEE);
offset+=15;
this.drawCenteredString(this.fontRendererObj, I18n.format("fml.messages.mod.wrongminecraft.fix", wrongMC.mod.getName()),this.width/2, offset, 0xFFFFFF);
offset+=20;
this.drawCenteredString(this.fontRendererObj, "The file 'fml-client-latest.log' contains more information", this.width / 2, offset, 0xFFFFFF);
this.drawCenteredString(this.fontRendererObj, I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.clientLog.getName()), this.width / 2, offset, 0xFFFFFF);
super.drawScreen(mouseX, mouseY, partialTicks);
}
}

View file

@ -236,6 +236,8 @@ public class Loader
private void sortModList()
{
FMLLog.finer("Verifying mod requirements are satisfied");
List<WrongMinecraftVersionException> wrongMinecraftExceptions = new ArrayList<WrongMinecraftVersionException>();
List<MissingModsException> missingModsExceptions = new ArrayList<MissingModsException>();
try
{
BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
@ -250,9 +252,10 @@ public class Loader
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());
RuntimeException ret = new WrongMinecraftVersionException(mod, getMCVersionString());
WrongMinecraftVersionException ret = new WrongMinecraftVersionException(mod, getMCVersionString());
FMLLog.severe(ret.getMessage());
throw ret;
wrongMinecraftExceptions.add(ret);
continue;
}
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new ArtifactVersionNameFunction());
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
@ -265,9 +268,10 @@ public class Loader
{
versionMissingMods.add(names.get(modid));
}
RuntimeException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
MissingModsException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
FMLLog.severe(ret.getMessage());
throw ret;
missingModsExceptions.add(ret);
continue;
}
reqList.putAll(mod.getModId(), names.keySet());
ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
@ -284,13 +288,28 @@ public class Loader
if (!versionMissingMods.isEmpty())
{
FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), versionMissingMods);
RuntimeException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
MissingModsException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
FMLLog.severe(ret.toString());
throw ret;
missingModsExceptions.add(ret);
}
}
FMLLog.finer("All mod requirements are satisfied");
if (wrongMinecraftExceptions.isEmpty() && missingModsExceptions.isEmpty())
{
FMLLog.finer("All mod requirements are satisfied");
}
else if (missingModsExceptions.size()==1 && wrongMinecraftExceptions.isEmpty())
{
throw missingModsExceptions.get(0);
}
else if (wrongMinecraftExceptions.size()==1 && missingModsExceptions.isEmpty())
{
throw wrongMinecraftExceptions.get(0);
}
else
{
throw new MultipleModsErrored(wrongMinecraftExceptions, missingModsExceptions);
}
reverseDependencies = Multimaps.invertFrom(reqList, ArrayListMultimap.<String,String>create());
ModSorter sorter = new ModSorter(getActiveModList(), namedMods);

View file

@ -0,0 +1,33 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common;
import java.util.List;
public class MultipleModsErrored extends RuntimeException
{
public final List<WrongMinecraftVersionException> wrongMinecraftExceptions;
public final List<MissingModsException>missingModsExceptions;
public MultipleModsErrored(List<WrongMinecraftVersionException> wrongMinecraftExceptions, List<MissingModsException> missingModsExceptions)
{
this.wrongMinecraftExceptions = wrongMinecraftExceptions;
this.missingModsExceptions = missingModsExceptions;
}
}

View file

@ -212,9 +212,9 @@ public class Restriction
}
else if ( getLowerBound() != null && getUpperBound() != null )
{
if ( getLowerBound().equals(getUpperBound()) )
if ( getLowerBound().getVersionString().equals(getUpperBound().getVersionString()) )
{
return getLowerBound().toString();
return getLowerBound().getVersionString();
}
else
{

View file

@ -175,6 +175,12 @@ fml.messages.countbadandgood=%s of %s mods have this problem
fml.messages.mod.missing.dependencies=%s is missing mods it depends on.
fml.messages.mod.missing.dependencies.fix=Include the following mods or remove %s.
fml.messages.mod.missing.dependencies.see.log=See '%s' for technical information.
fml.messages.mod.missing.dependencies.multiple=Some mods are missing mods they depends on.
fml.messages.mod.missing.multiple=There were %s errors loading Minecraft
fml.messages.mod.wrongminecraft=The mods listed below can't run in Minecraft version %s
fml.messages.mod.wrongminecraft.requirement=%s (%s) requires Minecraft %s
fml.messages.mod.wrongminecraft.fix=Try to find an update or remove %s
fml.messages.mod.wrongminecraft.fix.multiple=Try to find an update or remove these mods
fml.messages.version.restriction.any=any
fml.messages.version.restriction.lower.inclusive=%s or above
fml.messages.version.restriction.lower.exclusive=above %s