i broke things (and other stuff)

This commit is contained in:
moehreag 2024-05-13 17:15:52 +02:00
parent 00c36a746c
commit c9d6f0b1f3
8 changed files with 159 additions and 30 deletions

View file

@ -1,5 +1,6 @@
package io.github.moehreag.nonsense.loader.api; package io.github.moehreag.nonsense.loader.api;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import io.github.moehreag.nonsense.loader.impl.Env; import io.github.moehreag.nonsense.loader.impl.Env;
@ -16,4 +17,8 @@ public interface Loader {
Env getEnv(); Env getEnv();
Path getGameDir();
Path getConfigDir();
Path getModsDir();
} }

View file

@ -0,0 +1,53 @@
package io.github.moehreag.nonsense.loader.impl;
import java.io.File;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
public class Launcher {
@Getter
private final MixinClassloader targetClassLoader;
private final List<Path> classPath;
@Getter
private static Launcher instance;
public static void run(String[] args, Env env) {
new Launcher(args, env);
}
public Launcher(String[] args, Env env){
if (instance != null){
throw new IllegalStateException();
}
instance = this;
classPath = Arrays.stream(System.getProperty("java.class.path").split(File.pathSeparator)).filter(s -> !"*".equals(s)).map(Paths::get).toList();
targetClassLoader = new MixinClassloader(classPath.stream().map(Path::toUri).map((URI uri) -> {
try {
return uri.toURL();
} catch (MalformedURLException e) {
// TODO
throw new RuntimeException(e);
}
}).toArray(URL[]::new), this.getClass().getClassLoader());
Thread.currentThread().setContextClassLoader(targetClassLoader);
try {
MethodHandle ctor = MethodHandles.publicLookup().findStatic(targetClassLoader.findClass(LoaderImpl.class.getName()), "run", MethodType.methodType(void.class, String[].class, Env.class));
ctor.invoke(args, env);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}

View file

@ -4,10 +4,10 @@ import java.io.*;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.util.ArrayList; import java.nio.file.Files;
import java.util.HashMap; import java.nio.file.Path;
import java.util.List; import java.nio.file.Paths;
import java.util.Map; import java.util.*;
import io.github.moehreag.nonsense.loader.api.Loader; import io.github.moehreag.nonsense.loader.api.Loader;
import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin; import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin;
@ -19,6 +19,8 @@ import org.spongepowered.asm.service.IPropertyKey;
public class LoaderImpl implements Loader { public class LoaderImpl implements Loader {
private static final String PLUGIN_SERVICE_FILE_LOCATION = "META-INF/services/io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin"; private static final String PLUGIN_SERVICE_FILE_LOCATION = "META-INF/services/io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin";
// TODO decide this
public static final String MOD_FILE_EXTENSION = ".nonsense";
@Getter @Getter
private final String[] args; private final String[] args;
@ -31,17 +33,32 @@ public class LoaderImpl implements Loader {
@Getter @Getter
private final Map<IPropertyKey, Object> globalProperties = new HashMap<>(); private final Map<IPropertyKey, Object> globalProperties = new HashMap<>();
private Logger LOGGER = LoggerFactory.getLogger("Nonsense Loader"); private final Logger LOGGER = LoggerFactory.getLogger("Nonsense Loader");
@Getter @Getter
private final List<NonsensePlugin> plugins = new ArrayList<>(); private final List<NonsensePlugin> plugins = new ArrayList<>();
@Getter
private final Path gameDir, configDir, modsDir;
public LoaderImpl(String[] args, Env env) { public LoaderImpl(String[] args, Env env) {
this.args = args; this.args = args;
this.env = env; this.env = env;
gameDir = Paths.get(getArgument("gameDir"));
configDir = gameDir.resolve("config");
modsDir = gameDir.resolve("mods");
try {
Files.createDirectories(gameDir);
Files.createDirectories(modsDir);
} catch (IOException e) {
LOGGER.warn("Failed to create essential directories ", e);
}
discoverPlugins(); discoverPlugins();
} }
public static void run(String[] args, Env env) { public static void run(String[] args, Env env) {
@ -82,4 +99,13 @@ public class LoaderImpl implements Loader {
} }
}); });
} }
public String getArgument(String name){
for (int i=0;i<args.length-1;i+=2){
if (args[i].equals(name)){
return args[i+1];
}
}
return "";
}
} }

View file

@ -1,7 +1,5 @@
package io.github.moehreag.nonsense.loader.impl; package io.github.moehreag.nonsense.loader.impl;
import org.spongepowered.asm.launch.MixinBootstrap;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
@ -12,8 +10,12 @@ public class MixinClassloader extends URLClassLoader {
@Override @Override
protected Class<?> findClass(String name) throws ClassNotFoundException { public Class<?> findClass(String name) throws ClassNotFoundException {
MixinBootstrap.getPlatform().inject();
return super.findClass(name); return super.findClass(name);
} }
public boolean isClassLoaded(String name){
return findLoadedClass(name) != null;
}
} }

View file

@ -1,11 +1,11 @@
package io.github.moehreag.nonsense.loader.impl.client; package io.github.moehreag.nonsense.loader.impl.client;
import io.github.moehreag.nonsense.loader.impl.Launcher;
import io.github.moehreag.nonsense.loader.impl.Env; import io.github.moehreag.nonsense.loader.impl.Env;
import io.github.moehreag.nonsense.loader.impl.LoaderImpl;
public class NonsenseClient { public class NonsenseClient {
public static void main(String[] args){ public static void main(String[] args){
LoaderImpl.run(args, Env.CLIENT); Launcher.run(args, Env.CLIENT);
} }
} }

