diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 0c217da3d8..11821d7caf 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -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 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(); diff --git a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java b/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java index f6620fc231..9448ded820 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java @@ -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); } } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java b/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java new file mode 100644 index 0000000000..fe62fd29aa --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java @@ -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); + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/client/GuiJava8Error.java b/src/main/java/net/minecraftforge/fml/client/GuiJava8Error.java index d21dfcebdd..b917f6650f 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiJava8Error.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiJava8Error.java @@ -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); } } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java index 99e3337ca0..d69264a999 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java @@ -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); } } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java b/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java new file mode 100644 index 0000000000..dba91977fd --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java @@ -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 wrongMinecraftExceptions; + private final List 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; + } + } + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java b/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java index 64b1537a6f..e1dc95341f 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java @@ -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; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java b/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java index dae6547b49..d3d878cae6 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java @@ -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); } } diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java index aa52670bfa..9905a6af80 100644 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -236,6 +236,8 @@ public class Loader private void sortModList() { FMLLog.finer("Verifying mod requirements are satisfied"); + List wrongMinecraftExceptions = new ArrayList(); + List missingModsExceptions = new ArrayList(); try { BiMap 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 names = Maps.uniqueIndex(mod.getRequirements(), new ArtifactVersionNameFunction()); Set 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 allDeps = ImmutableList.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.create()); ModSorter sorter = new ModSorter(getActiveModList(), namedMods); diff --git a/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java b/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java new file mode 100644 index 0000000000..aee354f96b --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java @@ -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 wrongMinecraftExceptions; + public final ListmissingModsExceptions; + public MultipleModsErrored(List wrongMinecraftExceptions, List missingModsExceptions) + { + this.wrongMinecraftExceptions = wrongMinecraftExceptions; + this.missingModsExceptions = missingModsExceptions; + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java b/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java index 81fc3a20d5..aa0575cea4 100644 --- a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java +++ b/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java @@ -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 { diff --git a/src/main/resources/assets/forge/lang/en_US.lang b/src/main/resources/assets/forge/lang/en_US.lang index 3b40d1ce89..6447bd7291 100644 --- a/src/main/resources/assets/forge/lang/en_US.lang +++ b/src/main/resources/assets/forge/lang/en_US.lang @@ -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