diff --git a/common/src/main/java/io/gitlab/jfronny/inceptum/common/Updater.java b/common/src/main/java/io/gitlab/jfronny/inceptum/common/Updater.java index d0c561b..301d7fc 100644 --- a/common/src/main/java/io/gitlab/jfronny/inceptum/common/Updater.java +++ b/common/src/main/java/io/gitlab/jfronny/inceptum/common/Updater.java @@ -23,8 +23,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class Updater { - private static final long PROJECT_ID = 30862253L; - private static final String PROJECT_MAVEN = "https://gitlab.com/api/v4/projects/" + PROJECT_ID + "/packages/maven/"; public static UpdateMetadata getUpdate() { return Updater.check(InceptumConfig.channel, BuildMetadata.VERSION, channel -> { @@ -116,7 +114,7 @@ public class Updater { private static DependencyNode downloadLibrary(Set repositories, final String artifact, Set libraries) throws IOException, URISyntaxException { List exceptions = new LinkedList<>(); - for (String repository : Stream.concat(Stream.of(PROJECT_MAVEN), repositories.stream()).toList()) { + for (String repository : Stream.concat(Stream.of(GitlabApi.PROJECT_MAVEN), repositories.stream()).toList()) { Pom pom; try { pom = MavenApi.getPom(repository, artifact); @@ -149,7 +147,7 @@ public class Updater { public static @Nullable UpdateMetadata check(UpdateChannel channel, ComparableVersion current, Consumer channelInvalid) { try { int jvm = Runtime.version().feature(); - GitlabProject project = GitlabApi.getProject(PROJECT_ID); + GitlabProject project = GitlabApi.getProject(GitlabApi.PROJECT_ID); UpdateMetadata experimental = null; UpdateMetadata stable = null; packageLoop:for (GitlabPackage info : GitlabApi.getPackages(project)) { @@ -204,6 +202,6 @@ public class Updater { } public static String getShadowJarUrl(UpdateMetadata metadata) { - return PROJECT_MAVEN + "io/gitlab/jfronny/inceptum/Inceptum/" + metadata.version + "/Inceptum-" + metadata.version + "-" + Utils.getCurrentFlavor() + ".jar"; + return GitlabApi.PROJECT_MAVEN + "io/gitlab/jfronny/inceptum/Inceptum/" + metadata.version + "/Inceptum-" + metadata.version + "-" + Utils.getCurrentFlavor() + ".jar"; } } diff --git a/common/src/main/java/io/gitlab/jfronny/inceptum/common/api/GitlabApi.java b/common/src/main/java/io/gitlab/jfronny/inceptum/common/api/GitlabApi.java index bed1ac2..b83677f 100644 --- a/common/src/main/java/io/gitlab/jfronny/inceptum/common/api/GitlabApi.java +++ b/common/src/main/java/io/gitlab/jfronny/inceptum/common/api/GitlabApi.java @@ -12,6 +12,10 @@ import java.util.function.Predicate; public class GitlabApi { public static final String PROJECTS = "https://gitlab.com/api/v4/projects/"; + + public static final long PROJECT_ID = 30862253L; + public static final String PROJECT_MAVEN = "https://gitlab.com/api/v4/projects/" + PROJECT_ID + "/packages/maven/"; + private static final Type packageInfoListType = new TypeToken>() {}.getType(); private static final Type jobListType = new TypeToken>() {}.getType(); private static final Type packageFileInfoListType = new TypeToken>() {}.getType(); diff --git a/docs/Modules.md b/docs/Modules.md index 49a0fc8..6159fce 100644 --- a/docs/Modules.md +++ b/docs/Modules.md @@ -25,6 +25,10 @@ It also adds additional, platform-specific commands to the CLI. A shadowed build can be obtained as "Inceptum" from maven, a build with dependencies as "launcher-dist" Windows users can also obtain a binary built using fabric-installer-native-bootstrap. +## launchwrapper +This module is added to the minecraft classpath and therefore independent of any other modules. +It handles loading forceload natives + ## wrapper This module serves the purpose of downloading the components necessary for executing Inceptum on the current platform. A build with shadowed dependencies can be obtained through the maven (with the suffix "all") or as a jar. diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/export/Exporters.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/export/Exporters.java index 890471e..25cf988 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/export/Exporters.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/export/Exporters.java @@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.launcher.system.export; import java.util.List; -//TODO modrinth export public class Exporters { public static final int STEP_COUNT = 4; public static final CurseForgeExporter CURSE_FORGE = new CurseForgeExporter(); diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadJavaStep.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadJavaStep.java index ae4004d..18cb29f 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadJavaStep.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadJavaStep.java @@ -1,12 +1,11 @@ package io.gitlab.jfronny.inceptum.launcher.system.install.steps; -import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.Net; -import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import io.gitlab.jfronny.inceptum.launcher.api.McApi; -import io.gitlab.jfronny.inceptum.launcher.system.install.Step; +import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; +import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import java.io.IOException; import java.net.URISyntaxException; @@ -42,7 +41,5 @@ public class DownloadJavaStep implements Step { case "directory" -> Files.createDirectories(tPath); } } - //TODO link these in using a pre-launch class added to the launch classpath instead - JFiles.copyRecursive(MetaHolder.FORCE_LOAD_PATH, jvmDir.resolve("bin")); } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadLibrariesStep.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadLibrariesStep.java index 55def69..c1312c3 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadLibrariesStep.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/install/steps/DownloadLibrariesStep.java @@ -2,6 +2,8 @@ package io.gitlab.jfronny.inceptum.launcher.system.install.steps; import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.inceptum.common.*; +import io.gitlab.jfronny.inceptum.common.api.GitlabApi; +import io.gitlab.jfronny.inceptum.common.api.MavenApi; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ArtifactInfo; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo; @@ -48,5 +50,18 @@ public class DownloadLibrariesStep implements Step { } } } + + String artifact = getLaunchWrapperArtifact(); + if (!Files.exists(MetaHolder.LIBRARIES_DIR.resolve(MavenApi.mavenNotationToJarPath(artifact)))) { + try { + MavenApi.downloadLibrary(GitlabApi.PROJECT_MAVEN, artifact); + } catch (URISyntaxException e) { + throw new IOException("Could not download launchwrapper", e); + } + } + } + + public static String getLaunchWrapperArtifact() { + return "io.gitlab.jfronny.inceptum:launchwrapper:" + (BuildMetadata.IS_PUBLIC ? BuildMetadata.VERSION : Updater.getUpdate().version); } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/launch/InstanceLauncher.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/launch/InstanceLauncher.java index e0e181b..d03a16a 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/launch/InstanceLauncher.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/launch/InstanceLauncher.java @@ -81,8 +81,10 @@ public class InstanceLauncher { classPath.append(MetaHolder.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath()); classPath.append(File.pathSeparatorChar); } - Path gameJar = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/" + launchType.name).resolve(versionDataSimple.id + ".jar").toAbsolutePath(); + Path gameJar = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/" + launchType.name).resolve(versionDataSimple.id + ".jar"); classPath.append(gameJar); + classPath.append(File.pathSeparatorChar); + classPath.append(MetaHolder.LIBRARIES_DIR.resolve(DownloadLibrariesStep.getLaunchWrapperArtifact())); // JVM arguments if (launchType == LaunchType.Client && versionInfo.arguments != null) args.addAll(parse(versionInfo.arguments.jvm, versionInfo, instance, classPath.toString(), instancePath.toAbsolutePath().toString(), authInfo)); @@ -90,7 +92,11 @@ public class InstanceLauncher { if (instance.maxMem != null) args.add("-Xmx" + instance.maxMem); if (instance.arguments != null && instance.arguments.jvm != null) args.addAll(instance.arguments.jvm); // Native library path - args.add("-Djava.library.path=" + MetaHolder.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath()); + args.add("-Djava.library.path=" + MetaHolder.NATIVES_DIR.resolve(instance.getMinecraftVersion())); + // Forceload natives + if (Files.exists(MetaHolder.FORCE_LOAD_PATH)) { + args.add("-Dinceptum.forceloadNatives=" + MetaHolder.FORCE_LOAD_PATH); + } // Fabric imods if (instance.isFabric()) { StringBuilder fabricAddMods = new StringBuilder("-Dfabric.addMods="); @@ -114,6 +120,8 @@ public class InstanceLauncher { // Add classpath to args args.add("-cp"); args.add(classPath.toString()); + // Wrapper class (launched by vm, launches main class) + args.add("io.gitlab.jfronny.inceptum.launchwrapper.Main"); // Main class args.add(resolveMainClass(instance, versionInfo, gameJar, launchType)); // Game arguments diff --git a/launchwrapper/build.gradle.kts b/launchwrapper/build.gradle.kts new file mode 100644 index 0000000..f6b897e --- /dev/null +++ b/launchwrapper/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("inceptum.library-conventions") +} + +java { + targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { +} \ No newline at end of file diff --git a/launchwrapper/src/main/java/io/gitlab/jfronny/inceptum/launchwrapper/Main.java b/launchwrapper/src/main/java/io/gitlab/jfronny/inceptum/launchwrapper/Main.java new file mode 100644 index 0000000..71d7d33 --- /dev/null +++ b/launchwrapper/src/main/java/io/gitlab/jfronny/inceptum/launchwrapper/Main.java @@ -0,0 +1,33 @@ +package io.gitlab.jfronny.inceptum.launchwrapper; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.nio.file.*; +import java.util.stream.Stream; + +public class Main { + public static void main(String[] args) throws ClassNotFoundException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + if (args.length == 0) throw new IllegalArgumentException("Missing class argument"); + + String forceloadNatives = System.getProperty("inceptum.forceloadNatives"); + if (forceloadNatives != null) { + Path p = Paths.get(forceloadNatives); + if (Files.exists(p)) { + try (Stream paths = Files.list(p)) { + paths.forEach(Main::load); + } + } else { + throw new IllegalArgumentException("Could not find forceloadNatives path"); + } + } + + Class mainClass = Class.forName(args[0]); + String[] newArgs = new String[args.length - 1]; + System.arraycopy(args, 1, newArgs, 0, args.length - 1); + mainClass.getMethod("main", String[].class).invoke(null, new Object[] {newArgs}); + } + + private static void load(Path path) { + System.load(path.toAbsolutePath().normalize().toString()); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 3b32546..bdee2b8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,4 +5,5 @@ include("wrapper") include("launcher") include("launcher-cli") include("launcher-imgui") -include("launcher-dist") \ No newline at end of file +include("launcher-dist") +include("launchwrapper")