View file

@ -1,11 +1,13 @@
package io.github.moehreag.nonsense.loader.impl.mixin; package io.github.moehreag.nonsense.loader.impl.mixin;
import io.github.moehreag.nonsense.loader.impl.Launcher;
import io.github.moehreag.nonsense.loader.impl.LoaderImpl; import io.github.moehreag.nonsense.loader.impl.LoaderImpl;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.launch.platform.container.IContainerHandle; import org.spongepowered.asm.launch.platform.container.IContainerHandle;
import org.spongepowered.asm.logging.ILogger; import org.spongepowered.asm.logging.ILogger;
import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.transformer.IMixinTransformer; import org.spongepowered.asm.mixin.transformer.IMixinTransformer;
import org.spongepowered.asm.mixin.transformer.IMixinTransformerFactory;
import org.spongepowered.asm.service.*; import org.spongepowered.asm.service.*;
import org.spongepowered.asm.util.ReEntranceLock; import org.spongepowered.asm.util.ReEntranceLock;
@ -41,7 +43,9 @@ public class NonsenseMixinService implements IMixinService, IClassProvider, ICla
@Override @Override
public void offer(IMixinInternal internal) { public void offer(IMixinInternal internal) {
if (internal instanceof IMixinTransformerFactory) {
transformer = ((IMixinTransformerFactory) internal).createTransformer();
}
} }
@Override @Override
@ -106,7 +110,7 @@ public class NonsenseMixinService implements IMixinService, IClassProvider, ICla
@Override @Override
public InputStream getResourceAsStream(String name) { public InputStream getResourceAsStream(String name) {
return null; return Launcher.getInstance().getTargetClassLoader().getResourceAsStream(name);
} }
@Override @Override
@ -147,17 +151,17 @@ public class NonsenseMixinService implements IMixinService, IClassProvider, ICla
@Override @Override
public Class<?> findClass(String name) throws ClassNotFoundException { public Class<?> findClass(String name) throws ClassNotFoundException {
return null; 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 null; 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 null; return Class.forName(name, initialize, Launcher.getInstance().getTargetClassLoader());
} }
@Override @Override
@ -167,7 +171,7 @@ public class NonsenseMixinService implements IMixinService, IClassProvider, ICla
@Override @Override
public boolean isClassLoaded(String className) { public boolean isClassLoaded(String className) {
return false; return Launcher.getInstance().getTargetClassLoader().isClassLoaded(className);
} }
@Override @Override

View file

@ -1,22 +1,61 @@
package io.github.moehreag.nonsense.loader.impl.plugin.game; package io.github.moehreag.nonsense.loader.impl.plugin.game;
import io.github.moehreag.nonsense.loader.api.Loader;
import io.github.moehreag.nonsense.loader.impl.Discovery;
import io.github.moehreag.nonsense.loader.impl.Env; import io.github.moehreag.nonsense.loader.impl.Env;
import io.github.moehreag.nonsense.loader.impl.LoaderImpl;
import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin; import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.Map; import java.util.Map;
public class Minecraft implements NonsensePlugin { public class Minecraft implements NonsensePlugin {
private static final String[] MINECRAFT_CLASSES = new String[]{
"net/minecraft/client/main/Main.class",
"net/minecraft/client/MinecraftApplet.class",
"net/minecraft/server/main/Main.class"
};
@Override @Override
public Map<Env, String> getEntrypoints() { public Map<Env, String> getEntrypoints() {
return Map.of( return Map.of(
Env.CLIENT, "net.minecraft.client.main.Main", Env.CLIENT, "net.minecraft.client.main.Main",
Env.SERVER, "net.minecraft.server.main.Main" Env.SERVER, "net.minecraft.server.main.Main"
); );
} }
@Override @Override
public void init() { public void init() {
initMixin(); initMixin();
} }
private Path findGame() {
for (String s : System.getProperty("java.class.path", "").split(File.pathSeparator)) {
Path p = Paths.get(s);
try (FileSystem fs = FileSystems.newFileSystem(p)) {
for (String n : MINECRAFT_CLASSES) {
if (Files.exists(fs.getPath(n))){
return p;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
@Override
public void run() {
Discovery.find(Loader.getInstance().getModsDir(), path ->
LoaderImpl.getInstance().getArgument("version")
.equals(path.getFileName().toString()), path ->
path.getFileName().toString().endsWith(LoaderImpl.MOD_FILE_EXTENSION))
.forEach(path -> {
// TODO collect mods
// TODO load mods
});
}
} }

View file

@ -1,11 +1,11 @@
package io.github.moehreag.nonsense.loader.impl.server; package io.github.moehreag.nonsense.loader.impl.server;
import io.github.moehreag.nonsense.loader.impl.Launcher;
import io.github.moehreag.nonsense.loader.impl.Env; import io.github.moehreag.nonsense.loader.impl.Env;
import io.github.moehreag.nonsense.loader.impl.LoaderImpl;
public class NonsenseServer { public class NonsenseServer {
public static void main(String[] args){ public static void main(String[] args){
LoaderImpl.run(args, Env.SERVER); Launcher.run(args, Env.SERVER);
} }
} }