diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java index 1327fd9e8..905e60930 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.loading; +import net.minecraftforge.forgespi.language.IModInfo; + import java.util.List; /** @@ -29,10 +31,17 @@ public class EarlyLoadingException extends RuntimeException { public static class ExceptionData { + private final IModInfo modInfo; private final String i18message; private final Object[] args; + public ExceptionData(final String message, Object... args) { + this(message, null, args); + } + + public ExceptionData(final String message, final IModInfo modInfo, Object... args) { this.i18message = message; + this.modInfo = modInfo; this.args = args; } @@ -43,6 +52,10 @@ public class EarlyLoadingException extends RuntimeException { public Object[] getArgs() { return args; } + + public IModInfo getModInfo() { + return modInfo; + } } private final List errorMessages; diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java index d4a083933..fc9f45e4d 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java @@ -42,6 +42,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -191,7 +192,7 @@ public class ModSorter if (!dupedMods.isEmpty()) { final List duplicateModErrors = dupedMods .stream() - .map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedmod", dm.getValue().get(0))) + .map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedmod", dm.getValue().get(0), Objects.toString(dm.getValue().get(0)))) .collect(Collectors.toList()); throw new EarlyLoadingException("Duplicate mods found", null, duplicateModErrors); } @@ -243,7 +244,7 @@ public class ModSorter if (!missingVersions.isEmpty()) { final List exceptionData = missingVersions .stream() - .map(mv -> new EarlyLoadingException.ExceptionData("fml.modloading.missingdependency", + .map(mv -> new EarlyLoadingException.ExceptionData("fml.modloading.missingdependency", mv.getOwner(), mv.getModId(), mv.getOwner().getModId(), mv.getVersionRange(), modVersions.getOrDefault(mv.getModId(), new DefaultArtifactVersion("null")))) .collect(Collectors.toList()); diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java index d993a8084..63bce5132 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java @@ -19,6 +19,7 @@ package net.minecraftforge.fml.loading.moddiscovery; +import com.google.common.base.Strings; import net.minecraftforge.fml.loading.StringUtils; import net.minecraftforge.forgespi.language.IConfigurable; import net.minecraftforge.forgespi.language.IModFileInfo; @@ -65,7 +66,7 @@ public class ModFileInfo implements IModFileInfo, IConfigurable .map(MavenVersionAdapter::createFromVersionSpec) .orElseThrow(()->new InvalidModFileException("Missing ModLoader version in file", this)); this.license = config.getConfigElement("license") - .orElseThrow(()->new InvalidModFileException("Missing License, please supply a license.", this)); + .orElse(""); this.showAsResourcePack = config.getConfigElement("showAsResourcePack").orElse(false); this.properties = config.>getConfigElement("properties").orElse(Collections.emptyMap()); this.modFile.setFileProperties(this.properties); @@ -147,4 +148,9 @@ public class ModFileInfo implements IModFileInfo, IConfigurable { return issueURL; } + + public boolean missingLicense() + { + return Strings.isNullOrEmpty(license); + } } diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 737eec22d..459a42172 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -120,6 +120,11 @@ public class ModLoader this.loadingWarnings = FMLLoader.getLoadingModList(). getBrokenFiles().stream().map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName())).collect(Collectors.toList()); + FMLLoader.getLoadingModList() + .getModFiles().stream().filter(ModFileInfo::missingLicense) //Search for files with missing licenses + .filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(thisModInfo -> this.loadingExceptions.stream().map(ModLoadingException::getModInfo).anyMatch(otherInfo -> otherInfo == thisModInfo))) //Ignore files where any other mod already encountered an error + .map(modFileInfo -> new ModLoadingException(null, ModLoadingStage.VALIDATE, "fml.modloading.missinglicense", null, modFileInfo.getFile())) + .forEach(this.loadingExceptions::add); LOGGER.debug(CORE, "Loading Network data for FML net version: {}", FMLNetworkConstants.init()); CrashReportExtender.registerCrashCallable("ModLauncher", FMLLoader::getLauncherInfo); CrashReportExtender.registerCrashCallable("ModLauncher launch target", FMLLoader::launcherHandlerName); diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingException.java b/src/main/java/net/minecraftforge/fml/ModLoadingException.java index 324967382..c4acafd99 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoadingException.java +++ b/src/main/java/net/minecraftforge/fml/ModLoadingException.java @@ -61,7 +61,7 @@ public class ModLoadingException extends RuntimeException } static Stream fromEarlyException(final EarlyLoadingException e) { - return e.getAllData().stream().map(ed->new ModLoadingException(null, ModLoadingStage.VALIDATE, ed.getI18message(), e.getCause(), ed.getArgs())); + return e.getAllData().stream().map(ed->new ModLoadingException(ed.getModInfo(), ModLoadingStage.VALIDATE, ed.getI18message(), e.getCause(), ed.getArgs())); } public String getI18NMessage() { diff --git a/src/main/resources/assets/forge/lang/en_us.json b/src/main/resources/assets/forge/lang/en_us.json index d6dde36a3..9258369c1 100644 --- a/src/main/resources/assets/forge/lang/en_us.json +++ b/src/main/resources/assets/forge/lang/en_us.json @@ -58,6 +58,7 @@ "fml.modloading.brokenfile.optifine": "File {2} is an incompatible version of OptiFine", "fml.modloading.brokenfile.invalidzip": "File {2} is not a jar file", "fml.modloading.brokenresources": "File {2} failed to load a valid ResourcePackInfo", + "fml.modloading.missinglicense": "Missing License Information in file {3}", "fml.resources.modresources": "Resources for {0} mod files", "fml.messages.artifactversion.ornotinstalled":"{0,ornull,fml.messages.artifactversion.notinstalled}",