Early signs of modloading
This commit is contained in:
parent
66b6150027
commit
c38d2e48cd
13 changed files with 288 additions and 25 deletions
|
@ -25,9 +25,10 @@ import org.apache.logging.log4j.core.config.Configurator;
|
||||||
|
|
||||||
public class LaunchTesting
|
public class LaunchTesting
|
||||||
{
|
{
|
||||||
public static void main(String... args)
|
public static void main(String... args) throws InterruptedException
|
||||||
{
|
{
|
||||||
Configurator.setRootLevel(Level.DEBUG);
|
Configurator.setRootLevel(Level.DEBUG);
|
||||||
Launcher.main("--launchTarget", "fml","--gameDir", "projects/run");
|
Launcher.main("--launchTarget", "fml","--gameDir", "projects/run");
|
||||||
|
Thread.sleep(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2018.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.ModContainer;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ScanResult;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.SCAN;
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class FMLJavaModLanguageProvider implements IModLanguageProvider
|
||||||
|
{
|
||||||
|
private static class FMLModTarget implements IModLanguageProvider.IModLanguageLoader {
|
||||||
|
private final String className;
|
||||||
|
private final String modId;
|
||||||
|
|
||||||
|
private FMLModTarget(String className, String modId)
|
||||||
|
{
|
||||||
|
this.className = className;
|
||||||
|
this.modId = modId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModId()
|
||||||
|
{
|
||||||
|
return modId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModContainer loadMod(ModFile file, ClassLoader modClassLoader)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Type MODANNOTATION = Type.getType("Lnet/minecraftforge/fml/common/Mod;");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name()
|
||||||
|
{
|
||||||
|
return "javafml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Consumer<ScanResult> getFileVisitor() {
|
||||||
|
return scanResult -> {
|
||||||
|
final Map<String, FMLModTarget> modTargetMap = scanResult.getAnnotations().stream()
|
||||||
|
.filter(ad -> ad.getAnnotationType().equals(MODANNOTATION))
|
||||||
|
.peek(ad -> fmlLog.debug(SCAN, "Found @Mod class {} with id {}", ad.getClassType().getClassName(), ad.getAnnotationData().get("modid")))
|
||||||
|
.map(ad -> new FMLModTarget(ad.getClassType().getClassName(), (String)ad.getAnnotationData().get("modid")))
|
||||||
|
.collect(Collectors.toMap(FMLModTarget::getModId, Function.identity()));
|
||||||
|
modTargetMap.forEach((key, value) -> scanResult.getFile().claimLanguage(key, value));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ModContainer> buildModContainers(List<ModInfo> modFiles, ClassLoader modClassLoader)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,25 +28,20 @@ import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
|
||||||
import net.minecraftforge.forgespi.ICoreModProvider;
|
import net.minecraftforge.forgespi.ICoreModProvider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static net.minecraftforge.fml.Logging.CORE;
|
import static net.minecraftforge.fml.Logging.CORE;
|
||||||
import static net.minecraftforge.fml.Logging.LOADING;
|
|
||||||
import static net.minecraftforge.fml.Logging.SCAN;
|
import static net.minecraftforge.fml.Logging.SCAN;
|
||||||
import static net.minecraftforge.fml.Logging.fmlLog;
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
public class FMLLoader
|
public class FMLLoader
|
||||||
{
|
{
|
||||||
|
|
||||||
private static ILaunchPluginService accessTransformer;
|
private static ILaunchPluginService accessTransformer;
|
||||||
private static ModDiscoverer modDiscoverer;
|
private static ModDiscoverer modDiscoverer;
|
||||||
private static ICoreModProvider coreMod;
|
private static ICoreModProvider coreModProvider;
|
||||||
|
private static LanguageLoadingProvider languageLoadingProvider;
|
||||||
|
|
||||||
static void onInitialLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
|
static void onInitialLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
|
||||||
{
|
{
|
||||||
|
@ -79,9 +74,11 @@ public class FMLLoader
|
||||||
throw new IncompatibleEnvironmentException("Multiple coremod libraries found");
|
throw new IncompatibleEnvironmentException("Multiple coremod libraries found");
|
||||||
}
|
}
|
||||||
|
|
||||||
coreMod = coreModProviders.get(0);
|
coreModProvider = coreModProviders.get(0);
|
||||||
final Package coremodPackage = coreMod.getClass().getPackage();
|
final Package coremodPackage = coreModProvider.getClass().getPackage();
|
||||||
fmlLog.debug(CORE,"FML found CoreMod version : {}", coremodPackage.getImplementationVersion());
|
fmlLog.debug(CORE,"FML found CoreMod version : {}", coremodPackage.getImplementationVersion());
|
||||||
|
|
||||||
|
languageLoadingProvider = new LanguageLoadingProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void load()
|
public static void load()
|
||||||
|
@ -90,4 +87,13 @@ public class FMLLoader
|
||||||
modDiscoverer = new ModDiscoverer();
|
modDiscoverer = new ModDiscoverer();
|
||||||
modDiscoverer.discoverMods();
|
modDiscoverer.discoverMods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ICoreModProvider getCoreModProvider() {
|
||||||
|
return coreModProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LanguageLoadingProvider getLanguageLoadingProvider()
|
||||||
|
{
|
||||||
|
return languageLoadingProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,17 @@ import cpw.mods.modlauncher.api.ITransformer;
|
||||||
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
||||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||||
import joptsimple.OptionSpecBuilder;
|
import joptsimple.OptionSpecBuilder;
|
||||||
|
import net.minecraftforge.coremod.CoreModEngine;
|
||||||
import net.minecraftforge.fml.FMLConfig;
|
import net.minecraftforge.fml.FMLConfig;
|
||||||
import net.minecraftforge.fml.common.FMLPaths;
|
import net.minecraftforge.fml.common.FMLPaths;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static net.minecraftforge.fml.Logging.CORE;
|
import static net.minecraftforge.fml.Logging.CORE;
|
||||||
import static net.minecraftforge.fml.Logging.fmlLog;
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
@ -86,7 +89,8 @@ public class FMLServiceProvider implements ITransformationService
|
||||||
@Override
|
@Override
|
||||||
public List<ITransformer> transformers()
|
public List<ITransformer> transformers()
|
||||||
{
|
{
|
||||||
return Collections.emptyList();
|
fmlLog.debug(CORE, "Loading coremod transformers");
|
||||||
|
return new ArrayList<>(FMLLoader.getCoreModProvider().getCoreModTransformers());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2018.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.ModContainer;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ScanResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loaded as a ServiceLoader, from the classpath. Extensions are loaded from
|
||||||
|
* the mods directory, with the FMLType META-INF of LANGPROVIDER.
|
||||||
|
*
|
||||||
|
* Version data is read from the manifest's implementation version.
|
||||||
|
*/
|
||||||
|
public interface IModLanguageProvider
|
||||||
|
{
|
||||||
|
String name();
|
||||||
|
|
||||||
|
Consumer<ScanResult> getFileVisitor();
|
||||||
|
|
||||||
|
interface IModLanguageLoader {
|
||||||
|
ModContainer loadMod(ModFile file, ClassLoader modClassLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ModContainer> buildModContainers(List<ModInfo> modFiles, ClassLoader modClassLoader);
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2018.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.CORE;
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class LanguageLoadingProvider
|
||||||
|
{
|
||||||
|
private final List<IModLanguageProvider> languageProviders = new ArrayList<>();
|
||||||
|
private final ServiceLoader<IModLanguageProvider> serviceLoader;
|
||||||
|
private final Map<String, IModLanguageProvider> languageProviderMap = new HashMap<>();
|
||||||
|
|
||||||
|
LanguageLoadingProvider() {
|
||||||
|
serviceLoader = ServiceLoader.load(IModLanguageProvider.class);
|
||||||
|
serviceLoader.forEach(languageProviders::add);
|
||||||
|
|
||||||
|
languageProviders.forEach(lp -> {
|
||||||
|
final Package pkg = lp.getClass().getPackage();
|
||||||
|
fmlLog.debug(CORE, "Found system classpath language provider {}, version {}", lp.name(), pkg.getImplementationVersion());
|
||||||
|
});
|
||||||
|
|
||||||
|
languageProviders.forEach(lp->languageProviderMap.put(lp.name(), lp));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAdditionalLanguages(List<ModFile> modFiles)
|
||||||
|
{
|
||||||
|
if (modFiles==null) return;
|
||||||
|
Stream<Path> langPaths = modFiles.stream().map(ModFile::getFilePath);
|
||||||
|
serviceLoader.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IModLanguageProvider getLanguage(String name)
|
||||||
|
{
|
||||||
|
return languageProviderMap.get(name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,11 +19,14 @@
|
||||||
|
|
||||||
package net.minecraftforge.fml.loading.moddiscovery;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static net.minecraftforge.fml.Logging.SCAN;
|
import static net.minecraftforge.fml.Logging.SCAN;
|
||||||
|
@ -37,7 +40,11 @@ public class BackgroundScanHandler
|
||||||
private final List<ModFile> allFiles;
|
private final List<ModFile> allFiles;
|
||||||
|
|
||||||
public BackgroundScanHandler() {
|
public BackgroundScanHandler() {
|
||||||
modContentScanner = Executors.newCachedThreadPool();
|
modContentScanner = Executors.newSingleThreadExecutor(r -> {
|
||||||
|
final Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
return thread;
|
||||||
|
});
|
||||||
scannedFiles = new ArrayList<>();
|
scannedFiles = new ArrayList<>();
|
||||||
pendingFiles = new ArrayList<>();
|
pendingFiles = new ArrayList<>();
|
||||||
allFiles = new ArrayList<>();
|
allFiles = new ArrayList<>();
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
package net.minecraftforge.fml.loading.moddiscovery;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
|
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
|
||||||
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
|
import net.minecraftforge.fml.loading.LanguageLoadingProvider;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -54,12 +56,12 @@ public class ModDiscoverer {
|
||||||
.peek(mf -> fmlLog.debug(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator()))
|
.peek(mf -> fmlLog.debug(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator()))
|
||||||
.collect(Collectors.groupingBy(ModFile::getType));
|
.collect(Collectors.groupingBy(ModFile::getType));
|
||||||
|
|
||||||
//ModLanguageProvider.loadAdditionalLanguages(modFiles.get(ModFile.Type.LANGPROVIDER));
|
FMLLoader.getLanguageLoadingProvider().addAdditionalLanguages(modFiles.get(ModFile.Type.LANGPROVIDER));
|
||||||
BackgroundScanHandler backgroundScanHandler = new BackgroundScanHandler();
|
BackgroundScanHandler backgroundScanHandler = new BackgroundScanHandler();
|
||||||
final List<ModFile> mods = modFiles.get(ModFile.Type.MOD);
|
final List<ModFile> mods = modFiles.get(ModFile.Type.MOD);
|
||||||
mods.forEach(ModFile::identifyMods);
|
mods.forEach(ModFile::identifyMods);
|
||||||
fmlLog.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
|
fmlLog.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
|
||||||
//mods.stream().map(ModFile::getCoreMods).flatMap(List::stream).forEach(ServiceProviders.getCoreModProvider()::addCoreMod);
|
mods.stream().map(ModFile::getCoreMods).flatMap(List::stream).forEach(FMLLoader.getCoreModProvider()::addCoreMod);
|
||||||
mods.forEach(backgroundScanHandler::submitForScanning);
|
mods.forEach(backgroundScanHandler::submitForScanning);
|
||||||
return backgroundScanHandler;
|
return backgroundScanHandler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,21 @@
|
||||||
|
|
||||||
package net.minecraftforge.fml.loading.moddiscovery;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.IModLanguageProvider;
|
||||||
|
|
||||||
|
import javax.swing.text.html.Option;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static net.minecraftforge.fml.Logging.LOADING;
|
import static net.minecraftforge.fml.Logging.LOADING;
|
||||||
import static net.minecraftforge.fml.Logging.SCAN;
|
import static net.minecraftforge.fml.Logging.SCAN;
|
||||||
|
@ -40,6 +47,11 @@ public class ModFile
|
||||||
DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD");
|
DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void claimLanguage(String modId, IModLanguageProvider.IModLanguageLoader loader)
|
||||||
|
{
|
||||||
|
this.modInfoMap.get(modId).setLoader(loader);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
MOD, LIBRARY, LANGPROVIDER
|
MOD, LIBRARY, LANGPROVIDER
|
||||||
}
|
}
|
||||||
|
@ -47,6 +59,7 @@ public class ModFile
|
||||||
private final Type modFileType;
|
private final Type modFileType;
|
||||||
private final Manifest manifest;
|
private final Manifest manifest;
|
||||||
private List<ModInfo> modInfos;
|
private List<ModInfo> modInfos;
|
||||||
|
private Map<String, ModInfo> modInfoMap;
|
||||||
private final IModLocator locator;
|
private final IModLocator locator;
|
||||||
private ScanResult fileScanResult;
|
private ScanResult fileScanResult;
|
||||||
private CompletableFuture<ScanResult> futureScanResult;
|
private CompletableFuture<ScanResult> futureScanResult;
|
||||||
|
@ -60,7 +73,8 @@ public class ModFile
|
||||||
manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST);
|
manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST);
|
||||||
if (manifest != DEFAULTMANIFEST) fmlLog.debug(SCAN,"Mod file {} has a manifest", file);
|
if (manifest != DEFAULTMANIFEST) fmlLog.debug(SCAN,"Mod file {} has a manifest", file);
|
||||||
else fmlLog.debug(SCAN,"Mod file {} is missing a manifest", file);
|
else fmlLog.debug(SCAN,"Mod file {} is missing a manifest", file);
|
||||||
modFileType = Type.valueOf(manifest.getMainAttributes().getValue(TYPE));
|
final Optional<String> value = Optional.ofNullable(manifest.getMainAttributes().getValue(TYPE));
|
||||||
|
modFileType = Type.valueOf(value.orElse("MOD"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
|
@ -78,6 +92,7 @@ public class ModFile
|
||||||
public void identifyMods() {
|
public void identifyMods() {
|
||||||
this.modInfos = ModFileParser.readModList(this);
|
this.modInfos = ModFileParser.readModList(this);
|
||||||
this.modInfos.forEach(mi-> fmlLog.debug(LOADING,"Found mod {} for language {}", mi.getModId(), mi.getModLoader()));
|
this.modInfos.forEach(mi-> fmlLog.debug(LOADING,"Found mod {} for language {}", mi.getModId(), mi.getModLoader()));
|
||||||
|
this.modInfoMap = this.modInfos.stream().collect(Collectors.toMap(ModInfo::getModId, Function.identity()));
|
||||||
this.coreMods = ModFileParser.getCoreMods(this);
|
this.coreMods = ModFileParser.getCoreMods(this);
|
||||||
this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath()));
|
this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
package net.minecraftforge.fml.loading.moddiscovery;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||||
|
import net.minecraftforge.fml.loading.IModLanguageProvider;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ModInfo {
|
public class ModInfo {
|
||||||
private final ModFile owningFile;
|
private final ModFile owningFile;
|
||||||
|
@ -27,11 +31,12 @@ public class ModInfo {
|
||||||
private final ArtifactVersion version;
|
private final ArtifactVersion version;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
private final String description;
|
private final String description;
|
||||||
private final java.net.URL updateJSONURL;
|
private final URL updateJSONURL;
|
||||||
private final String modLoader;
|
private final String modLoader;
|
||||||
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ModInfo.ModVersion> dependencies;
|
private final List<ModInfo.ModVersion> dependencies;
|
||||||
|
private IModLanguageProvider.IModLanguageLoader loader;
|
||||||
|
|
||||||
public ModInfo(final ModFile owningFile, final String modLoader, final String modId, final String displayName, final ArtifactVersion version, final String description, final java.net.URL updateJSONURL, final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ModInfo.ModVersion> dependencies) {
|
public ModInfo(final ModFile owningFile, final String modLoader, final String modId, final String displayName, final ArtifactVersion version, final String description, final URL updateJSONURL, final List<ModInfo.ModVersion> dependencies) {
|
||||||
this.owningFile = owningFile;
|
this.owningFile = owningFile;
|
||||||
this.modLoader = modLoader;
|
this.modLoader = modLoader;
|
||||||
this.modId = modId;
|
this.modId = modId;
|
||||||
|
@ -58,6 +63,11 @@ public class ModInfo {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLoader(IModLanguageProvider.IModLanguageLoader loader)
|
||||||
|
{
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Ordering {
|
public enum Ordering {
|
||||||
BEFORE, AFTER, NONE;
|
BEFORE, AFTER, NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,27 +22,33 @@ package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ScanResult {
|
public class ScanResult {
|
||||||
private final ModFile file;
|
private final ModFile file;
|
||||||
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.AnnotationData> annotations = new java.util.ArrayList<>();
|
private final List<ScanResult.AnnotationData> annotations = new ArrayList<>();
|
||||||
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.ClassData> classes = new java.util.ArrayList<>();
|
private final List<ScanResult.ClassData> classes = new ArrayList<>();
|
||||||
|
|
||||||
public ScanResult(final ModFile file) {
|
public ScanResult(final ModFile file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModFile getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean interestingAnnotations(final ModAnnotation annotation) {
|
public static boolean interestingAnnotations(final ModAnnotation annotation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.ClassData> getClasses() {
|
public List<ScanResult.ClassData> getClasses() {
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.AnnotationData> getAnnotations() {
|
public List<ScanResult.AnnotationData> getAnnotations() {
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,19 @@
|
||||||
|
|
||||||
package net.minecraftforge.fml.loading.moddiscovery;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
|
import net.minecraftforge.fml.loading.IModLanguageProvider;
|
||||||
|
import net.minecraftforge.fml.loading.LanguageLoadingProvider;
|
||||||
import org.objectweb.asm.ClassReader;
|
import org.objectweb.asm.ClassReader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.LOADING;
|
||||||
import static net.minecraftforge.fml.Logging.SCAN;
|
import static net.minecraftforge.fml.Logging.SCAN;
|
||||||
import static net.minecraftforge.fml.Logging.fmlLog;
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
@ -34,17 +45,20 @@ public class Scanner {
|
||||||
public ScanResult scan() {
|
public ScanResult scan() {
|
||||||
ScanResult result = new ScanResult(fileToScan);
|
ScanResult result = new ScanResult(fileToScan);
|
||||||
fileToScan.scanFile(p -> fileVisitor(p, result));
|
fileToScan.scanFile(p -> fileVisitor(p, result));
|
||||||
|
final Set<IModLanguageProvider> modLoaders = fileToScan.getModInfos().stream().map(ModInfo::getModLoader).map(FMLLoader.getLanguageLoadingProvider()::getLanguage).collect(Collectors.toSet());
|
||||||
|
modLoaders.stream().peek(ml-> fmlLog.debug(SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), ml.name()))
|
||||||
|
.map(IModLanguageProvider::getFileVisitor).forEach(c->c.accept(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fileVisitor(final java.nio.file.Path path, final ScanResult result) {
|
private void fileVisitor(final Path path, final ScanResult result) {
|
||||||
try {
|
try {
|
||||||
fmlLog.debug(SCAN,"Scanning {} path {}", fileToScan, path);
|
fmlLog.debug(SCAN,"Scanning {} path {}", fileToScan, path);
|
||||||
ModClassVisitor mcv = new ModClassVisitor();
|
ModClassVisitor mcv = new ModClassVisitor();
|
||||||
org.objectweb.asm.ClassReader cr = new ClassReader(java.nio.file.Files.newInputStream(path));
|
ClassReader cr = new ClassReader(Files.newInputStream(path));
|
||||||
cr.accept(mcv, 0);
|
cr.accept(mcv, 0);
|
||||||
mcv.buildData(result.getClasses(), result.getAnnotations());
|
mcv.buildData(result.getClasses(), result.getAnnotations());
|
||||||
} catch (java.io.IOException e) {
|
} catch (IOException e) {
|
||||||
// mark path bad
|
// mark path bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
net.minecraftforge.fml.loading.FMLJavaModLanguageProvider
|
Loading…
Reference in a new issue