diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModIdentifier.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModIdentifier.java new file mode 100644 index 000000000..f338d5612 --- /dev/null +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModIdentifier.java @@ -0,0 +1,80 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.loading.moddiscovery; + +import cpw.mods.modlauncher.api.LamdbaExceptionUtils.Supplier_WithExceptions; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.BiPredicate; +import java.util.zip.ZipFile; + +import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.*; + +public enum InvalidModIdentifier { + + OLDFORGE(filePresent("mcmod.info")), + FABRIC(filePresent("fabric.mod.json")), + LITELOADER(filePresent("litemod.json")), + OPTIFINE(filePresent("optifine/Installer.class")), + INVALIDZIP((f,zf) -> !zf.isPresent()); + + private BiPredicate> ident; + + InvalidModIdentifier(BiPredicate> identifier) + { + this.ident = identifier; + } + + private String getReason() + { + return "fml.modloading.brokenfile." + this.name().toLowerCase(); + } + + public static Optional identifyJarProblem(Path path) + { + Optional zfo = optionalFromException(() -> new ZipFile(path.toFile())); + Optional result = Arrays.stream(values()). + filter(i -> i.ident.test(path, zfo)). + map(InvalidModIdentifier::getReason). + findAny(); + zfo.ifPresent(rethrowConsumer(ZipFile::close)); + return result; + } + + private static BiPredicate> filePresent(String filename) + { + return (f, zfo) -> zfo.map(zf -> zf.getEntry(filename) != null).orElse(false); + } + + private static Optional optionalFromException(Supplier_WithExceptions supp) + { + try + { + return Optional.of(supp.get()); + } + catch (Exception e) + { + return Optional.empty(); + } + } + +} diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index b773d5b81..88a71452a 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -35,6 +35,7 @@ import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.LoadingModList; +import net.minecraftforge.fml.loading.moddiscovery.InvalidModIdentifier; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.fml.network.FMLNetworkConstants; @@ -113,7 +114,8 @@ public class ModLoader this.loadingExceptions = FMLLoader.getLoadingModList(). getErrors().stream().flatMap(ModLoadingException::fromEarlyException).collect(Collectors.toList()); this.loadingWarnings = FMLLoader.getLoadingModList(). - getBrokenFiles().stream().map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, "fml.modloading.brokenfile", file.getFileName())).collect(Collectors.toList()); + getBrokenFiles().stream().map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, + InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName())).collect(Collectors.toList()); LOGGER.info(CORE, "Loading Network data for FML net version: {}", FMLNetworkConstants.NETVERSION); } diff --git a/src/main/resources/assets/forge/lang/en_us.json b/src/main/resources/assets/forge/lang/en_us.json index 6ff40b0dc..aa3f85212 100644 --- a/src/main/resources/assets/forge/lang/en_us.json +++ b/src/main/resources/assets/forge/lang/en_us.json @@ -49,6 +49,11 @@ "fml.modloading.cycle": "Detected a mod dependency cycle: {0}", "fml.modloading.failedtoprocesswork":"{0,modinfo,name} ({0,modinfo,id}) encountered an error processing deferred work\n\u00a77{2,exc,msg}", "fml.modloading.brokenfile": "File {2} is not a valid mod file", + "fml.modloading.brokenfile.oldforge": "File {2} is for an older version of Forge and cannot be loaded", + "fml.modloading.brokenfile.liteloader": "File {2} is a LiteLoader mod and cannot be loaded", + "fml.modloading.brokenfile.fabric": "File {2} is a Fabric mod and cannot be loaded", + "fml.modloading.brokenfile.optifine": "File {2} is OptiFine, which is unsupported", + "fml.modloading.brokenfile.invalidzip": "File {2} is not a jar file", "fml.modloading.brokenresources": "File {2} failed to load a valid ResourcePackInfo", "fml.messages.artifactversion.ornotinstalled":"{0,ornull,fml.messages.artifactversion.notinstalled}",