nearly successful loading

This commit is contained in:
moehreag 2024-05-13 20:38:57 +02:00
parent edd5f5fedc
commit 5f8ed35231
11 changed files with 132 additions and 40 deletions

3
.gitignore vendored
View file

@ -41,3 +41,6 @@ bin/
### Mac OS ###
.DS_Store
.idea/
minecraft/*
!minecraft/.gitkeep

View file

@ -4,15 +4,24 @@ plugins {
}
group = "org.example"
version = "1.0-SNAPSHOT"
version = "0.0.1-SNAPSHOT"
repositories {
maven {
name = "Esnesnon Maven/Snapshots"
url = uri("https://maven-esnesnon.ecorous.org/snapshots")
}
maven {
name = "Esnesnon Maven/Releases"
url = uri("https://maven-esnesnon.ecorous.org/releases")
}
maven("https://maven.fabricmc.net/")
maven("https://repo.spongepowered.org/maven")
mavenCentral()
}
dependencies {
implementation("org.ecorous.esnesnon:mojmap-patcher:1.0.0-SNAPSHOT")
implementation("net.fabricmc:sponge-mixin:0.13.4+mixin.0.8.5")
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:3.0.0-beta2")
implementation("org.apache.logging.log4j:log4j-api:3.0.0-beta2")

0
minecraft/.gitkeep Normal file
View file

View file

@ -0,0 +1,10 @@
package io.github.moehreag.nonsense.loader.api.mod;
public interface ModProperties {
String id();
String name();
}

View file

@ -0,0 +1,11 @@
package io.github.moehreag.nonsense.loader.api.mod;
import java.util.Map;
public interface ModProvider {
ModProperties properties();
Map<String, String> entrypoints();
}

View file

@ -16,6 +16,8 @@ import java.util.Map;
import io.github.moehreag.nonsense.loader.impl.mixin.NonsenseMixinService;
import lombok.Getter;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.service.IPropertyKey;
@ -35,6 +37,7 @@ public class Launcher {
private final Env env;
public static void run(String[] args, Env env) {
Configurator.setRootLevel(Level.INFO); // TODO replace with actual log4j config
new Launcher(args, env);
}
@ -56,7 +59,7 @@ public class Launcher {
Thread.currentThread().setContextClassLoader(targetClassLoader);
try {
MethodHandle ctor = MethodHandles.publicLookup().findStatic(targetClassLoader.findClass(LoaderImpl.class.getName()), "run", MethodType.methodType(void.class, String[].class, Env.class));
MethodHandle ctor = MethodHandles.publicLookup().findStatic(targetClassLoader.loadClass(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

@ -14,6 +14,7 @@ import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
public class LoaderImpl implements Loader {
@ -37,16 +38,19 @@ public class LoaderImpl implements Loader {
@Getter
private final Path gameDir, configDir, modsDir;
public LoaderImpl(String[] args, Env env) {
private LoaderImpl(String[] args, Env env) {
instance = this;
System.out.println("info logging: "+ LOGGER.isEnabledForLevel(Level.INFO));
this.args = args;
this.env = env;
gameDir = Paths.get(getArgument("gameDir"));
gameDir = Paths.get(getArgumentOrElse("gameDir", "."));
configDir = gameDir.resolve("config");
modsDir = gameDir.resolve("mods");
try {
Files.createDirectories(gameDir);
Files.createDirectories(configDir);
Files.createDirectories(modsDir);
} catch (IOException e) {
LOGGER.warn("Failed to create essential directories ", e);
@ -54,7 +58,8 @@ public class LoaderImpl implements Loader {
discoverPlugins();
LOGGER.info("Launching...");
plugins.forEach(NonsensePlugin::run);
}
public static void run(String[] args, Env env) {
@ -62,12 +67,12 @@ public class LoaderImpl implements Loader {
throw new IllegalStateException("Loader was started multiple times!");
}
instance = new LoaderImpl(args, env);
new LoaderImpl(args, env);
}
private void discoverPlugins() {
List<String> classes = new ArrayList<>();
this.getClass().getClassLoader().resources(PLUGIN_SERVICE_FILE_LOCATION).forEach(url -> {
this.getClass().getClassLoader().resources(PLUGIN_SERVICE_FILE_LOCATION).distinct().forEach(url -> {
try (InputStream inputStream = url.openStream()) {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(classes::add);
} catch (IOException e) {
@ -75,6 +80,7 @@ public class LoaderImpl implements Loader {
throw new UncheckedIOException(e);
}
});
LOGGER.info("Found plugins: \n{}", String.join("\t\n", classes));
classes.stream().map((String className) -> {
try {
@ -88,7 +94,7 @@ public class LoaderImpl implements Loader {
MethodHandle ctor = MethodHandles.publicLookup().findConstructor(c, MethodType.methodType(void.class));
NonsensePlugin plugin = (NonsensePlugin) ctor.invoke();
plugins.add(plugin);
plugin.init();
plugin.init(this);
} catch (Throwable e) {
e.printStackTrace();
LOGGER.error("Failed to instantiate plugin: ", e);
@ -98,10 +104,18 @@ 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)){
if (args[i].equals("--"+name)){
return args[i+1];
}
}
return "";
}
public String getArgumentOrElse(String name, String other){
String res = getArgument(name);
if (res.isEmpty()){
return other;
}
return res;
}
}

View file

@ -0,0 +1,6 @@
package io.github.moehreag.nonsense.loader.impl.mod;
import io.github.moehreag.nonsense.loader.api.mod.ModProperties;
public record BuiltinModProperties(String id, String name) implements ModProperties {
}

View file

@ -0,0 +1,9 @@
package io.github.moehreag.nonsense.loader.impl.mod;
import java.util.Map;
import io.github.moehreag.nonsense.loader.api.mod.ModProperties;
import io.github.moehreag.nonsense.loader.api.mod.ModProvider;
public record BuiltinModProvider(ModProperties properties, Map<String, String> entrypoints) implements ModProvider {
}

View file

@ -1,21 +1,14 @@
package io.github.moehreag.nonsense.loader.impl.plugin;
import io.github.moehreag.nonsense.loader.impl.Env;
import java.util.Collections;
import java.util.Map;
import io.github.moehreag.nonsense.loader.impl.LoaderImpl;
public interface NonsensePlugin extends Runnable {
default Map<Env, String> getEntrypoints(){
return Collections.emptyMap();
}
default void run() {
default void run(){
}
}
default void init(LoaderImpl loader) {
default void init(){
}
}
}

View file

@ -1,42 +1,74 @@
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.LoaderImpl;
import io.github.moehreag.nonsense.loader.impl.plugin.NonsensePlugin;
import org.ecorous.esnesnon.mojmap_patcher.MojMapPatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
public class Minecraft implements NonsensePlugin {
private static final Logger LOGGER = LoggerFactory.getLogger("Plugin/Minecraft");
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
public Map<Env, String> getEntrypoints() {
return Map.of(
Env.CLIENT, "net.minecraft.client.main.Main",
Env.SERVER, "net.minecraft.server.main.Main"
);
}
private final List<Path> mods = new ArrayList<>();
private String version;
private Path remappedGamePath;
private String foundMainClass;
@Override
public void init() {
public void init(LoaderImpl loader) {
version = loader.getArgument("version");
remappedGamePath = loader.getGameDir().resolve(".nonsense/remappedJars").resolve(version).resolve("game-"+version+"-remapped.jar");
if (!Files.exists(remappedGamePath)){
try {
Files.createDirectories(remappedGamePath.getParent());
} catch (IOException e) {
LOGGER.error("Failed to create directory", e);
}
}
mods.addAll(Discovery.find(loader.getModsDir(), path ->
version.equals(path.getFileName().toString()), path ->
path.getFileName().toString().endsWith(LoaderImpl.MOD_FILE_EXTENSION)));
if (!Files.exists(remappedGamePath)){
Path gameJar = findGame();
if (gameJar == null){
throw new IllegalStateException("Could not find game jar!");
}
try {
MojMapPatcher.run(version, gameJar, remappedGamePath);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private Path findGame() {
for (String s : System.getProperty("java.class.path", "").split(File.pathSeparator)) {
Path p = Paths.get(s);
if (!Files.exists(p) || Files.isDirectory(p)){
continue;
}
try (FileSystem fs = FileSystems.newFileSystem(p)) {
for (String n : MINECRAFT_CLASSES) {
if (Files.exists(fs.getPath(n))){
LOGGER.info("Found game: {}", p);
foundMainClass = n.substring(0, n.length()-6).replace("/", ".");
return p;
}
}
@ -44,18 +76,20 @@ public class Minecraft implements NonsensePlugin {
throw new RuntimeException(e);
}
}
LOGGER.warn("Could not locate game!");
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
});
try {
LOGGER.info("Launching main class: {}", foundMainClass);
//Class<?> mainClass = Class.forName(foundMainClass);
//MethodHandle main = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
//main.invoke((Object)LoaderImpl.getInstance().getArgs());
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}