Skip to content

Commit

Permalink
Make things in ML visible so that it can be used by FML in a library-…
Browse files Browse the repository at this point in the history
…like fashion.
  • Loading branch information
shartte committed Jul 1, 2024
1 parent 0f24dec commit d66297b
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 94 deletions.
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
4 changes: 2 additions & 2 deletions src/main/java/cpw/mods/modlauncher/ArgumentHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public class ArgumentHandler {
private OptionSpec<String> launchTarget;
private OptionSpec<String> uuidOption;

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

DiscoveryData setArgs(String[] args) {
public DiscoveryData setArgs(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("."));
Expand Down
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
45 changes: 29 additions & 16 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 @@ -44,20 +43,40 @@ public class Launcher {
private final ModuleLayerHandler moduleLayerHandler;
private TransformingClassLoader classLoader;

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,
ArgumentHandler argumentHandler,
LaunchServiceHandler launchService,
LaunchPluginHandler launchPlugins,
ModuleLayerHandler moduleLayerHandler) {
this.blackboard = new TypesafeMap();
this.transformationServicesHandler = transformationServicesHandler;
this.environment = environment;
this.transformStore = transformStore;
this.argumentHandler = argumentHandler;
this.launchService = launchService;
this.launchPlugins = launchPlugins;
this.moduleLayerHandler = moduleLayerHandler;
}

public static void main(String... args) {
Expand All @@ -71,7 +90,9 @@ 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() {
Expand Down Expand Up @@ -107,14 +128,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
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,28 @@

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

class TransformationServicesHandler {
public class TransformationServicesHandler {
private static final Logger LOGGER = LogManager.getLogger();
private Map<String, TransformationServiceDecorator> serviceLookup;
private final TransformStore transformStore;
private final ModuleLayerHandler layerHandler;

TransformationServicesHandler(TransformStore transformStore, ModuleLayerHandler layerHandler) {
public TransformationServicesHandler(TransformStore transformStore, ModuleLayerHandler layerHandler) {
this.transformStore = transformStore;
this.layerHandler = layerHandler;
}

List<ITransformationService.Resource> initializeTransformationServices(ArgumentHandler argumentHandler, Environment environment) {
public List<ITransformationService.Resource> initializeTransformationServices(ArgumentHandler argumentHandler, Environment environment) {
loadTransformationServices(environment);
validateTransformationServices();
processArguments(argumentHandler, environment);
initialiseTransformationServices(environment);
return runScanningTransformationServices(environment);
}

TransformingClassLoader buildTransformingClassLoader(final LaunchPluginHandler pluginHandler, final Environment environment, final ModuleLayerHandler layerHandler) {
public TransformingClassLoader buildTransformingClassLoader(final LaunchPluginHandler pluginHandler,
final Environment environment,
final ModuleLayerHandler layerHandler) {
final var layerInfo = layerHandler.buildLayer(IModuleLayerManager.Layer.GAME, (cf, parents)->new TransformingClassLoader(transformStore, pluginHandler, environment, cf, parents));
layerHandler.updateLayer(IModuleLayerManager.Layer.PLUGIN, li->li.cl().setFallbackClassLoader(layerInfo.cl()));
return (TransformingClassLoader) layerInfo.cl();
Expand All @@ -74,7 +76,7 @@ private void offerArgumentResultsToServices(OptionSet optionSet, BiFunction<Stri
.forEach(service -> service.argumentValues(resultHandler.apply(service.name(), optionSet)));
}

void initialiseServiceTransformers() {
public void initialiseServiceTransformers() {
LOGGER.debug(MODLAUNCHER,"Transformation services loading transformers");

serviceLookup.values().forEach(s -> s.gatherTransformers(transformStore));
Expand Down Expand Up @@ -110,7 +112,7 @@ private void loadTransformationServices(Environment environment) {
serviceLookup.values().forEach(s -> s.onLoad(environment, serviceLookup.keySet()));
}

void discoverServices(final ArgumentHandler.DiscoveryData discoveryData) {
public void discoverServices(final ArgumentHandler.DiscoveryData discoveryData) {
LOGGER.debug(MODLAUNCHER, "Discovering transformation services");
var bootLayer = layerHandler.getLayer(IModuleLayerManager.Layer.BOOT).orElseThrow();
var earlyDiscoveryServices = ServiceLoaderUtils.streamServiceLoader(()->ServiceLoader.load(bootLayer, ITransformerDiscoveryService.class), sce -> LOGGER.fatal(MODLAUNCHER, "Encountered serious error loading transformation discoverer, expect problems", sce))
Expand Down
Loading

0 comments on commit d66297b

Please sign in to comment.