Add in the ability to load modlists from a file.
This is simple: <modfile>.list is a newline separated list of maven-like coordinates for mods to load into the game. They are searched for in all known maven roots. Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
parent
1d0c67d67b
commit
7cfc5c3316
3 changed files with 118 additions and 1 deletions
|
@ -56,4 +56,15 @@ public class FileUtils
|
||||||
}
|
}
|
||||||
return dirPath;
|
return dirPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fileExtension(final Path path) {
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
int idx = fileName.lastIndexOf('.');
|
||||||
|
if (idx > -1) {
|
||||||
|
return fileName.substring(idx+1);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class MavenDirectoryLocator extends AbstractJarFileLocator {
|
public class MavenDirectoryLocator extends AbstractJarFileLocator {
|
||||||
private List<Path> modCoords;
|
private List<Path> modCoords;
|
||||||
|
@ -54,7 +55,9 @@ public class MavenDirectoryLocator extends AbstractJarFileLocator {
|
||||||
final List<String> mavenRoots = (List<String>) arguments.get("mavenRoots");
|
final List<String> mavenRoots = (List<String>) arguments.get("mavenRoots");
|
||||||
final List<Path> mavenRootPaths = mavenRoots.stream().map(n -> FMLPaths.GAMEDIR.get().resolve(n)).collect(Collectors.toList());
|
final List<Path> mavenRootPaths = mavenRoots.stream().map(n -> FMLPaths.GAMEDIR.get().resolve(n)).collect(Collectors.toList());
|
||||||
final List<String> mods = (List<String>) arguments.get("mods");
|
final List<String> mods = (List<String>) arguments.get("mods");
|
||||||
List<Path> localModCoords = mods.stream().map(MavenCoordinateResolver::get).collect(Collectors.toList());
|
final List<String> listedMods = ModListHandler.processModLists((List<String>) arguments.get("modLists"), mavenRootPaths);
|
||||||
|
|
||||||
|
List<Path> localModCoords = Stream.concat(mods.stream(),listedMods.stream()).map(MavenCoordinateResolver::get).collect(Collectors.toList());
|
||||||
// find the modCoords path in each supplied maven path, and turn it into a mod file. (skips not found files)
|
// find the modCoords path in each supplied maven path, and turn it into a mod file. (skips not found files)
|
||||||
|
|
||||||
this.modCoords = localModCoords.stream().map(mc -> mavenRootPaths.stream().map(root -> root.resolve(mc)).filter(path -> Files.exists(path)).findFirst().orElseThrow(() -> new IllegalArgumentException("Failed to locate requested mod coordinate " + mc))).collect(Collectors.toList());
|
this.modCoords = localModCoords.stream().map(mc -> mavenRootPaths.stream().map(root -> root.resolve(mc)).filter(path -> Files.exists(path)).findFirst().orElseThrow(() -> new IllegalArgumentException("Failed to locate requested mod coordinate " + mc))).collect(Collectors.toList());
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* 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 net.minecraftforge.fml.loading.FMLPaths;
|
||||||
|
import net.minecraftforge.fml.loading.FileUtils;
|
||||||
|
import net.minecraftforge.fml.loading.MavenCoordinateResolver;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
|
||||||
|
|
||||||
|
public class ModListHandler {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
/**
|
||||||
|
* Reads the modList paths specified, and searches each maven root for mods matching. Returns a list of mods
|
||||||
|
* found.
|
||||||
|
*
|
||||||
|
* @param modListPaths Paths to search for mod file lists
|
||||||
|
* @param mavenRootPaths Roots to look for mods listed
|
||||||
|
* @return list of found mod coordinates
|
||||||
|
*/
|
||||||
|
public static List<String> processModLists(final List<String> modListPaths, final List<Path> mavenRootPaths) {
|
||||||
|
final List<String> modCoordinates = modListPaths.stream().map(ModListHandler::transformPathToList).
|
||||||
|
flatMap(Collection::stream).
|
||||||
|
collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<Pair<Path,String>> localModCoords = modCoordinates.stream().map(mc->Pair.of(MavenCoordinateResolver.get(mc), mc)).collect(Collectors.toList());
|
||||||
|
final List<Pair<Path, String>> foundCoordinates = localModCoords.stream().
|
||||||
|
map(mc -> mavenRootPaths.stream().
|
||||||
|
map(root -> Pair.of(root.resolve(mc.getLeft()), mc.getRight())).
|
||||||
|
filter(path -> Files.exists(path.getLeft())).
|
||||||
|
findFirst().
|
||||||
|
orElseGet(()->{
|
||||||
|
LOGGER.warn(CORE, "Failed to find coordinate {}", mc);
|
||||||
|
return null;
|
||||||
|
})).
|
||||||
|
filter(Objects::nonNull).
|
||||||
|
collect(Collectors.toList());
|
||||||
|
|
||||||
|
final List<String> found = foundCoordinates.stream().map(Pair::getRight).collect(Collectors.toList());
|
||||||
|
LOGGER.debug(CORE, "Found mod coordinates from lists: {}", found);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> transformPathToList(final String path) {
|
||||||
|
LOGGER.debug(CORE, "Reading mod list {}", path);
|
||||||
|
Path filePath = FMLPaths.GAMEDIR.get().resolve(path);
|
||||||
|
if (!Files.exists(filePath)) {
|
||||||
|
LOGGER.warn(CORE, "Failed to find modlist file at {}", filePath);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
String extension = FileUtils.fileExtension(filePath);
|
||||||
|
if (Objects.equals("list",extension)) {
|
||||||
|
return readListFile(filePath).stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
LOGGER.warn(CORE, "Failed to read unknown file list type {} for file {}", extension, filePath);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple list file, ending in ".list" with one mod coordinate per line
|
||||||
|
* @param filePath path
|
||||||
|
* @return list
|
||||||
|
*/
|
||||||
|
private static List<String> readListFile(final Path filePath) {
|
||||||
|
try {
|
||||||
|
return Files.readAllLines(filePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.warn(CORE, "Failed to read file list {}", filePath, e);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue