Better error passing from early to game client launch.
This commit is contained in:
parent
c6e7bbe18b
commit
d5e04dbcb5
|
@ -180,7 +180,11 @@ project(':forge') {
|
|||
main 'net.minecraftforge.fml.LaunchTesting'
|
||||
systemProperties = [
|
||||
"org.lwjgl.util.Debug": "true",
|
||||
"org.lwjgl.util.DebugLoader": "true"
|
||||
"org.lwjgl.util.DebugLoader": "true",
|
||||
"mc.version": "${MC_VERSION}",
|
||||
"mcp.version": "${MCP_VERSION}",
|
||||
"forge.version": "${project.version}",
|
||||
"forge.spec":"${SPEC_VERSION}"
|
||||
]
|
||||
environment += [
|
||||
target:'fmldevclient',
|
||||
|
|
|
@ -39,14 +39,23 @@ public class ForgeVersion
|
|||
|
||||
private static final String forgeVersion;
|
||||
|
||||
private static final String forgeSpec;
|
||||
|
||||
static {
|
||||
String vers = ForgeVersion.class.getPackage().getImplementationVersion();
|
||||
if (vers == null) {
|
||||
vers = System.getProperty("forge.version");
|
||||
}
|
||||
if (vers == null) throw new RuntimeException("Missing forge version, cannot continue");
|
||||
String spec = ForgeVersion.class.getPackage().getSpecificationVersion();
|
||||
if (spec == null) {
|
||||
spec = System.getProperty("forge.spec");
|
||||
}
|
||||
if (spec == null) throw new RuntimeException("Missing forge spec, cannot continue");
|
||||
forgeVersion = vers;
|
||||
forgeSpec = spec;
|
||||
LOGGER.info(CORE, "Found Forge version {}", forgeVersion);
|
||||
LOGGER.info(CORE, "Found Forge spec {}", forgeSpec);
|
||||
}
|
||||
|
||||
public static String getVersion()
|
||||
|
@ -64,5 +73,9 @@ public class ForgeVersion
|
|||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getSpec() {
|
||||
return forgeSpec;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,10 @@ package net.minecraftforge.fml;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import net.minecraft.nbt.INBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -65,7 +64,7 @@ public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.Worl
|
|||
{
|
||||
final NBTTagCompound mod = new NBTTagCompound();
|
||||
mod.setString("ModId", mi.getModId());
|
||||
mod.setString("ModVersion", mi.getVersion().getVersionString());
|
||||
mod.setString("ModVersion", MavenVersionStringHelper.artifactVersionToString(mi.getVersion()));
|
||||
modList.add(mod);
|
||||
});
|
||||
fmlData.setTag("LoadingModList", modList);
|
||||
|
@ -98,9 +97,9 @@ public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.Worl
|
|||
LOGGER.error(WORLDPERSISTENCE,"This world was saved with mod {} which appears to be missing, things may not work well", modId);
|
||||
continue;
|
||||
}
|
||||
if (!modVersion.equals(container.get().getModInfo().getVersion().getVersionString()))
|
||||
if (!Objects.equals(modVersion, MavenVersionStringHelper.artifactVersionToString(container.get().getModInfo().getVersion())))
|
||||
{
|
||||
LOGGER.info(WORLDPERSISTENCE,"This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, container.get().getModInfo().getVersion().getVersionString());
|
||||
LOGGER.info(WORLDPERSISTENCE,"This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, MavenVersionStringHelper.artifactVersionToString(container.get().getModInfo().getVersion()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ public class ForgeI18n {
|
|||
customFactories.put("lower", (name, formatString, locale) -> new CustomReadOnlyFormat((stringBuffer, objectToParse) -> stringBuffer.append(StringUtils.toLowerCase((String)objectToParse))));
|
||||
customFactories.put("upper", (name, formatString, locale) -> new CustomReadOnlyFormat((stringBuffer, objectToParse) -> stringBuffer.append(StringUtils.toUpperCase((String)objectToParse))));
|
||||
customFactories.put("exc", (name, formatString, locale) -> new CustomReadOnlyFormat((stringBuffer, objectToParse) -> parseException(formatString, stringBuffer, objectToParse)));
|
||||
customFactories.put("vr", (name, formatString, locale) -> new CustomReadOnlyFormat(((stringBuffer, o) -> MavenVersionStringHelper.parseVersionRange(formatString, stringBuffer, o))));
|
||||
}
|
||||
|
||||
private static void parseException(final String formatString, final StringBuffer stringBuffer, final Object objectToParse) {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package net.minecraftforge.fml;
|
||||
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.Restriction;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MavenVersionStringHelper {
|
||||
public static String artifactVersionToString(final ArtifactVersion artifactVersion) {
|
||||
return artifactVersion.toString();
|
||||
}
|
||||
|
||||
public static String versionRangeToString(final VersionRange range) {
|
||||
return range.getRestrictions().stream().map(MavenVersionStringHelper::restrictionToString).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
public static String restrictionToString(final Restriction restriction) {
|
||||
if ( restriction.getLowerBound() == null && restriction.getUpperBound() == null )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.any");
|
||||
}
|
||||
else if ( restriction.getLowerBound() != null && restriction.getUpperBound() != null )
|
||||
{
|
||||
if (Objects.equals(artifactVersionToString(restriction.getLowerBound()), artifactVersionToString(restriction.getUpperBound())))
|
||||
{
|
||||
return artifactVersionToString(restriction.getLowerBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (restriction.isLowerBoundInclusive() && restriction.isUpperBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.inclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else if (restriction.isLowerBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.upperexclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else if (restriction.isUpperBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.lowerexclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.exclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( restriction.getLowerBound() != null )
|
||||
{
|
||||
if ( restriction.isLowerBoundInclusive() )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.lower.inclusive", restriction.getLowerBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.lower.exclusive", restriction.getLowerBound());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( restriction.isUpperBoundInclusive() )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.upper.inclusive", restriction.getUpperBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.upper.exclusive", restriction.getUpperBound());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseVersionRange(final String formatString, final StringBuffer stringBuffer, final Object range) {
|
||||
stringBuffer.append(versionRangeToString((VersionRange) range));
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ public class ModLoader
|
|||
this.loadingModList = FMLLoader.getLoadingModList();
|
||||
this.modClassLoader = new ModLoadingClassLoader(this.launchClassLoader);
|
||||
this.loadingExceptions = FMLLoader.getLoadingModList().
|
||||
getErrors().stream().map(ModLoadingException::fromEarlyException).collect(Collectors.toList());
|
||||
getErrors().stream().flatMap(ModLoadingException::fromEarlyException).collect(Collectors.toList());
|
||||
Thread.currentThread().setContextClassLoader(this.modClassLoader);
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,6 @@ public class ModLoader
|
|||
}
|
||||
|
||||
public void loadMods() {
|
||||
if (!this.loadingExceptions.isEmpty()) {
|
||||
throw new LoadingFailedException(loadingExceptions);
|
||||
}
|
||||
final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods());
|
||||
ModContainer forgeModContainer;
|
||||
try
|
||||
|
@ -88,9 +85,12 @@ public class ModLoader
|
|||
catch (ClassNotFoundException | IllegalAccessException | NoSuchMethodException | InstantiationException | InvocationTargetException e)
|
||||
{
|
||||
LOGGER.error(CORE,"Unable to load the Forge Mod Container", e);
|
||||
loadingExceptions.add(new ModLoadingException(DefaultModInfos.forgeModInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadforge", e));
|
||||
loadingExceptions.add(new ModLoadingException(DefaultModInfos.forgeModInfo, ModLoadingStage.VALIDATE, "fml.modloading.failedtoloadforge", e));
|
||||
forgeModContainer = null;
|
||||
}
|
||||
if (!this.loadingExceptions.isEmpty()) {
|
||||
throw new LoadingFailedException(loadingExceptions);
|
||||
}
|
||||
final Stream<ModContainer> modContainerStream = loadingModList.getModFiles().stream().
|
||||
map(ModFileInfo::getFile).
|
||||
map(mf -> buildMods(mf, modClassLoader)).
|
||||
|
|
|
@ -59,8 +59,8 @@ public class ModLoadingException extends RuntimeException
|
|||
this.context = Arrays.asList(context);
|
||||
}
|
||||
|
||||
static ModLoadingException fromEarlyException(final EarlyLoadingException e) {
|
||||
return new ModLoadingException(null, ModLoadingStage.VALIDATE, e.getI18NMessage(), e, e.getContext().toArray());
|
||||
static Stream<ModLoadingException> fromEarlyException(final EarlyLoadingException e) {
|
||||
return e.getAllData().stream().map(ed->new ModLoadingException(null, ModLoadingStage.VALIDATE, ed.getI18message(), e.getCause(), ed.getArgs()));
|
||||
}
|
||||
|
||||
public String getI18NMessage() {
|
||||
|
|
|
@ -37,14 +37,10 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.fml.ForgeI18n;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.VersionChecker;
|
||||
import net.minecraftforge.fml.*;
|
||||
import net.minecraftforge.fml.client.ConfigGuiHandler;
|
||||
import net.minecraftforge.fml.client.ResourcePackLoader;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.MavenVersionAdapter;
|
||||
import net.minecraftforge.fml.loading.StringUtils;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
@ -291,7 +287,7 @@ public class GuiModList extends GuiScreen
|
|||
for (ModInfo mod : mods)
|
||||
{
|
||||
listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(mod.getDisplayName()) + 10);
|
||||
listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(MavenVersionAdapter.artifactVersionToString(mod.getVersion())) + 5);
|
||||
listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(MavenVersionStringHelper.artifactVersionToString(mod.getVersion())) + 5);
|
||||
}
|
||||
listWidth = Math.min(listWidth, 150);
|
||||
listWidth += listWidth % numButtons != 0 ? (numButtons - listWidth % numButtons) : 0;
|
||||
|
@ -455,7 +451,7 @@ public class GuiModList extends GuiScreen
|
|||
}).orElse(Pair.of(null, new Dimension(0, 0)));
|
||||
|
||||
lines.add(selectedMod.getDisplayName());
|
||||
lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.version", MavenVersionAdapter.artifactVersionToString(selectedMod.getVersion())));
|
||||
lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.version", MavenVersionStringHelper.artifactVersionToString(selectedMod.getVersion())));
|
||||
lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.idstate", selectedMod.getModId(), ModList.get().getModContainerById(selectedMod.getModId()).
|
||||
map(ModContainer::getCurrentState).map(Object::toString).orElse("NONE")));
|
||||
|
||||
|
|
|
@ -19,16 +19,14 @@
|
|||
|
||||
package net.minecraftforge.fml.client.gui;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiListExtended;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeVersion;
|
||||
import net.minecraftforge.fml.MavenVersionStringHelper;
|
||||
import net.minecraftforge.fml.VersionChecker;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
|
@ -97,7 +95,7 @@ public class GuiSlotModList extends GuiListExtended<GuiSlotModList.ModEntry>
|
|||
int top = this.getY();
|
||||
int left = this.getX();
|
||||
String name = stripControlCodes(modInfo.getDisplayName());
|
||||
String version = stripControlCodes(modInfo.getVersion().getVersionString());
|
||||
String version = stripControlCodes(MavenVersionStringHelper.artifactVersionToString(modInfo.getVersion()));
|
||||
VersionChecker.CheckResult vercheck = VersionChecker.getResult(modInfo);
|
||||
FontRenderer font = this.parent.getFontRenderer();
|
||||
font.drawString(font.trimStringToWidth(name, listWidth),left + 3, top + 2, 0xFFFFFF);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package net.minecraftforge.fml.common.toposort;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraftforge.fml.loading.EarlyLoadingException;
|
||||
import org.apache.logging.log4j.message.Message;
|
||||
import org.apache.logging.log4j.util.StringBuilderFormattable;
|
||||
|
||||
|
@ -35,6 +36,8 @@ import java.util.NoSuchElementException;
|
|||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Topological sort for mod loading
|
||||
|
@ -250,6 +253,13 @@ public class TopologicalSort
|
|||
buffer.append("Explored node set : {}\n").append(expandedNodes);
|
||||
buffer.append("Likely cycle is in : {}\n").append(Sets.difference(visitedNodes, expandedNodes));
|
||||
}
|
||||
|
||||
public List<EarlyLoadingException.ExceptionData> toExceptionData(Function<T, String> nodeMapper) {
|
||||
return Collections.singletonList(
|
||||
new EarlyLoadingException.ExceptionData("fml.messages.cycleproblem",
|
||||
nodeMapper.apply(node),
|
||||
visitedNodes.stream().map(nodeMapper).collect(Collectors.joining(","))));
|
||||
}
|
||||
}
|
||||
|
||||
public <T> TopoSortException(TopoSortExceptionData<T> data)
|
||||
|
|
|
@ -8,20 +8,34 @@ import java.util.List;
|
|||
* or server.
|
||||
*/
|
||||
public class EarlyLoadingException extends RuntimeException {
|
||||
private final String i18nMessage;
|
||||
private final List<Object> context;
|
||||
public static class ExceptionData {
|
||||
|
||||
public EarlyLoadingException(final String message, final String i18nMessage, final Throwable originalException, Object... context) {
|
||||
|
||||
private final String i18message;
|
||||
private final Object[] args;
|
||||
public ExceptionData(final String message, Object... args) {
|
||||
this.i18message = message;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public String getI18message() {
|
||||
return i18message;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
}
|
||||
private final List<ExceptionData> errorMessages;
|
||||
|
||||
public List<ExceptionData> getAllData() {
|
||||
return errorMessages;
|
||||
}
|
||||
|
||||
EarlyLoadingException(final String message, final Throwable originalException, List<ExceptionData> errorMessages) {
|
||||
super(message, originalException);
|
||||
this.i18nMessage = i18nMessage;
|
||||
this.context = Arrays.asList(context);
|
||||
this.errorMessages = errorMessages;
|
||||
}
|
||||
|
||||
public String getI18NMessage() {
|
||||
return this.i18nMessage;
|
||||
}
|
||||
|
||||
public List<Object> getContext() {
|
||||
return this.context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.logging.log4j.Logger;
|
|||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
@ -51,14 +52,20 @@ public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements I
|
|||
"net.minecraftforge.fml.common.versioning."
|
||||
);
|
||||
static {
|
||||
Path forgePath1 = null;
|
||||
Path patchedBinariesPath1 = null;
|
||||
Path srgMcPath1 = null;
|
||||
try {
|
||||
forgePath = Paths.get(FMLClientLaunchProvider.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||
patchedBinariesPath = forgePath.resolveSibling("forge-"+MCPVersion.getMCVersion()+"-"+ForgeVersion.getVersion()+"-client.jar");
|
||||
Path libs = forgePath.getParent().getParent().getParent().getParent().getParent();
|
||||
srgMcPath = libs.resolve(Paths.get("net","minecraft", "client", MCPVersion.getMCPandMCVersion(), "client-"+MCPVersion.getMCPandMCVersion()+"-srg.jar")).toAbsolutePath();
|
||||
forgePath1 = Paths.get(FMLClientLaunchProvider.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||
patchedBinariesPath1 = forgePath1.resolveSibling("forge-"+MCPVersion.getMCVersion()+"-"+ForgeVersion.getVersion()+"-client.jar");
|
||||
Path libs = forgePath1.getParent().getParent().getParent().getParent().getParent();
|
||||
srgMcPath1 = libs.resolve(Paths.get("net","minecraft", "client", MCPVersion.getMCPandMCVersion(), "client-"+MCPVersion.getMCPandMCVersion()+"-srg.jar")).toAbsolutePath();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("Unable to locate myself!");
|
||||
|
||||
}
|
||||
forgePath = forgePath1;
|
||||
patchedBinariesPath = patchedBinariesPath1;
|
||||
srgMcPath = srgMcPath1;
|
||||
}
|
||||
@Override
|
||||
public String name()
|
||||
|
@ -69,9 +76,12 @@ public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements I
|
|||
@Override
|
||||
public Path[] identifyTransformationTargets()
|
||||
{
|
||||
LOGGER.info("Found SRG MC at {}", srgMcPath.toString());
|
||||
LOGGER.info("Found Forge patches at {}", patchedBinariesPath.toString());
|
||||
LOGGER.info("Found Forge at {}", forgePath.toString());
|
||||
LOGGER.info("SRG MC at {} is {}", srgMcPath.toString(), Files.exists(srgMcPath) ? "present" : "missing");
|
||||
LOGGER.info("Forge patches at {} is {}", patchedBinariesPath.toString(), Files.exists(patchedBinariesPath) ? "present" : "missing");
|
||||
LOGGER.info("Forge at {} is {}", forgePath.toString(), Files.exists(forgePath) ? "present" : "missing");
|
||||
if (!(Files.exists(srgMcPath) && Files.exists(patchedBinariesPath) && Files.exists(forgePath))) {
|
||||
throw new RuntimeException("Failed to find patched jars");
|
||||
}
|
||||
return new Path[] {forgePath, patchedBinariesPath, srgMcPath};
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public class LanguageLoadingProvider
|
|||
final Package pkg = lp.getClass().getPackage();
|
||||
String implementationVersion = pkg.getImplementationVersion();
|
||||
if (implementationVersion == null) {
|
||||
implementationVersion = ForgeVersion.getVersion();
|
||||
implementationVersion = ForgeVersion.getSpec();
|
||||
}
|
||||
LOGGER.debug(CORE, "Found system classpath language provider {}, version {}", lp.name(), implementationVersion);
|
||||
languageProviderMap.put(lp.name(), new ModLanguageWrapper(lp, new DefaultArtifactVersion(implementationVersion)));
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import net.minecraftforge.fml.ForgeI18n;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
|
||||
import org.apache.maven.artifact.versioning.Restriction;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
|
||||
public final class MavenVersionAdapter {
|
||||
|
@ -25,66 +19,5 @@ public final class MavenVersionAdapter {
|
|||
throw new RuntimeException("Failed to parse spec", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String artifactVersionToString(final ArtifactVersion artifactVersion) {
|
||||
return artifactVersion.toString();
|
||||
}
|
||||
|
||||
public static String versionRangeToString(final VersionRange range) {
|
||||
return range.getRestrictions().stream().map(MavenVersionAdapter::restrictionToString).collect(Collectors.joining(","));
|
||||
}
|
||||
public static String restrictionToString(final Restriction restriction) {
|
||||
if ( restriction.getLowerBound() == null && restriction.getUpperBound() == null )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.any");
|
||||
}
|
||||
else if ( restriction.getLowerBound() != null && restriction.getUpperBound() != null )
|
||||
{
|
||||
if (Objects.equals(artifactVersionToString(restriction.getLowerBound()), artifactVersionToString(restriction.getUpperBound())))
|
||||
{
|
||||
return artifactVersionToString(restriction.getLowerBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (restriction.isLowerBoundInclusive() && restriction.isUpperBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.inclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else if (restriction.isLowerBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.upperexclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else if (restriction.isUpperBoundInclusive())
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.lowerexclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.bounded.exclusive", restriction.getLowerBound(), restriction.getUpperBound());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( restriction.getLowerBound() != null )
|
||||
{
|
||||
if ( restriction.isLowerBoundInclusive() )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.lower.inclusive", restriction.getLowerBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.lower.exclusive", restriction.getLowerBound());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( restriction.isUpperBoundInclusive() )
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.upper.inclusive", restriction.getUpperBound());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ForgeI18n.parseMessage("fml.messages.version.restriction.upper.exclusive", restriction.getUpperBound());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,9 @@ import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -62,6 +60,7 @@ public class ModSorter
|
|||
ms.sort();
|
||||
} catch (EarlyLoadingException ele) {
|
||||
earlyLoadingException = ele;
|
||||
ms.sortedList = Collections.emptyList();
|
||||
}
|
||||
return LoadingModList.of(ms.modFiles, ms.sortedList, earlyLoadingException);
|
||||
}
|
||||
|
@ -70,7 +69,8 @@ public class ModSorter
|
|||
{
|
||||
final TopologicalSort.DirectedGraph<Supplier<ModFileInfo>> topoGraph = new TopologicalSort.DirectedGraph<>();
|
||||
modFiles.stream().map(ModFile::getModFileInfo).map(ModFileInfo.class::cast).forEach(mi -> topoGraph.addNode(() -> mi));
|
||||
modFiles.stream().map(ModFile::getModInfos).flatMap(Collection::stream).map(IModInfo::getDependencies).flatMap(Collection::stream).
|
||||
modFiles.stream().map(ModFile::getModInfos).flatMap(Collection::stream).
|
||||
map(IModInfo::getDependencies).flatMap(Collection::stream).
|
||||
forEach(dep -> addDependency(topoGraph, dep));
|
||||
final List<Supplier<ModFileInfo>> sorted;
|
||||
try
|
||||
|
@ -81,7 +81,7 @@ public class ModSorter
|
|||
{
|
||||
TopologicalSort.TopoSortException.TopoSortExceptionData<Supplier<ModInfo>> data = e.getData();
|
||||
LOGGER.error(LOADING, ()-> data);
|
||||
throw new EarlyLoadingException("Sorting error", "fml.modloading.sortingerror", e, e.getData());
|
||||
throw new EarlyLoadingException("Sorting error", e, data.toExceptionData(mi-> mi.get().getModId()));
|
||||
}
|
||||
this.sortedList = sorted.stream().map(Supplier::get).map(ModFileInfo::getMods).
|
||||
flatMap(Collection::stream).map(ModInfo.class::cast).collect(Collectors.toList());
|
||||
|
@ -111,7 +111,10 @@ public class ModSorter
|
|||
final List<Map.Entry<String, List<ModInfo>>> dupedMods = modIds.entrySet().stream().filter(e -> e.getValue().size() > 1).collect(Collectors.toList());
|
||||
|
||||
if (!dupedMods.isEmpty()) {
|
||||
throw new EarlyLoadingException("Duplicate mods found", "fml.modloading.dupesfound", null, dupedMods);
|
||||
final List<EarlyLoadingException.ExceptionData> duplicateModErrors = dupedMods.stream().
|
||||
map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedmod", dm.getValue().get(0))).
|
||||
collect(Collectors.toList());
|
||||
throw new EarlyLoadingException("Duplicate mods found", null, duplicateModErrors);
|
||||
}
|
||||
|
||||
modIdNameLookup = modIds.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0)));
|
||||
|
@ -131,7 +134,12 @@ public class ModSorter
|
|||
LOGGER.debug(LOADING, "Found {} mandatory mod requirements missing", missingVersions.size());
|
||||
|
||||
if (!missingVersions.isEmpty()) {
|
||||
throw new EarlyLoadingException("Missing mods", "fml.modloading.missingmods", null, missingVersions);
|
||||
final List<EarlyLoadingException.ExceptionData> exceptionData = missingVersions.stream().map(mv ->
|
||||
new EarlyLoadingException.ExceptionData("fml.modloading.missingdependency", mv.getModId(),
|
||||
mv.getOwner().getModId(), mv.getVersionRange(),
|
||||
modVersions.containsKey(mv.getModId()) ? modVersions.get(mv.getModId()) : "NONE" )).
|
||||
collect(Collectors.toList());
|
||||
throw new EarlyLoadingException("Missing mods", null, exceptionData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"fml.modloading.failedtoloadmod":"{0,modinfo,name} ({0,modinfo,id}) has failed to load correctly\n\u00a77{2,exc,msg}",
|
||||
"fml.modloading.errorduringevent":"{0,modinfo,name} ({0,modinfo,id}) encountered an error during the {1,lower} event phase\n\u00a77{2,exc,msg}",
|
||||
"fml.modloading.failedtoloadforge": "Failed to load forge",
|
||||
"fml.modloading.missingdependency": "Mod {4} has missing dependency {3}\n\u00a77Want {5,vr}, have {6}",
|
||||
|
||||
"fml.messages.version.restriction.any":"any",
|
||||
"fml.messages.version.restriction.lower.inclusive":"{0} or above",
|
||||
|
|
Loading…
Reference in New Issue