diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd-version.c | 7 | ||||
| -rw-r--r-- | src/l2su.h | 1 | ||||
| -rw-r--r-- | src/launch.c | 105 | ||||
| -rw-r--r-- | src/launch.h | 4 | ||||
| -rw-r--r-- | src/launcherutil.c | 1 | ||||
| -rw-r--r-- | src/runtime.c | 11 | ||||
| -rw-r--r-- | src/runtime.h | 2 |
7 files changed, 124 insertions, 7 deletions
diff --git a/src/cmd-version.c b/src/cmd-version.c index fc9b7a8..5796a72 100644 --- a/src/cmd-version.c +++ b/src/cmd-version.c @@ -45,10 +45,15 @@ unsigned cmd_version_list_local(struct l2_context_node *ctx, char **args) json_dumpf(manifest, stdout, JSON_INDENT(4)); putchar('\n'); - if (l2_runtime_install_component(manifest, "jre-legacy") < 0) { + char *jrepath = NULL; + + if (l2_runtime_install_component(manifest, "jre-legacy", &jrepath) < 0) { CMD_FATAL0("Failed to install component"); } + CMD_DEBUG("JRE path: %s", jrepath); + + free(jrepath); json_decref(manifest); return CMD_RESULT_SUCCESS; @@ -52,6 +52,7 @@ int l2_launcher_rm_tree(const char *path, int nfds); struct l2_ftw_data { int depth; int reloffset; + int baseoffset; void *user; }; 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 <stdlib.h> #include <stdarg.h> @@ -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)); diff --git a/src/launch.h b/src/launch.h index e4b634c..598a152 100644 --- a/src/launch.h +++ b/src/launch.h @@ -24,6 +24,7 @@ struct l2_launch { char *natives; char *jarpath; + char *jrepath; char *main_class; char *classpath; @@ -36,6 +37,9 @@ struct l2_launch { }; int l2_launch_init(struct l2_launch *launch, const char *vername, struct l2_instance *inst); +int l2_launch_init_runtime(struct l2_launch *launch); /* returns 1 if good, 0 if no java version specified */ +int l2_launch_init_runtime_manual(struct l2_launch *launch, const char *home); + int l2_launch_init_substitutor(struct l2_launch *launch); int l2_launch_init_args(struct l2_launch *launch); int l2_launch_jni(struct l2_launch *launch); diff --git a/src/launcherutil.c b/src/launcherutil.c index 070290d..4a866f5 100644 --- a/src/launcherutil.c +++ b/src/launcherutil.c @@ -603,6 +603,7 @@ int l2_launcher__ftw_internal(char **path, int depth, l2_ftw_proc_t *proc, struc flags |= L2_FTW_SYMLINK; } + ftw->user.baseoffset = (int)pathlen + 1; if ((res = (*proc)(*path, &st, flags, (struct l2_ftw_data *)ftw))) { CMD_DEBUG("myftw: user aborted %s: %d", *path, res); ftw->abort = 1; diff --git a/src/runtime.c b/src/runtime.c index b811519..f40d97d 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -366,7 +366,7 @@ int l2_runtime__check_runtime_ftw(const char *fpath, const struct stat *sb, int int l2_runtime__ensure_runtime_files(const char *basepath, json_t *jfiles); -int l2_runtime_install_component(json_t *manifest, const char *component) +int l2_runtime_install_component(json_t *manifest, const char *component, char **ojrepath) { json_t *jrtcomps; if (json_unpack(manifest, "{s:{s:o}}", L2SU_JRE_ARCH, component, &jrtcomps) < 0) { @@ -407,9 +407,10 @@ int l2_runtime_install_component(json_t *manifest, const char *component) } } - char *jrepath; - size_t jrepathlen; - L2_ASPRINTF(jrepath, jrepathlen, "%s/runtime/%s/%s", l2_state.paths.data, L2SU_JRE_ARCH, component); + char *jrepath = l2_launcher_sprintf_alloc("%s/runtime/%s/%s", l2_state.paths.data, L2SU_JRE_ARCH, component); + if (!jrepath) { + goto cleanup; + } errno = 0; if (l2_launcher_mkdir_parents(jrepath) < 0) { @@ -435,10 +436,12 @@ int l2_runtime_install_component(json_t *manifest, const char *component) goto cleanup; } + *ojrepath = jrepath; json_decref(jcompmanifest); return 0; cleanup: + free(jrepath); if (jcompmanifest) json_decref(jcompmanifest); return -1; } diff --git a/src/runtime.h b/src/runtime.h index bf2e523..1250a1a 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -4,6 +4,6 @@ #include <jansson.h> int l2_runtime_load_manifest(json_t **manifest); -int l2_runtime_install_component(json_t *manifest, const char *component); +int l2_runtime_install_component(json_t *manifest, const char *component, char **ojrepath); #endif /* include guard */ |
