aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cmd-version.c7
-rw-r--r--src/l2su.h1
-rw-r--r--src/launch.c105
-rw-r--r--src/launch.h4
-rw-r--r--src/launcherutil.c1
-rw-r--r--src/runtime.c11
-rw-r--r--src/runtime.h2
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;
diff --git a/src/l2su.h b/src/l2su.h
index 5813c66..4353266 100644
--- a/src/l2su.h
+++ b/src/l2su.h
@@ -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 */