mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-14 22:56:31 +01:00
Loading mixins from extensions
This commit is contained in:
parent
26b8ad125e
commit
c3c2b0a34c
@ -21,15 +21,14 @@ public class Bootstrap {
|
|||||||
try {
|
try {
|
||||||
ClassLoader classLoader = MinestomOverwriteClassLoader.getInstance();
|
ClassLoader classLoader = MinestomOverwriteClassLoader.getInstance();
|
||||||
startMixin(args);
|
startMixin(args);
|
||||||
MixinEnvironment.init(MixinEnvironment.Phase.INIT);
|
|
||||||
MinestomOverwriteClassLoader.getInstance().addCodeModifier(new MixinCodeModifier());
|
MinestomOverwriteClassLoader.getInstance().addCodeModifier(new MixinCodeModifier());
|
||||||
|
MixinEnvironment.init(MixinEnvironment.Phase.DEFAULT);
|
||||||
|
|
||||||
// ensure extensions are loaded when starting the server
|
// ensure extensions are loaded when starting the server
|
||||||
Class<?> serverClass = classLoader.loadClass("net.minestom.server.MinecraftServer");
|
Class<?> serverClass = classLoader.loadClass("net.minestom.server.MinecraftServer");
|
||||||
Method init = serverClass.getMethod("init");
|
Method init = serverClass.getMethod("init");
|
||||||
init.invoke(null);
|
init.invoke(null);
|
||||||
|
|
||||||
|
|
||||||
Class<?> mainClass = classLoader.loadClass(mainClassFullName);
|
Class<?> mainClass = classLoader.loadClass(mainClassFullName);
|
||||||
Method main = mainClass.getDeclaredMethod("main", String[].class);
|
Method main = mainClass.getDeclaredMethod("main", String[].class);
|
||||||
main.invoke(null, new Object[] { args });
|
main.invoke(null, new Object[] { args });
|
||||||
|
@ -6,6 +6,7 @@ import net.minestom.server.extras.selfmodification.MinestomOverwriteClassLoader;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongepowered.asm.mixin.Mixins;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
@ -232,7 +233,11 @@ public class ExtensionManager {
|
|||||||
modifiableClassLoader.loadModifier(extension.files, elem.getAsString());
|
modifiableClassLoader.loadModifier(extension.files, elem.getAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: special support for mixins
|
if(extension.description.has("mixinConfig")) {
|
||||||
|
String mixinConfigFile = extension.description.get("mixinConfig").getAsString();
|
||||||
|
Mixins.addConfiguration(mixinConfigFile);
|
||||||
|
log.info("Found mixin in extension "+extension.description.get("name").getAsString()+": "+mixinConfigFile);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error("Failed to load code modifier for extension in files: "+Arrays.toString(extension.files), e);
|
log.error("Failed to load code modifier for extension in files: "+Arrays.toString(extension.files), e);
|
||||||
|
@ -9,7 +9,6 @@ import org.objectweb.asm.tree.ClassNode;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
@ -18,6 +17,9 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Loader that can modify class bytecode when they are loaded
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class MinestomOverwriteClassLoader extends URLClassLoader {
|
public class MinestomOverwriteClassLoader extends URLClassLoader {
|
||||||
|
|
||||||
@ -38,8 +40,16 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
add("com.google");
|
add("com.google");
|
||||||
add("com.mojang");
|
add("com.mojang");
|
||||||
add("org.objectweb.asm");
|
add("org.objectweb.asm");
|
||||||
|
add("org.slf4j");
|
||||||
|
add("org.apache");
|
||||||
|
add("org.spongepowered");
|
||||||
|
add("net.minestom.server.extras.selfmodification");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Used to let ASM find out common super types, without actually commiting to loading them
|
||||||
|
* Otherwise ASM would accidentally load classes we might want to modify
|
||||||
|
*/
|
||||||
private final URLClassLoader asmClassLoader;
|
private final URLClassLoader asmClassLoader;
|
||||||
|
|
||||||
// TODO: replace by tree to optimize lookup times. We can use the fact that package names are split with '.' to allow for fast lookup
|
// TODO: replace by tree to optimize lookup times. We can use the fact that package names are split with '.' to allow for fast lookup
|
||||||
@ -48,26 +58,9 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
|
|
||||||
// TODO: priorities?
|
// TODO: priorities?
|
||||||
private List<CodeModifier> modifiers = new LinkedList<>();
|
private List<CodeModifier> modifiers = new LinkedList<>();
|
||||||
private final Method findParentLoadedClass;
|
|
||||||
private final Class<?> loadedCodeModifier;
|
|
||||||
|
|
||||||
private MinestomOverwriteClassLoader(ClassLoader parent) {
|
private MinestomOverwriteClassLoader(ClassLoader parent) {
|
||||||
super("Minestom ClassLoader", loadURLs(), parent);
|
super("Minestom ClassLoader", extractURLsFromClasspath(), parent);
|
||||||
try {
|
|
||||||
findParentLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
|
|
||||||
findParentLoadedClass.setAccessible(true);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new Error("Failed to access ClassLoader#findLoadedClass", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
loadedCodeModifier = loadClass("net.minestom.server.extras.selfmodification.CodeModifier");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new Error("Failed to access CodeModifier class.");
|
|
||||||
}
|
|
||||||
|
|
||||||
asmClassLoader = newChild(new URL[0]);
|
asmClassLoader = newChild(new URL[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +75,7 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URL[] loadURLs() {
|
private static URL[] extractURLsFromClasspath() {
|
||||||
String classpath = System.getProperty("java.class.path");
|
String classpath = System.getProperty("java.class.path");
|
||||||
String[] parts = classpath.split(";");
|
String[] parts = classpath.split(";");
|
||||||
URL[] urls = new URL[parts.length];
|
URL[] urls = new URL[parts.length];
|
||||||
@ -103,13 +96,6 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URL[] fromParent(ClassLoader parent) {
|
|
||||||
if(parent instanceof URLClassLoader) {
|
|
||||||
return ((URLClassLoader) parent).getURLs();
|
|
||||||
}
|
|
||||||
return new URL[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||||
Class<?> loadedClass = findLoadedClass(name);
|
Class<?> loadedClass = findLoadedClass(name);
|
||||||
@ -117,18 +103,12 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
return loadedClass;
|
return loadedClass;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// we do not load system classes by ourselves
|
||||||
Class<?> systemClass = ClassLoader.getPlatformClassLoader().loadClass(name);
|
Class<?> systemClass = ClassLoader.getPlatformClassLoader().loadClass(name);
|
||||||
log.trace("System class: "+systemClass);
|
log.trace("System class: "+systemClass);
|
||||||
return systemClass;
|
return systemClass;
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
// check if parent already loaded the class
|
|
||||||
Class<?> loadedByParent = (Class<?>) findParentLoadedClass.invoke(getParent(), name);
|
|
||||||
if(loadedByParent != null) {
|
|
||||||
log.trace("Already found in parent: "+loadedByParent);
|
|
||||||
return super.loadClass(name, resolve);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isProtected(name)) {
|
if(isProtected(name)) {
|
||||||
log.trace("Protected: "+name);
|
log.trace("Protected: "+name);
|
||||||
return super.loadClass(name, resolve);
|
return super.loadClass(name, resolve);
|
||||||
@ -164,7 +144,17 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
return defined;
|
return defined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] loadBytes(String name, boolean transform) throws IOException {
|
/**
|
||||||
|
* Loads and possibly transforms class bytecode corresponding to the given binary name.
|
||||||
|
* @param name
|
||||||
|
* @param transform
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
public byte[] loadBytes(String name, boolean transform) throws IOException, ClassNotFoundException {
|
||||||
|
if(name == null)
|
||||||
|
throw new ClassNotFoundException();
|
||||||
String path = name.replace(".", "/") + ".class";
|
String path = name.replace(".", "/") + ".class";
|
||||||
byte[] bytes = getResourceAsStream(path).readAllBytes();
|
byte[] bytes = getResourceAsStream(path).readAllBytes();
|
||||||
if(transform && !isProtected(name)) {
|
if(transform && !isProtected(name)) {
|
||||||
@ -195,15 +185,12 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// overriden to increase access (from protected to public)
|
||||||
@Override
|
@Override
|
||||||
public Class<?> findClass(String name) throws ClassNotFoundException {
|
public Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
return super.findClass(name);
|
return super.findClass(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resolve(Class<?> clazz) {
|
|
||||||
resolveClass(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public URLClassLoader newChild(@NotNull URL[] urls) {
|
public URLClassLoader newChild(@NotNull URL[] urls) {
|
||||||
return URLClassLoader.newInstance(urls, this);
|
return URLClassLoader.newInstance(urls, this);
|
||||||
|
@ -7,6 +7,9 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global properties service for Mixin
|
||||||
|
*/
|
||||||
public class GlobalPropertyServiceMinestom implements IGlobalPropertyService {
|
public class GlobalPropertyServiceMinestom implements IGlobalPropertyService {
|
||||||
|
|
||||||
private class BasicProperty implements IPropertyKey {
|
private class BasicProperty implements IPropertyKey {
|
||||||
|
@ -7,6 +7,9 @@ import org.spongepowered.asm.service.IClassBytecodeProvider;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides class bytecode for Mixin
|
||||||
|
*/
|
||||||
public class MinestomBytecodeProvider implements IClassBytecodeProvider {
|
public class MinestomBytecodeProvider implements IClassBytecodeProvider {
|
||||||
private final MinestomOverwriteClassLoader classLoader;
|
private final MinestomOverwriteClassLoader classLoader;
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ import org.spongepowered.asm.service.IClassProvider;
|
|||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides classes for Mixin
|
||||||
|
*/
|
||||||
public class MinestomClassProvider implements IClassProvider {
|
public class MinestomClassProvider implements IClassProvider {
|
||||||
private final MinestomOverwriteClassLoader classLoader;
|
private final MinestomOverwriteClassLoader classLoader;
|
||||||
|
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
package net.minestom.server.extras.selfmodification.mixins;
|
|
||||||
|
|
||||||
import net.minestom.server.extras.selfmodification.CodeModifier;
|
|
||||||
import net.minestom.server.extras.selfmodification.MinestomOverwriteClassLoader;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
import org.spongepowered.asm.service.ITransformer;
|
|
||||||
import org.spongepowered.asm.service.ITransformerProvider;
|
|
||||||
import org.spongepowered.asm.service.ITreeClassTransformer;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MinestomTransformerProvider implements ITransformerProvider {
|
|
||||||
private final MinestomOverwriteClassLoader classLoader;
|
|
||||||
private List<ITransformer> transformers;
|
|
||||||
|
|
||||||
public MinestomTransformerProvider(MinestomOverwriteClassLoader classLoader) {
|
|
||||||
this.classLoader = classLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTransformerExclusion(String name) {
|
|
||||||
classLoader.protectedClasses.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<ITransformer> getTransformers() {
|
|
||||||
return getDelegatedTransformers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<ITransformer> getDelegatedTransformers() {
|
|
||||||
if(transformers == null) {
|
|
||||||
transformers = buildTransformerList();
|
|
||||||
}
|
|
||||||
return transformers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ITransformer> buildTransformerList() {
|
|
||||||
List<ITransformer> result = new LinkedList<>();
|
|
||||||
for(CodeModifier modifier : classLoader.getModifiers()) {
|
|
||||||
result.add(toMixin(modifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> clazz = classLoader.loadClass("org.spongepowered.asm.mixin.transformer.MixingTransformer");
|
|
||||||
ITransformer mixinTransformer = (ITransformer) clazz.getDeclaredConstructor().newInstance();
|
|
||||||
result.add(mixinTransformer);
|
|
||||||
} catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ITransformer toMixin(CodeModifier modifier) {
|
|
||||||
return new ITreeClassTransformer() {
|
|
||||||
@Override
|
|
||||||
public boolean transformClassNode(String name, String transformedName, ClassNode classNode) {
|
|
||||||
return modifier.transform(classNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return modifier.getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDelegationExcluded() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.minestom.server.extras.selfmodification.mixins;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.spongepowered.asm.service.IMixinAuditTrail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes care of logging mixin operations
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class MixinAuditTrailMinestom implements IMixinAuditTrail {
|
||||||
|
@Override
|
||||||
|
public void onApply(String className, String mixinName) {
|
||||||
|
log.trace("Applied mixin "+mixinName+" to class "+className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostProcess(String className) {
|
||||||
|
log.trace("Post processing "+className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGenerate(String className, String generatorName) {
|
||||||
|
log.trace("Generating class "+className+" via generator "+generatorName);
|
||||||
|
}
|
||||||
|
}
|
@ -3,50 +3,44 @@ package net.minestom.server.extras.selfmodification.mixins;
|
|||||||
import net.minestom.server.extras.selfmodification.CodeModifier;
|
import net.minestom.server.extras.selfmodification.CodeModifier;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||||
import org.spongepowered.asm.mixin.transformer.MixinProcessor;
|
|
||||||
import org.spongepowered.asm.mixin.transformer.ext.Extensions;
|
|
||||||
import org.spongepowered.asm.mixin.transformer.ext.IHotSwap;
|
|
||||||
import org.spongepowered.asm.service.ISyntheticClassInfo;
|
|
||||||
import org.spongepowered.asm.service.ISyntheticClassRegistry;
|
|
||||||
import org.spongepowered.asm.transformers.TreeTransformer;
|
import org.spongepowered.asm.transformers.TreeTransformer;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CodeModifier responsible for applying Mixins during class load
|
||||||
|
*/
|
||||||
public class MixinCodeModifier extends CodeModifier {
|
public class MixinCodeModifier extends CodeModifier {
|
||||||
|
|
||||||
private Method transformClassMethod;
|
/**
|
||||||
private TreeTransformer processor;
|
* Call MixinTransformer's transformClass
|
||||||
|
*/
|
||||||
|
private final Method transformClassMethod;
|
||||||
|
private final TreeTransformer transformer;
|
||||||
|
|
||||||
public MixinCodeModifier() {
|
public MixinCodeModifier() {
|
||||||
try {
|
try {
|
||||||
|
// MixinTransformer is package-protected, so we have to force to gain access
|
||||||
Class<?> mixinTransformerClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinTransformer");
|
Class<?> mixinTransformerClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinTransformer");
|
||||||
Constructor<?> ctor = mixinTransformerClass.getDeclaredConstructor();
|
Constructor<?> ctor = mixinTransformerClass.getDeclaredConstructor();
|
||||||
ctor.setAccessible(true);
|
ctor.setAccessible(true);
|
||||||
this.processor = (TreeTransformer) ctor.newInstance();
|
this.transformer = (TreeTransformer) ctor.newInstance();
|
||||||
|
|
||||||
|
// we can't access the MixinTransformer type here, so we use reflection to access the method
|
||||||
transformClassMethod = mixinTransformerClass.getDeclaredMethod("transformClass", MixinEnvironment.class, String.class, ClassNode.class);
|
transformClassMethod = mixinTransformerClass.getDeclaredMethod("transformClass", MixinEnvironment.class, String.class, ClassNode.class);
|
||||||
transformClassMethod.setAccessible(true);
|
transformClassMethod.setAccessible(true);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException | ClassNotFoundException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException("Failed to initialize MixinCodeModifier", e);
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean transform(ClassNode source) {
|
public boolean transform(ClassNode source) {
|
||||||
try {
|
try {
|
||||||
return (boolean) transformClassMethod.invoke(processor, MixinEnvironment.getEnvironment(MixinEnvironment.Phase.DEFAULT), source.name.replace("/", "."), source);
|
return (boolean) transformClassMethod.invoke(transformer, MixinEnvironment.getEnvironment(MixinEnvironment.Phase.DEFAULT), source.name.replace("/", "."), source);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -16,13 +16,13 @@ public class MixinServiceMinestom extends MixinServiceAbstract {
|
|||||||
private final MinestomOverwriteClassLoader classLoader;
|
private final MinestomOverwriteClassLoader classLoader;
|
||||||
private final MinestomClassProvider classProvider;
|
private final MinestomClassProvider classProvider;
|
||||||
private final MinestomBytecodeProvider bytecodeProvider;
|
private final MinestomBytecodeProvider bytecodeProvider;
|
||||||
private final MinestomTransformerProvider transformerProvider;
|
private final MixinAuditTrailMinestom auditTrail;
|
||||||
|
|
||||||
public MixinServiceMinestom() {
|
public MixinServiceMinestom() {
|
||||||
this.classLoader = MinestomOverwriteClassLoader.getInstance();
|
this.classLoader = MinestomOverwriteClassLoader.getInstance();
|
||||||
classProvider = new MinestomClassProvider(classLoader);
|
classProvider = new MinestomClassProvider(classLoader);
|
||||||
bytecodeProvider = new MinestomBytecodeProvider(classLoader);
|
bytecodeProvider = new MinestomBytecodeProvider(classLoader);
|
||||||
transformerProvider = new MinestomTransformerProvider(classLoader);
|
auditTrail = new MixinAuditTrailMinestom();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,7 +47,7 @@ public class MixinServiceMinestom extends MixinServiceAbstract {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITransformerProvider getTransformerProvider() {
|
public ITransformerProvider getTransformerProvider() {
|
||||||
return transformerProvider;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,8 +65,6 @@ public class MixinServiceMinestom extends MixinServiceAbstract {
|
|||||||
return classLoader.getResourceAsStream(name);
|
return classLoader.getResourceAsStream(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: everything below
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IClassTracker getClassTracker() {
|
public IClassTracker getClassTracker() {
|
||||||
return null;
|
return null;
|
||||||
@ -74,12 +72,13 @@ public class MixinServiceMinestom extends MixinServiceAbstract {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IMixinAuditTrail getAuditTrail() {
|
public IMixinAuditTrail getAuditTrail() {
|
||||||
return null;
|
return auditTrail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wire(MixinEnvironment.Phase phase, IConsumer<MixinEnvironment.Phase> phaseConsumer) {
|
public void wire(MixinEnvironment.Phase phase, IConsumer<MixinEnvironment.Phase> phaseConsumer) {
|
||||||
super.wire(phase, phaseConsumer);
|
super.wire(phase, phaseConsumer);
|
||||||
|
// TODO: hook into Minestom initialization process
|
||||||
phaseConsumer.accept(MixinEnvironment.Phase.PREINIT);
|
phaseConsumer.accept(MixinEnvironment.Phase.PREINIT);
|
||||||
phaseConsumer.accept(MixinEnvironment.Phase.INIT);
|
phaseConsumer.accept(MixinEnvironment.Phase.INIT);
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,9 @@ import org.spongepowered.asm.mixin.Mixins;
|
|||||||
|
|
||||||
// To launch with VM arguments:
|
// To launch with VM arguments:
|
||||||
// -Dminestom.extension.indevfolder.classes=build/classes/java/test/ -Dminestom.extension.indevfolder.resources=build/resources/test/
|
// -Dminestom.extension.indevfolder.classes=build/classes/java/test/ -Dminestom.extension.indevfolder.resources=build/resources/test/
|
||||||
public class TestExtensionLauncher {
|
public class TestExtensionLauncherNoSetup {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
MixinBootstrap.init();
|
|
||||||
Mixins.addConfiguration("mixins.testextension.json");
|
|
||||||
Bootstrap.bootstrap("fr.themode.demo.MainDemo", args);
|
Bootstrap.bootstrap("fr.themode.demo.MainDemo", args);
|
||||||
}
|
}
|
||||||
|
|
@ -14,5 +14,4 @@ public class InstanceContainerMixin {
|
|||||||
System.out.println("Hello from Mixin!!!");
|
System.out.println("Hello from Mixin!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
"name": "Test extension",
|
"name": "Test extension",
|
||||||
"codeModifiers": [
|
"codeModifiers": [
|
||||||
"testextension.TestModifier"
|
"testextension.TestModifier"
|
||||||
]
|
],
|
||||||
|
"mixinConfig": "mixins.testextension.json"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user