From 82ceaa4680ee1a626effb6008ba605a10da07468 Mon Sep 17 00:00:00 2001 From: bigfoot547 Date: Tue, 9 Jan 2024 04:27:18 -0600 Subject: actually use runtime --- src/launch.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'src/launch.c') diff --git a/src/launch.c b/src/launch.c index 7d1c2b5..a8ea689 100644 --- a/src/launch.c +++ b/src/launch.c @@ -6,6 +6,7 @@ #include "version.h" #include "assets.h" #include "args.h" +#include "runtime.h" #include #include @@ -115,6 +116,47 @@ cleanup: return -1; } +int l2_launch_init_runtime(struct l2_launch *launch) +{ + const char *jrecompname; + if (json_unpack(launch->version, "{s:{s:s}}", "javaVersion", "component", &jrecompname) < 0) { + CMD_DEBUG0("bad launch version (no javaVersion)"); + return 0; + } + + json_t *rtmanifest = NULL; + if (l2_runtime_load_manifest(&rtmanifest) < 0) { + return -1; + } + + char *jrepath = NULL; + + if (l2_runtime_install_component(rtmanifest, jrecompname, &jrepath) < 0) { + goto cleanup; + } + + json_decref(rtmanifest); + launch->jrepath = jrepath; + + return 1; + +cleanup: + if (rtmanifest) json_decref(rtmanifest); + return -1; +} + +int l2_launch_init_runtime_manual(struct l2_launch *launch, const char *home) +{ + char *jrepath = realpath(home, NULL); + if (!jrepath) { + CMD_WARN("Could not resolve JRE path %s: %s", home, strerror(errno)); + return -1; + } + + launch->jrepath = jrepath; + return 0; +} + void l2_launch_free_contents(struct l2_launch *launch) { json_decref(launch->version); @@ -456,6 +498,57 @@ jobjectArray l2_launch__create_game_args(JNIEnv *env, char **game_args, size_t n return jarr; } +struct l2_launch__java_search_data { + char *out_fname; + +}; + +int l2_launch__java_search_ftw(const char *fname, const struct stat *sp, int flags, struct l2_ftw_data *data) +{ + L2_UNUSED(sp); + + char **opath = data->user; + if ((flags & L2_FTW_TYPEMASK) == L2_FTW_FILE && !strcmp(fname + data->baseoffset, "libjvm.so")) { + char *temp = strdup(fname); + if (!temp) { + CMD_ERROR("Failed to duplicate path name %s: %s", fname, strerror(errno)); + return -1; + } + + *opath = temp; + return 1; + } + + return 0; +} + +int l2_launch__find_jni(struct l2_launch *launch, char **jnifile) +{ + int res; + if (!launch->jrepath) { + CMD_INFO0("Downloading Mojang-provided JRE"); + res = l2_launch_init_runtime(launch); + if (res < 0) return -1; + else if (!res) { + CMD_WARN0("The JRE must be specified manually."); + return -1; + } + } + + char *ofile = NULL; + res = l2_launcher_ftw(launch->jrepath, 32, &l2_launch__java_search_ftw, &ofile); + if (res < 0) { + CMD_WARN("Error searching for JNI binary in %s", launch->jrepath); + return -1; + } else if (res == 0) { + CMD_WARN("libjvm.so not found in %s", launch->jrepath); + return -1; + } + + *jnifile = ofile; + return 0; +} + int l2_launch_jni(struct l2_launch *launch) { int res = 0; @@ -465,11 +558,21 @@ int l2_launch_jni(struct l2_launch *launch) return -1; } - if (l2_jni_init("/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/jre/lib/amd64/server/libjvm.so") < 0) { + char *jnipath = NULL; + if (l2_launch__find_jni(launch, &jnipath) < 0) { + CMD_ERROR0("JNI library could not be found automatically."); + return -1; + } + + if (l2_jni_init(jnipath) < 0) { + free(jnipath); CMD_ERROR0("Failed to initialize JNI"); return -1; } + free(jnipath); + jnipath = NULL; + JavaVMInitArgs args; jint jres; memset(&args, 0, sizeof(JavaVMInitArgs)); -- cgit v1.2.3-70-g09d2