mixins are now working

This commit is contained in:
moehreag 2024-05-24 21:14:05 +02:00
parent 798fc26fe4
commit ba409f9905
5 changed files with 173 additions and 156 deletions

View file

@ -17,6 +17,7 @@ import org.ecorous.esnesnon.nonsense.loader.impl.plugin.NonsensePlugin;
import lombok.Getter; import lombok.Getter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.MixinEnvironment;
public class LoaderImpl implements Loader { public class LoaderImpl implements Loader {
// TODO decide this // TODO decide this
@ -64,11 +65,21 @@ public class LoaderImpl implements Loader {
} }
discoverPlugins(); discoverPlugins();
advanceMixinState();
LOGGER.info("Launching..."); LOGGER.info("Launching...");
plugins.forEach(NonsensePlugin::run); plugins.forEach(NonsensePlugin::run);
} }
private void advanceMixinState(){
try {
MethodHandle m = MethodHandles.privateLookupIn(MixinEnvironment.class, MethodHandles.lookup()).findStatic(MixinEnvironment.class, "gotoPhase", MethodType.methodType(void.class, MixinEnvironment.Phase.class));
m.invoke(MixinEnvironment.Phase.INIT);
m.invoke(MixinEnvironment.Phase.DEFAULT);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static void run(String[] args, Env env) { public static void run(String[] args, Env env) {
if (instance != null) { if (instance != null) {

View file

@ -1,6 +1,8 @@
package org.ecorous.esnesnon.nonsense.loader.impl.launch; package org.ecorous.esnesnon.nonsense.loader.impl.launch;
import org.ecorous.esnesnon.nonsense.loader.impl.mixin.NonsenseMixinService;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.MixinEnvironment;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -40,7 +42,7 @@ public class MixinClassLoader extends URLClassLoader {
if (in == null) if (in == null)
return null; return null;
return in.readAllBytes(); return NonsenseMixinService.getTransformer().transformClass(MixinEnvironment.getCurrentEnvironment(), name, in.readAllBytes());
} }
} }

View file

@ -1,5 +1,6 @@
package org.ecorous.esnesnon.nonsense.loader.impl.mixin; package org.ecorous.esnesnon.nonsense.loader.impl.mixin;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -20,7 +21,7 @@ public class NonsenseMixinLogger extends LoggerAdapterAbstract {
public NonsenseMixinLogger(String name){ public NonsenseMixinLogger(String name){
super(name); super(name);
log = LoggerFactory.getLogger(name); log = LoggerFactory.getLogger("Nonsense Loader/"+name.substring(0, 1).toUpperCase(Locale.ROOT)+name.substring(1));
} }
@Override @Override

View file

@ -1,5 +1,13 @@
package org.ecorous.esnesnon.nonsense.loader.impl.mixin; package org.ecorous.esnesnon.nonsense.loader.impl.mixin;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import lombok.Getter;
import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher; import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
@ -13,198 +21,193 @@ import org.spongepowered.asm.service.*;
import org.spongepowered.asm.transformers.MixinClassReader; import org.spongepowered.asm.transformers.MixinClassReader;
import org.spongepowered.asm.util.ReEntranceLock; import org.spongepowered.asm.util.ReEntranceLock;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.List;
public class NonsenseMixinService implements IMixinService, IClassProvider, IClassBytecodeProvider, ITransformerProvider, IClassTracker { public class NonsenseMixinService implements IMixinService, IClassProvider, IClassBytecodeProvider, ITransformerProvider, IClassTracker {
static IMixinTransformer transformer; @Getter
private final ReEntranceLock lock = new ReEntranceLock(1); static IMixinTransformer transformer;
private final ContainerHandleVirtual handle = new ContainerHandleVirtual(getName()); private final ReEntranceLock lock = new ReEntranceLock(1);
private final ContainerHandleVirtual handle = new ContainerHandleVirtual(getName());
@Override @Override
public String getName() { public String getName() {
return "NonsenseMixinService"; return "NonsenseMixinService";
} }
@Override @Override
public boolean isValid() { public boolean isValid() {
return true; return true;
} }
@Override @Override
public void prepare() { public void prepare() {
} }
@Override @Override
public MixinEnvironment.Phase getInitialPhase() { public MixinEnvironment.Phase getInitialPhase() {
return null; return MixinEnvironment.Phase.PREINIT;
} }
@Override @Override
public void offer(IMixinInternal internal) { public void offer(IMixinInternal internal) {
if (internal instanceof IMixinTransformerFactory) { if (internal instanceof IMixinTransformerFactory) {
transformer = ((IMixinTransformerFactory) internal).createTransformer(); transformer = ((IMixinTransformerFactory) internal).createTransformer();
} }
} }
@Override @Override
public void init() { public void init() {
} }
@Override @Override
public void beginPhase() { public void beginPhase() {
} }
@Override @Override
public void checkEnv(Object bootSource) { public void checkEnv(Object bootSource) {
} }
@Override @Override
public ReEntranceLock getReEntranceLock() { public ReEntranceLock getReEntranceLock() {
return lock; return lock;
} }
@Override @Override
public IClassProvider getClassProvider() { public IClassProvider getClassProvider() {
return this; return this;
} }
@Override @Override
public IClassBytecodeProvider getBytecodeProvider() { public IClassBytecodeProvider getBytecodeProvider() {
return this; return this;
} }
@Override @Override
public ITransformerProvider getTransformerProvider() { public ITransformerProvider getTransformerProvider() {
return this; return this;
} }
@Override @Override
public IClassTracker getClassTracker() { public IClassTracker getClassTracker() {
return this; return this;
} }
@Override @Override
public IMixinAuditTrail getAuditTrail() { public IMixinAuditTrail getAuditTrail() {
return null; return null;
} }
@Override @Override
public Collection<String> getPlatformAgents() { public Collection<String> getPlatformAgents() {
return List.of(); return Collections.singletonList("org.spongepowered.asm.launch.platform.MixinPlatformAgentDefault");
} }
@Override @Override
public IContainerHandle getPrimaryContainer() { public IContainerHandle getPrimaryContainer() {
return handle; return handle;
} }
@Override @Override
public Collection<IContainerHandle> getMixinContainers() { public Collection<IContainerHandle> getMixinContainers() {
return List.of(); return List.of();
} }
@Override @Override
public InputStream getResourceAsStream(String name) { public InputStream getResourceAsStream(String name) {
return Launcher.getInstance().getTargetClassLoader().getResourceAsStream(name); return Launcher.getInstance().getTargetClassLoader().getResourceAsStream(name);
} }
@Override @Override
public String getSideName() { public String getSideName() {
return Launcher.getInstance().getEnv().getMixinName(); return Launcher.getInstance().getEnv().getMixinName();
} }
@Override @Override
public MixinEnvironment.CompatibilityLevel getMinCompatibilityLevel() { public MixinEnvironment.CompatibilityLevel getMinCompatibilityLevel() {
return null; return MixinEnvironment.CompatibilityLevel.JAVA_8;
} }
@Override @Override
public MixinEnvironment.CompatibilityLevel getMaxCompatibilityLevel() { public MixinEnvironment.CompatibilityLevel getMaxCompatibilityLevel() {
return null; return MixinEnvironment.CompatibilityLevel.JAVA_22;
} }
@Override @Override
public ILogger getLogger(String name) { public ILogger getLogger(String name) {
return NonsenseMixinLogger.get(name); return NonsenseMixinLogger.get(name);
} }
@Override @Override
public ClassNode getClassNode(String name) throws IOException { public ClassNode getClassNode(String name) throws IOException {
return getClassNode(name, true); return getClassNode(name, true);
} }
@Override @Override
public ClassNode getClassNode(String name, boolean runTransformers) throws IOException { public ClassNode getClassNode(String name, boolean runTransformers) throws IOException {
byte[] bytes; byte[] bytes;
if (runTransformers){ if (runTransformers && transformer != null) {
bytes = transformer.transformClass(MixinEnvironment.getCurrentEnvironment(), name, bytes = transformer.transformClass(MixinEnvironment.getCurrentEnvironment(), name,
Launcher.getInstance().getTargetClassLoader().getClassBytes(name)); Launcher.getInstance().getTargetClassLoader().getClassBytes(name));
} else { } else {
bytes = Launcher.getInstance().getTargetClassLoader().getClassBytes(name); bytes = Launcher.getInstance().getTargetClassLoader().getClassBytes(name);
} }
ClassReader reader = new MixinClassReader(bytes, name); ClassReader reader = new MixinClassReader(bytes, name);
ClassNode node = new ClassNode(); ClassNode node = new ClassNode();
reader.accept(node, 0); reader.accept(node, 0);
return node; return node;
} }
@Override @Override
@Deprecated @Deprecated
public URL[] getClassPath() { public URL[] getClassPath() {
return new URL[0]; return new URL[0];
} }
@Override @Override
public Class<?> findClass(String name) throws ClassNotFoundException { public Class<?> findClass(String name) throws ClassNotFoundException {
return Class.forName(name, false, Launcher.getInstance().getTargetClassLoader()); return Class.forName(name, false, Launcher.getInstance().getTargetClassLoader());
} }
@Override @Override
public Class<?> findClass(String name, boolean initialize) throws ClassNotFoundException { public Class<?> findClass(String name, boolean initialize) throws ClassNotFoundException {
return Class.forName(name, initialize, Launcher.getInstance().getTargetClassLoader()); return Class.forName(name, initialize, Launcher.getInstance().getTargetClassLoader());
} }
@Override @Override
public Class<?> findAgentClass(String name, boolean initialize) throws ClassNotFoundException { public Class<?> findAgentClass(String name, boolean initialize) throws ClassNotFoundException {
return Class.forName(name, initialize, Launcher.getInstance().getTargetClassLoader()); return Class.forName(name, initialize, Launcher.getInstance().getTargetClassLoader());
} }
@Override @Override
public void registerInvalidClass(String className) { public void registerInvalidClass(String className) {
} }
@Override @Override
public boolean isClassLoaded(String className) { public boolean isClassLoaded(String className) {
return Launcher.getInstance().getTargetClassLoader().isClassLoaded(className); return Launcher.getInstance().getTargetClassLoader().isClassLoaded(className);
} }
@Override @Override
public String getClassRestrictions(String className) { public String getClassRestrictions(String className) {
return ""; return "";
} }
@Override @Override
public Collection<ITransformer> getTransformers() { public Collection<ITransformer> getTransformers() {
return List.of(); return List.of();
} }
@Override @Override
public Collection<ITransformer> getDelegatedTransformers() { public Collection<ITransformer> getDelegatedTransformers() {
return List.of(); return List.of();
} }
@Override @Override
public void addTransformerExclusion(String name) { public void addTransformerExclusion(String name) {
} }
} }

View file

@ -70,7 +70,7 @@ public class Minecraft implements NonsensePlugin {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}).forEachOrdered(LoaderImpl.getInstance().getClassloader()::addURL); }).forEachOrdered(LoaderImpl.getInstance().getClassloader()::addURL);
LOGGER.info("Found {} mods", mods.size()+classpathMods.size()); LOGGER.info("Found {} mod(s)", mods.size()+classpathMods.size());
classpathMods.parallelStream().map(ModPropertiesReader::readFile).forEachOrdered(modProperties::add); classpathMods.parallelStream().map(ModPropertiesReader::readFile).forEachOrdered(modProperties::add);
mods.parallelStream().map(ModPropertiesReader::read).forEachOrdered(opt -> opt.ifPresent(modProperties::add)); mods.parallelStream().map(ModPropertiesReader::read).forEachOrdered(opt -> opt.ifPresent(modProperties::add));