Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make things in ML visible so that it can be used by FML in a library-like fashion #128

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id 'java-library'
id 'eclipse'
id 'com.github.ben-manes.versions' version '0.48.0'
id 'net.neoforged.gradleutils' version '3.0.0-alpha.4'
id 'net.neoforged.gradleutils' version '3.0.0'
id 'org.gradlex.extra-java-module-info' version '1.4.2'
id 'maven-publish'
}
Expand Down
3 changes: 3 additions & 0 deletions gradle/daemon-jvm.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

#This file is generated by updateDaemonJvm
toolchainVersion=21
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.6.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
}

rootProject.name = "modlauncher"
12 changes: 2 additions & 10 deletions src/main/java/cpw/mods/modlauncher/ArgumentHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import java.util.function.*;

public class ArgumentHandler {
private String[] args;
private final String[] args;
private OptionSet optionSet;
private OptionSpec<String> profileOption;
private OptionSpec<Path> gameDirOption;
Expand All @@ -37,16 +37,8 @@ public class ArgumentHandler {
private OptionSpec<String> launchTarget;
private OptionSpec<String> uuidOption;

record DiscoveryData(Path gameDir, String launchTarget, String[] arguments) {}

DiscoveryData setArgs(String[] args) {
public ArgumentHandler(String[] args) {
this.args = args;
final OptionParser parser = new OptionParser();
final var gameDir = parser.accepts("gameDir", "Alternative game directory").withRequiredArg().withValuesConvertedBy(new PathConverter(PathProperties.DIRECTORY_EXISTING)).defaultsTo(Path.of("."));
final var launchTarget = parser.accepts("launchTarget", "LauncherService target to launch").withRequiredArg();
parser.allowsUnrecognizedOptions();
final OptionSet optionSet = parser.parse(args);
return new DiscoveryData(optionSet.valueOf(gameDir), optionSet.valueOf(launchTarget), args);
}

void processArguments(Environment env, Consumer<OptionParser> parserConsumer, BiConsumer<OptionSet, BiFunction<String, OptionSet, ITransformationService.OptionResult>> resultConsumer) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/cpw/mods/modlauncher/DiscoveryData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cpw.mods.modlauncher;

import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.util.PathConverter;
import joptsimple.util.PathProperties;

import java.nio.file.Path;

public record DiscoveryData(Path gameDir, String launchTarget, String[] arguments) {
public static DiscoveryData create(String[] programArgs) {
final OptionParser parser = new OptionParser();
final var gameDir = parser.accepts("gameDir", "Alternative game directory").withRequiredArg().withValuesConvertedBy(new PathConverter(PathProperties.DIRECTORY_EXISTING)).defaultsTo(Path.of("."));
final var launchTarget = parser.accepts("launchTarget", "LauncherService target to launch").withRequiredArg();
parser.allowsUnrecognizedOptions();
final OptionSet optionSet = parser.parse(programArgs);
return new DiscoveryData(optionSet.valueOf(gameDir), optionSet.valueOf(launchTarget), programArgs);
}
}
21 changes: 13 additions & 8 deletions src/main/java/cpw/mods/modlauncher/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@
* Environment implementation class
*/
public final class Environment implements IEnvironment {
private final TypesafeMap environment;
private final Launcher launcher;
private final TypesafeMap environment = new TypesafeMap(IEnvironment.class);
private final Function<String, Optional<ILaunchPluginService>> launchPlugins;
private final Function<String, Optional<ILaunchHandlerService>> launchService;
private final IModuleLayerManager moduleLayerHandler;

Environment(Launcher launcher) {
environment = new TypesafeMap(IEnvironment.class);
this.launcher = launcher;
public Environment(Function<String, Optional<ILaunchPluginService>> launchPlugins,
Function<String, Optional<ILaunchHandlerService>> launchService,
IModuleLayerManager moduleLayerHandler) {
this.launchPlugins = launchPlugins;
this.launchService = launchService;
this.moduleLayerHandler = moduleLayerHandler;
}

@Override
Expand All @@ -43,17 +48,17 @@ public final <T> Optional<T> getProperty(TypesafeMap.Key<T> key) {

@Override
public Optional<ILaunchPluginService> findLaunchPlugin(final String name) {
return launcher.findLaunchPlugin(name);
return launchPlugins.apply(name);
}

@Override
public Optional<ILaunchHandlerService> findLaunchHandler(final String name) {
return launcher.findLaunchHandler(name);
return launchService.apply(name);
}

@Override
public Optional<IModuleLayerManager> findModuleLayerManager() {
return launcher.findLayerManager();
return Optional.of(this.moduleLayerHandler);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public EnumMap<ILaunchPluginService.Phase, List<ILaunchPluginService>> computeLa
return phaseObjectEnumMap;
}

void offerScanResultsToPlugins(List<SecureJar> scanResults) {
public void offerScanResultsToPlugins(List<SecureJar> scanResults) {
plugins.forEach((n,p)->p.addResources(scanResults));
}

Expand Down
12 changes: 8 additions & 4 deletions src/main/java/cpw/mods/modlauncher/LaunchServiceHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@
/**
* Identifies the launch target and dispatches to it
*/
class LaunchServiceHandler {
public class LaunchServiceHandler {
private static final Logger LOGGER = LogManager.getLogger();
private final Map<String, LaunchServiceHandlerDecorator> launchHandlerLookup;

public LaunchServiceHandler(final ModuleLayerHandler layerHandler) {
this.launchHandlerLookup = ServiceLoaderUtils.streamServiceLoader(()->ServiceLoader.load(layerHandler.getLayer(IModuleLayerManager.Layer.BOOT).orElseThrow(), ILaunchHandlerService.class), sce -> LOGGER.fatal("Encountered serious error loading transformation service, expect problems", sce))
this(ServiceLoaderUtils.streamServiceLoader(()->ServiceLoader.load(layerHandler.getLayer(IModuleLayerManager.Layer.BOOT).orElseThrow(), ILaunchHandlerService.class), sce -> LOGGER.fatal("Encountered serious error loading transformation service, expect problems", sce)));
}

public LaunchServiceHandler(Stream<ILaunchHandlerService> launchHandlers) {
this.launchHandlerLookup = launchHandlers
.collect(Collectors.toMap(ILaunchHandlerService::name, LaunchServiceHandlerDecorator::new));
LOGGER.debug(MODLAUNCHER,"Found launch services [{}]", () -> String.join(",",launchHandlerLookup.keySet()));
}
Expand All @@ -45,7 +49,7 @@ public Optional<ILaunchHandlerService> findLaunchHandler(final String name) {
return Optional.ofNullable(launchHandlerLookup.getOrDefault(name, null)).map(LaunchServiceHandlerDecorator::service);
}

private void launch(String target, String[] arguments, ModuleLayer gameLayer, TransformingClassLoader classLoader, final LaunchPluginHandler launchPluginHandler) {
public void launch(String target, String[] arguments, ModuleLayer gameLayer, TransformingClassLoader classLoader, final LaunchPluginHandler launchPluginHandler) {
final LaunchServiceHandlerDecorator launchServiceHandlerDecorator = launchHandlerLookup.get(target);
final NamedPath[] paths = launchServiceHandlerDecorator.service().getPaths();
launchPluginHandler.announceLaunch(classLoader, paths);
Expand All @@ -71,7 +75,7 @@ public void launch(ArgumentHandler argumentHandler, ModuleLayer gameLayer, Trans
launch(launchTarget, args, gameLayer, classLoader, launchPluginHandler);
}

void validateLaunchTarget(final ArgumentHandler argumentHandler) {
public void validateLaunchTarget(final ArgumentHandler argumentHandler) {
if (!launchHandlerLookup.containsKey(argumentHandler.getLaunchTarget())) {
LOGGER.error(MODLAUNCHER, "Cannot find launch target {}, unable to launch",
argumentHandler.getLaunchTarget());
Expand Down
50 changes: 30 additions & 20 deletions src/main/java/cpw/mods/modlauncher/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.modlauncher.api.*;
import org.apache.logging.log4j.LogManager;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;

import java.util.*;
import java.util.stream.Collectors;
Expand All @@ -38,26 +37,43 @@ public class Launcher {
private final TransformationServicesHandler transformationServicesHandler;
private final Environment environment;
private final TransformStore transformStore;
private final ArgumentHandler argumentHandler;
private final LaunchServiceHandler launchService;
private final LaunchPluginHandler launchPlugins;
private final ModuleLayerHandler moduleLayerHandler;
private TransformingClassLoader classLoader;
private ArgumentHandler argumentHandler;

private Launcher() {
INSTANCE = this;
public Launcher() {
LogManager.getLogger().info(MODLAUNCHER,"ModLauncher {} starting: java version {} by {}; OS {} arch {} version {}", ()->IEnvironment.class.getPackage().getImplementationVersion(), () -> System.getProperty("java.version"), ()->System.getProperty("java.vendor"), ()->System.getProperty("os.name"), ()->System.getProperty("os.arch"), ()->System.getProperty("os.version"));
this.moduleLayerHandler = new ModuleLayerHandler();
this.launchService = new LaunchServiceHandler(this.moduleLayerHandler);
this.blackboard = new TypesafeMap();
this.environment = new Environment(this);
environment.computePropertyIfAbsent(IEnvironment.Keys.MLSPEC_VERSION.get(), s->IEnvironment.class.getPackage().getSpecificationVersion());
environment.computePropertyIfAbsent(IEnvironment.Keys.MLIMPL_VERSION.get(), s->IEnvironment.class.getPackage().getImplementationVersion());
environment.computePropertyIfAbsent(IEnvironment.Keys.MODLIST.get(), s->new ArrayList<>());
this.transformStore = new TransformStore();
this.transformationServicesHandler = new TransformationServicesHandler(this.transformStore, this.moduleLayerHandler);
this.argumentHandler = new ArgumentHandler();
this.launchPlugins = new LaunchPluginHandler(this.moduleLayerHandler);
this.environment = new Environment(
launchPlugins::get,
launchService::findLaunchHandler,
moduleLayerHandler
);
environment.computePropertyIfAbsent(IEnvironment.Keys.MLSPEC_VERSION.get(), s->IEnvironment.class.getPackage().getSpecificationVersion());
environment.computePropertyIfAbsent(IEnvironment.Keys.MLIMPL_VERSION.get(), s->IEnvironment.class.getPackage().getImplementationVersion());
environment.computePropertyIfAbsent(IEnvironment.Keys.MODLIST.get(), s->new ArrayList<>());
}

public Launcher(TransformationServicesHandler transformationServicesHandler,
Environment environment,
TransformStore transformStore,
LaunchServiceHandler launchService,
LaunchPluginHandler launchPlugins,
ModuleLayerHandler moduleLayerHandler) {
this.blackboard = new TypesafeMap();
this.transformationServicesHandler = transformationServicesHandler;
this.environment = environment;
this.transformStore = transformStore;
this.launchService = launchService;
this.launchPlugins = launchPlugins;
this.moduleLayerHandler = moduleLayerHandler;
}

public static void main(String... args) {
Expand All @@ -71,16 +87,18 @@ public static void main(String... args) {
}
LogManager.getLogger().info(MODLAUNCHER,"ModLauncher running: args {}", () -> LaunchServiceHandler.hideAccessToken(args));
LogManager.getLogger().info(MODLAUNCHER, "JVM identified as {} {} {}", props.getProperty("java.vm.vendor"), props.getProperty("java.vm.name"), props.getProperty("java.vm.version"));
new Launcher().run(args);
var launcher = new Launcher();
INSTANCE = launcher;
launcher.run(args);
}

public final TypesafeMap blackboard() {
return blackboard;
}

private void run(String... args) {
final ArgumentHandler.DiscoveryData discoveryData = this.argumentHandler.setArgs(args);
this.transformationServicesHandler.discoverServices(discoveryData);
this.argumentHandler = new ArgumentHandler(args);
this.transformationServicesHandler.discoverServices(DiscoveryData.create(args));
final var scanResults = this.transformationServicesHandler.initializeTransformationServices(this.argumentHandler, this.environment)
.stream().collect(Collectors.groupingBy(ITransformationService.Resource::target));
scanResults.getOrDefault(IModuleLayerManager.Layer.PLUGIN, List.of())
Expand All @@ -107,14 +125,6 @@ public Environment environment() {
return this.environment;
}

Optional<ILaunchPluginService> findLaunchPlugin(final String name) {
return launchPlugins.get(name);
}

Optional<ILaunchHandlerService> findLaunchHandler(final String name) {
return launchService.findLaunchHandler(name);
}

public Optional<IModuleLayerManager> findLayerManager() {
return Optional.ofNullable(this.moduleLayerHandler);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/cpw/mods/modlauncher/ModuleLayerHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ SecureJar build() {
private final EnumMap<Layer, List<PathOrJar>> layers = new EnumMap<>(Layer.class);
private final EnumMap<Layer, LayerInfo> completedLayers = new EnumMap<>(Layer.class);

ModuleLayerHandler() {
public ModuleLayerHandler() {
ClassLoader classLoader = getClass().getClassLoader();
// Create a new ModuleClassLoader from the boot module layer if it doesn't exist already.
// This allows us to launch without BootstrapLauncher.
Expand All @@ -57,7 +57,7 @@ SecureJar build() {
completedLayers.put(Layer.BOOT, new LayerInfo(getClass().getModule().getLayer(), cl));
}

void addToLayer(final Layer layer, final SecureJar jar) {
public void addToLayer(final Layer layer, final SecureJar jar) {
if (completedLayers.containsKey(layer)) throw new IllegalStateException("Layer already populated");
layers.computeIfAbsent(layer, l->new ArrayList<>()).add(PathOrJar.from(jar));
}
Expand Down
30 changes: 25 additions & 5 deletions src/main/java/cpw/mods/modlauncher/TransformStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.objectweb.asm.tree.*;

import java.util.*;
import java.util.stream.Collectors;

import static cpw.mods.modlauncher.LogMarkers.*;

Expand All @@ -41,30 +42,49 @@ public TransformStore() {
transformers.put(type, new TransformList<>(type.getNodeType()));
}

List<ITransformer<FieldNode>> getTransformersFor(String className, FieldNode field) {
public List<ITransformer<FieldNode>> getTransformersFor(String className, FieldNode field) {
TransformTargetLabel tl = new TransformTargetLabel(className, field.name);
TransformList<FieldNode> transformerlist = TargetType.FIELD.get(this.transformers);
return transformerlist.getTransformersForLabel(tl);
}

List<ITransformer<MethodNode>> getTransformersFor(String className, MethodNode method) {
public List<ITransformer<MethodNode>> getTransformersFor(String className, MethodNode method) {
TransformTargetLabel tl = new TransformTargetLabel(className, method.name, method.desc);
TransformList<MethodNode> transformerlist = TargetType.METHOD.get(this.transformers);
return transformerlist.getTransformersForLabel(tl);
}

List<ITransformer<ClassNode>> getTransformersFor(String className, TargetType<ClassNode> classType) {
public List<ITransformer<ClassNode>> getTransformersFor(String className, TargetType<ClassNode> classType) {
TransformTargetLabel tl = new TransformTargetLabel(className, classType);
TransformList<ClassNode> transformerlist = classType.get(this.transformers);
return transformerlist.getTransformersForLabel(tl);
}

public void addTransformer(ITransformer<?> xform, ITransformationService owner) {
final TargetType<?> targetType = xform.getTargetType();
Objects.requireNonNull(targetType, "Transformer type must not be null");
final Set<? extends ITransformer.Target<?>> targets = xform.targets();
if (!targets.isEmpty()) {
final Map<TargetType<?>, List<TransformTargetLabel>> targetTypeListMap = targets.stream()
.map(TransformTargetLabel::new)
.collect(Collectors.groupingBy(TransformTargetLabel::getTargetType));
if (targetTypeListMap.keySet().size() > 1 || !targetTypeListMap.containsKey(targetType)) {
LOGGER.error("Invalid target {} for transformer {}", targetType, xform);
throw new IllegalArgumentException("The transformer contains invalid targets");
}
targetTypeListMap.values()
.stream()
.flatMap(Collection::stream)
.forEach(target -> addTransformer(target, xform, owner));
}
}

@SuppressWarnings("unchecked")
<T> void addTransformer(TransformTargetLabel targetLabel, ITransformer<T> transformer, ITransformationService service) {
public <T> void addTransformer(TransformTargetLabel targetLabel, ITransformer<T> transformer, ITransformationService owner) {
LOGGER.debug(MODLAUNCHER,"Adding transformer {} to {}", () -> transformer, () -> targetLabel);
classNeedsTransforming.add(targetLabel.getClassName().getInternalName());
final TransformList<T> transformList = (TransformList<T>) this.transformers.get(targetLabel.getTargetType());
transformList.addTransformer(targetLabel, new TransformerHolder<>(transformer, service));
transformList.addTransformer(targetLabel, new TransformerHolder<>(transformer, owner));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public final Type getElementDescriptor() {
return this.elementDescriptor;
}

final TargetType<?> getTargetType() {
public TargetType<?> getTargetType() {
return this.labelType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.jetbrains.annotations.VisibleForTesting;

import java.util.*;
import java.util.stream.*;

import static cpw.mods.modlauncher.LogMarkers.*;

Expand Down Expand Up @@ -67,24 +66,9 @@ public void gatherTransformers(TransformStore transformStore) {
LOGGER.debug(MODLAUNCHER,"Initializing transformers for transformation service {}", this.service::name);
final List<? extends ITransformer<?>> transformers = this.service.transformers();
Objects.requireNonNull(transformers, "The transformers list should not be null");
transformers.forEach(xform -> {
final TargetType<?> targetType = xform.getTargetType();
Objects.requireNonNull(targetType, "Transformer type must not be null");
final Set<? extends ITransformer.Target<?>> targets = xform.targets();
if (!targets.isEmpty()) {
final Map<TargetType<?>, List<TransformTargetLabel>> targetTypeListMap = targets.stream()
.map(TransformTargetLabel::new)
.collect(Collectors.groupingBy(TransformTargetLabel::getTargetType));
if (targetTypeListMap.keySet().size() > 1 || !targetTypeListMap.containsKey(targetType)) {
LOGGER.error(MODLAUNCHER,"Invalid target {} for transformer {}", targetType, xform);
throw new IllegalArgumentException("The transformer contains invalid targets");
}
targetTypeListMap.values()
.stream()
.flatMap(Collection::stream)
.forEach(target -> transformStore.addTransformer(target, xform, service));
}
});
for (ITransformer<?> xform : transformers) {
transformStore.addTransformer(xform, service);
}
LOGGER.debug(MODLAUNCHER,"Initialized transformers for transformation service {}", this.service::name);
}

Expand Down
Loading
Loading