aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2021-12-27 15:24:28 -0800
committerTrumeet <yuuta@yuuta.moe>2021-12-27 15:24:28 -0800
commitfb84e0168c2f8be9f33af87547e961e4e8944828 (patch)
tree4aedc075e5a6c723e6113f2bb40d45745f9d9e45
parent5d004c12d05bf6aba067c194acc7f8ab5f0af62f (diff)
downloadminecraft-pacman-fb84e0168c2f8be9f33af87547e961e4e8944828.tar
minecraft-pacman-fb84e0168c2f8be9f33af87547e961e4e8944828.tar.gz
minecraft-pacman-fb84e0168c2f8be9f33af87547e961e4e8944828.tar.bz2
minecraft-pacman-fb84e0168c2f8be9f33af87547e961e4e8944828.zip
Initial Fabric support
-rw-r--r--.gitignore1
-rw-r--r--README.md12
-rw-r--r--fabric/.gitignore6
-rw-r--r--fabric/PKGBUILD31
l---------fabric/launcher.fabric.gen1
-rw-r--r--gen.c337
-rwxr-xr-xlauncher3
-rw-r--r--mc/PKGBUILD6
-rwxr-xr-xswitch5
9 files changed, 298 insertions, 104 deletions
diff --git a/.gitignore b/.gitignore
index 836d5cf..89b81b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
/launcher.gen
+/launcher.fabric.gen
PKGBUILD.gen
src/
pkg/
diff --git a/README.md b/README.md
index c1c6825..4651951 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,8 @@ This repository does not contain any launchers. Instead, it exposes some variabl
3. (Optional) Build and install the assets package: `cd assets; makepkg`
+4. (Optional) Build and install the fabric package: `cd fabric; makepkg`
+
Whenever you need to build a different Minecraft version, do the steps again (changing the arguments of `./switch` will cause it to generate new build files).
## Tested versions
@@ -28,9 +30,13 @@ Whenever you need to build a different Minecraft version, do the steps again (ch
Basic testing for 1.14, 1.15 and 1.16 (no assets)
-## TODO
+1.15 with Fabric
+
+## Fabric
-Fabric support
+After install the `minecraft-fabric-xxx` package, you will have Fabric jars in the same directory as Minecraft jars, and they will be added to the classpath (but not used). If you want to use Fabric, source the `launcher.fabric.gen` after sourcing `launcher.gen`. It will set necessary environment variables (e.g. `MAIN_CLASS`) for you.
+
+## TODO
Forge support
@@ -40,6 +46,8 @@ Assets folders cannot be shared across versions (i.e. you must have a dedicated
Library compatibility issues with version <= 1.12: Inconsistency detected by ld.so: dl-lookup.c: 105: check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!
+Compatibility with legacy versions that do not include `-cp` in their manifest.
+
## License
Thanks to my friends' help.
diff --git a/fabric/.gitignore b/fabric/.gitignore
new file mode 100644
index 0000000..10dc547
--- /dev/null
+++ b/fabric/.gitignore
@@ -0,0 +1,6 @@
+src/
+pkg/
+*.zst
+*.log
+*.jar
+*.xml
diff --git a/fabric/PKGBUILD b/fabric/PKGBUILD
new file mode 100644
index 0000000..d04dfc5
--- /dev/null
+++ b/fabric/PKGBUILD
@@ -0,0 +1,31 @@
+# Maintainer: YuutaW <YuutaW@ymc.moe>
+. ../PKGBUILD.gen
+pkgname=minecraft-fabric-${_MC_ID}
+pkgver=${_FABRIC//-/_}
+pkgrel=1
+epoch=
+pkgdesc="Fabric for Minecraft ${_MC_ID}"
+arch=(x86_64)
+url="https://fabricmc.net/"
+license=('custom')
+depends=("java-environment>=$_JAVA_VERSION" "minecraft-${_MC_ID}")
+makedepends=()
+optdepends=()
+install=
+source=(launcher.fabric.gen $_MC_FABRIC_JAR_URL)
+sha1sums=('SKIP' $_MC_FABRIC_JAR_SHA1)
+noextract=(launcher.fabric.gen $_MC_FABRIC_JAR)
+
+_dir=/usr/share/java/minecraft/${_MC_ID//-/_}/
+
+prepare() {
+ cd $srcdir
+}
+
+package() {
+ cd $srcdir
+ _dir="$pkgdir/$_dir"
+ mkdir -p $_dir
+ cp $_MC_FABRIC_JAR $_dir
+ cp launcher.fabric.gen $_dir/launcher.fabric.gen
+}
diff --git a/fabric/launcher.fabric.gen b/fabric/launcher.fabric.gen
new file mode 120000
index 0000000..f0b867b
--- /dev/null
+++ b/fabric/launcher.fabric.gen
@@ -0,0 +1 @@
+../launcher.fabric.gen \ No newline at end of file
diff --git a/gen.c b/gen.c
index 48f4141..7ea6b74 100644
--- a/gen.c
+++ b/gen.c
@@ -18,6 +18,7 @@
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <json-c/json.h>
+#include <assert.h>
enum source_type {
jar,
@@ -25,7 +26,8 @@ enum source_type {
extract_jar,
log4j,
asset,
- asset_index
+ asset_index,
+ fabric
};
struct source {
@@ -42,12 +44,15 @@ static char *out_pkgbuild = "PKGBUILD.gen";
static FILE *pkgbuild = NULL;
static char *out_launcher = "launcher.gen";
static FILE *launcher = NULL;
+static char *out_fabric_launcher = "launcher.fabric.gen";
static char *version = NULL;
static CURL *curl = NULL;
static json_object *json = NULL;
static json_tokener *tok = NULL;
static char *all_version_manifest_url = "https://launchermeta.mojang.com/mc/game/version_manifest_v2.json";
static char *version_manifest_url = NULL;
+static char *all_fabric_manifest_url = "https://meta.fabricmc.net/v2/versions/loader";
+static char *fabric_manifest_url = NULL;
static char *assets_url = NULL;
static void cleanup(void) {
@@ -71,9 +76,10 @@ static void cleanup(void) {
free(s);
s = s1;
}
+ if (version) free(version);
}
-static void get(const char *url) {
+static char get(const char *url, const char fail_not_found) {
/* The url may belong to the json. Use it first. */
curl_easy_setopt(curl, CURLOPT_URL, url);
if (json) {
@@ -86,6 +92,9 @@ static void get(const char *url) {
exit(1);
}
if (res) {
+ long http_code = 0;
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
+ if (!fail_not_found && (http_code == 400 || http_code == 404)) return 1;
cleanup();
errx(res, "Cannot GET %s: %s",
url,
@@ -97,6 +106,7 @@ static void get(const char *url) {
errx(1, "Cannot parse response JSON: "
"The stream ends without a full JSON.");
}
+ return 0;
}
static FILE *try_fopen(const char *path) {
@@ -133,7 +143,7 @@ static void src(const char *hash, const char *url, const enum source_type type)
errx(1, "URL %s is not valid.", url);
}
/* Remove leading / */
- id ++;
+ id++;
struct source *s = malloc(sizeof(struct source));
if (!s) {
cleanup();
@@ -171,26 +181,21 @@ static void src(const char *hash, const char *url, const enum source_type type)
source_fist = s;
}
-static char classpath_set = 0;
-static char libraries_set = 0;
-
static void append(FILE *stream, const char *key, const char *value) {
- if (!classpath_set &&
- !strcmp("JVM_ARGS", key) &&
- !strcmp("-cp", value)) {
- classpath_set = 1;
- }
- if (!libraries_set &&
- !strcmp("JVM_ARGS", key) &&
- !strncmp("-Djava.library.path", value, 19)) {
- libraries_set = 1;
- }
fprintf(stream, "%s=\"$%s %s\"\n",
key,
key,
value);
}
+static void arg(const char jvm, const char *value) {
+ if (strchr(value, ' ')) {
+ fprintf(stderr, "Warn: Refusing argument with space: %s\n", value);
+ return;
+ }
+ append(launcher, jvm ? (jvm == 2 ? "JVM_ARGS_X86" : "JVM_ARGS") : "MC_ARGS", value);
+}
+
static void set(FILE *stream, const char *key, const char *value) {
fprintf(stream, "%s=\"%s\"\n",
key,
@@ -215,7 +220,7 @@ static void parse_artifact(json_object *artifact, const enum source_type type) {
static char check_rules(json_object *rules) {
char allow = 0;
unsigned int rules_len = json_object_array_length(rules);
- for (unsigned int j = 0; j < rules_len; j ++) {
+ for (unsigned int j = 0; j < rules_len; j++) {
const json_object *rule = json_object_array_get_idx(rules, j);
json_object *obj2;
if (json_object_object_get_ex(rule, "os", &obj2)) {
@@ -225,7 +230,7 @@ static char check_rules(json_object *rules) {
continue;
}
if (json_object_object_get_ex(obj2, "arch", &obj3) &&
- !strcmp("x86", json_object_get_string(obj3))) {
+ !strcmp("x86", json_object_get_string(obj3))) {
allow = 2;
break;
}
@@ -246,7 +251,7 @@ static char check_rules(json_object *rules) {
}
static const char *fetch_version_manifest(void) {
- get(all_version_manifest_url);
+ get(all_version_manifest_url, 1);
json_object *obj;
if (!version) {
if (!json_object_object_get_ex(json, "latest", &obj)) {
@@ -257,14 +262,21 @@ static const char *fetch_version_manifest(void) {
cleanup();
errx(1, "Invalid version_manifest_v2.json: No release object.");
}
- version = (char *) json_object_get_string(obj);
+ const char *ver = json_object_get_string(obj);
+ unsigned int len = strlen(ver);
+ version = calloc(len + 1, sizeof(char));
+ if (!version) {
+ cleanup();
+ err(errno, "Cannot allocate memory");
+ }
+ memcpy(version, ver, len + 1);
}
if (!json_object_object_get_ex(json, "versions", &obj)) {
cleanup();
errx(1, "Invalid version_manifest_v2.json: No versions[] object.");
}
unsigned int len = json_object_array_length(obj);
- for (unsigned int i = 0; i < len; i ++) {
+ for (unsigned int i = 0; i < len; i++) {
const json_object *item = json_object_array_get_idx(obj, i);
json_object *obj1;
if (!json_object_object_get_ex(item, "id", &obj1)) {
@@ -282,6 +294,27 @@ static const char *fetch_version_manifest(void) {
errx(1, "Version %s is not found.", version);
}
+static const char *fetch_fabric_manifest(void) {
+ get(all_fabric_manifest_url, 1);
+ unsigned int len = json_object_array_length(json);
+ for (unsigned int i = 0; i < len; i++) {
+ const json_object *item = json_object_array_get_idx(json, i);
+ json_object *obj1;
+ if (!json_object_object_get_ex(item, "stable", &obj1)) {
+ cleanup();
+ errx(1, "Invalid fabric version json: no stable.");
+ }
+ if (!json_object_get_boolean(obj1)) continue;
+ if (!json_object_object_get_ex(item, "version", &obj1)) {
+ cleanup();
+ errx(1, "Fabric loader doesn't have the version object.");
+ }
+ return json_object_get_string(obj1);
+ }
+ cleanup();
+ errx(1, "No stable Fabric versions found.");
+}
+
static void parse_arguments(struct json_object *obj) {
json_object *args;
if (!json_object_object_get_ex(obj, "game", &args)) {
@@ -289,10 +322,10 @@ static void parse_arguments(struct json_object *obj) {
errx(1, "Invalid version.json: No game[] object.");
}
unsigned int args_len = json_object_array_length(args);
- for (unsigned int i = 0; i < args_len; i ++) {
+ for (unsigned int i = 0; i < args_len; i++) {
json_object *item = json_object_array_get_idx(args, i);
if (json_object_is_type(item, json_type_string)) {
- append(launcher, "MC_ARGS", json_object_get_string(item));
+ arg(0, json_object_get_string(item));
continue;
}
if (!json_object_is_type(item, json_type_object)) {
@@ -311,7 +344,7 @@ static void parse_arguments(struct json_object *obj) {
} else if (json_object_is_type(val, json_type_array)) {
fprintf(stderr, "Skipped unsupported game argument: ");
unsigned int len = json_object_array_length(val);
- for (unsigned int j = 0; j < len; j ++) {
+ for (unsigned int j = 0; j < len; j++) {
fprintf(stderr, "%s ",
json_object_get_string(
json_object_array_get_idx(val, j)
@@ -325,10 +358,10 @@ static void parse_arguments(struct json_object *obj) {
errx(1, "Invalid version.json: No jvm[] object.");
}
args_len = json_object_array_length(args);
- for (unsigned int i = 0; i < args_len; i ++) {
+ for (unsigned int i = 0; i < args_len; i++) {
json_object *item = json_object_array_get_idx(args, i);
if (json_object_is_type(item, json_type_string)) {
- append(launcher, "JVM_ARGS", json_object_get_string(item));
+ arg(1, json_object_get_string(item));
continue;
}
if (!json_object_is_type(item, json_type_object)) {
@@ -350,10 +383,10 @@ static void parse_arguments(struct json_object *obj) {
if (!rule) continue;
if (rule == 2) {
if (json_object_is_type(value, json_type_string)) {
- append(launcher, "JVM_ARGS_X86", json_object_get_string(value));
+ arg(2, json_object_get_string(value));
} else {
- for (unsigned int j = 0; j < value_len; j ++) {
- append(launcher, "JVM_ARGS_X86",
+ for (unsigned int j = 0; j < value_len; j++) {
+ arg(2,
json_object_get_string(
json_object_array_get_idx(value, j)
));
@@ -361,10 +394,10 @@ static void parse_arguments(struct json_object *obj) {
}
} else {
if (json_object_is_type(value, json_type_string)) {
- append(launcher, "JVM_ARGS", json_object_get_string(value));
+ arg(1, json_object_get_string(value));
} else {
- for (unsigned int j = 0; j < value_len; j ++) {
- append(launcher, "JVM_ARGS",
+ for (unsigned int j = 0; j < value_len; j++) {
+ arg(1,
json_object_get_string(
json_object_array_get_idx(value, j)
));
@@ -375,21 +408,93 @@ static void parse_arguments(struct json_object *obj) {
}
}
-static void fetch_version(const char *url) {
+static char *parse_maven(const char *name, const char *maven_repo) {
+ /* Download from Maven instead */
+ unsigned short seg = 0;
+ char *name_cpy = calloc(strlen(name) + 1, sizeof(char));
+ if (!name_cpy) {
+ cleanup();
+ err(errno, "Cannot allocate memory");
+ }
+ memcpy(name_cpy, name, strlen(name) + 1);
+ const unsigned int repo_len = strlen(maven_repo);
+ unsigned int artifact_len = 0;
+ const unsigned int len = repo_len + 1 /* / */ +
+ 2 * strlen(name) + 1 /* / before jar name */ + 4 /* .jar */ + 1;
+ char *url_jar = calloc(len, sizeof(char));
+ if (!url_jar) {
+ cleanup();
+ err(errno, "Cannot allocate memory");
+ }
+ unsigned int url_jar_len = 0;
+ unsigned int artifact_start = 0;
+ memcpy(url_jar, maven_repo, repo_len);
+ url_jar_len += repo_len;
+ url_jar[url_jar_len ++] = '/';
+ /* Highly inefficient code. */
+ for (char *p = strtok(name_cpy, ":"); p != NULL; p = strtok(NULL, ":")) {
+ switch (seg ++) {
+ case 0: {
+ unsigned int z = 0;
+ char c;
+ while ((c = p[z ++]) != '\0') {
+ if (c == '.') url_jar[url_jar_len ++] = '/';
+ else url_jar[url_jar_len ++] = c;
+ }
+ url_jar[url_jar_len ++] = '/';
+ break;
+ }
+ case 1:
+ artifact_len = strlen(p);
+ artifact_start = url_jar_len;
+ memcpy(&url_jar[url_jar_len], p, artifact_len);
+ url_jar_len += artifact_len;
+ url_jar[url_jar_len ++] = '/';
+ break;
+ case 2: {
+ unsigned int version_len = strlen(p);
+ memcpy(&url_jar[url_jar_len], p, version_len);
+ url_jar_len += version_len;
+ url_jar[url_jar_len ++] = '/';
+ memcpy(&url_jar[url_jar_len], &url_jar[artifact_start], artifact_len);
+ url_jar_len += artifact_len;
+ url_jar[url_jar_len ++] = '-';
+ memcpy(&url_jar[url_jar_len], p, version_len);
+ url_jar_len += version_len;
+ memcpy(&url_jar[url_jar_len], ".jar\0", 5);
+ url_jar_len += 5;
+ break;
+ }
+ default:
+ free(url_jar);
+ free(name_cpy);
+ errx(1, "Illegal maven name: %s", name);
+ }
+ }
+ free(name_cpy);
+ return url_jar;
+}
+
+static void fetch_version(const char *url, const char is_fabric) {
/* URL is no longer valid. */
- get(url);
+ if (get(url, is_fabric ? 0 : 1)) {
+ fprintf(stderr, "Warn: No Fabric available for this version.\n");
+ return;
+ }
json_object *obj;
if (!json_object_object_get_ex(json, "mainClass", &obj)) {
cleanup();
errx(1, "Invalid version.json: No mainClass object.");
}
set(launcher, "MAIN_CLASS", json_object_get_string(obj));
- if (!json_object_object_get_ex(json, "id", &obj)) {
- cleanup();
- errx(1, "Invalid version.json: No id object.");
+ if (!is_fabric) {
+ if (!json_object_object_get_ex(json, "id", &obj)) {
+ cleanup();
+ errx(1, "Invalid version.json: No id object.");
+ }
+ set(launcher, "ID", json_object_get_string(obj));
+ set(pkgbuild, "_MC_ID", json_object_get_string(obj));
}
- set(launcher, "ID", json_object_get_string(obj));
- set(pkgbuild, "_MC_ID", json_object_get_string(obj));
if (json_object_object_get_ex(json, "javaVersion", &obj)) {
if (!json_object_object_get_ex(obj, "majorVersion", &obj)) {
cleanup();
@@ -403,15 +508,25 @@ static void fetch_version(const char *url) {
errx(1, "Invalid version.json: No libraries[] object.");
}
unsigned int libs_len = json_object_array_length(obj);
- for (unsigned int i = 0; i < libs_len; i ++) {
+ for (unsigned int i = 0; i < libs_len; i++) {
const json_object *item = json_object_array_get_idx(obj, i);
json_object *obj1;
if (json_object_object_get_ex(item, "rules", &obj1)) {
if (!check_rules(obj1)) continue;
}
if (!json_object_object_get_ex(item, "downloads", &obj1)) {
- cleanup();
- errx(1, "Library doesn't have downloads object.");
+ json_object *maven;
+ if (!json_object_object_get_ex(item, "name", &obj1) ||
+ !json_object_object_get_ex(item, "url", &maven)) {
+ cleanup();
+ errx(1, "Library doesn't have downloads object.");
+ }
+ const char *name = json_object_get_string(obj1);
+ const char *maven_repo = json_object_get_string(maven);
+ char *maven_url = parse_maven(name, maven_repo);
+ src("SKIP", maven_url, is_fabric ? fabric : jar);
+ free(maven_url);
+ continue;
}
json_object *artifact;
json_object *natives;
@@ -420,7 +535,7 @@ static void fetch_version(const char *url) {
* It seems that if they both exist, there must be a standalone artifact before it.
*/
if (json_object_object_get_ex(item, "natives", &natives) &&
- json_object_object_get_ex(obj1, "classifiers", &classifiers)) {
+ json_object_object_get_ex(obj1, "classifiers", &classifiers)) {
if (!json_object_object_get_ex(natives, "linux", &obj1))
continue;
if (!json_object_object_get_ex(classifiers,
@@ -430,50 +545,53 @@ static void fetch_version(const char *url) {
parse_artifact(obj1, extract_jar);
} else if (json_object_object_get_ex(obj1, "artifact", &artifact)) {
parse_artifact(artifact,
- json_object_object_get_ex(item, "extract", &obj1) ? extract_jar
- : jar);
+ json_object_object_get_ex(item, "extract", &obj1) ? extract_jar
+ : jar);
} else {
cleanup();
errx(1, "Library doesn't have an artifact or natives and classifiers object.");
}
}
- if (!json_object_object_get_ex(json, "downloads", &obj)) {
- cleanup();
- errx(1, "Invalid version.json: No downloads object.");
- }
- if (!json_object_object_get_ex(obj, "client", &obj)) {
- cleanup();
- errx(1, "Invalid version.json: No client object.");
- }
- parse_artifact(obj, client);
- if (!json_object_object_get_ex(json, "assetIndex", &obj)) {
- cleanup();
- errx(1, "Invalid version.json: No assetIndex object.");
- }
- json_object *obj1;
- if (!json_object_object_get_ex(obj, "url", &obj1)) {
- cleanup();
- errx(1, "Invalid version.json: assetIndex does not have the url object.");
- }
- assets_url = (char *) json_object_get_string(obj1);
- if (!json_object_object_get_ex(obj, "sha1", &obj1)) {
- cleanup();
- errx(1, "Invalid version.json: assetIndex does not have the sha1 object.");
- }
- src(json_object_get_string(obj1), assets_url, asset_index);
- if (!json_object_object_get_ex(obj, "id", &obj1)) {
- cleanup();
- errx(1, "Invalid version.json: assetIndex does not have the id object.");
+ if (!is_fabric) {
+ if (!json_object_object_get_ex(json, "downloads", &obj)) {
+ cleanup();
+ errx(1, "Invalid version.json: No downloads object.");
+ }
+ if (!json_object_object_get_ex(obj, "client", &obj)) {
+ cleanup();
+ errx(1, "Invalid version.json: No client object.");
+ }
+ parse_artifact(obj, client);
+
+ if (!json_object_object_get_ex(json, "assetIndex", &obj)) {
+ cleanup();
+ errx(1, "Invalid version.json: No assetIndex object.");
+ }
+ json_object *obj1;
+ if (!json_object_object_get_ex(obj, "url", &obj1)) {
+ cleanup();
+ errx(1, "Invalid version.json: assetIndex does not have the url object.");
+ }
+ assets_url = (char *) json_object_get_string(obj1);
+ if (!json_object_object_get_ex(obj, "sha1", &obj1)) {
+ cleanup();
+ errx(1, "Invalid version.json: assetIndex does not have the sha1 object.");
+ }
+ src(json_object_get_string(obj1), assets_url, asset_index);
+ if (!json_object_object_get_ex(obj, "id", &obj1)) {
+ cleanup();
+ errx(1, "Invalid version.json: assetIndex does not have the id object.");
+ }
+ set(pkgbuild, "_ASSET_ID", json_object_get_string(obj1));
+ set(launcher, "ASSET_ID", json_object_get_string(obj1));
+ set(launcher, "assets_index_name", json_object_get_string(obj1));
}
- set(pkgbuild, "_ASSET_ID", json_object_get_string(obj1));
- set(launcher, "ASSET_ID", json_object_get_string(obj1));
- set(launcher, "assets_index_name", json_object_get_string(obj1));
if (json_object_object_get_ex(json, "arguments", &obj)) {
parse_arguments(obj);
} else if (json_object_object_get_ex(json, "minecraftArguments", &obj)) {
- append(launcher, "MC_ARGS", json_object_get_string(obj));
+ arg(0, json_object_get_string(obj));
} else {
cleanup();
errx(1, "Invalid version.json: No arguments or minecraftArguments object.");
@@ -481,12 +599,12 @@ static void fetch_version(const char *url) {
if (json_object_object_get_ex(json, "logging", &obj)) {
if (json_object_object_get_ex(obj, "client", &obj)) {
json_object *file;
- json_object *arg;
+ json_object *a;
if (!json_object_object_get_ex(obj, "file", &file)) {
cleanup();
errx(1, "Logging doesn't have the file object.");
}
- if (!json_object_object_get_ex(obj, "argument", &arg)) {
+ if (!json_object_object_get_ex(obj, "argument", &a)) {
cleanup();
errx(1, "Logging doesn't have the argument object.");
}
@@ -500,19 +618,19 @@ static void fetch_version(const char *url) {
parse_artifact(file, log4j);
/* Hope Mojang won't change this. */
if (strcmp("-Dlog4j.configurationFile=${path}",
- json_object_get_string(arg)) != 0) {
+ json_object_get_string(a)) != 0) {
fprintf(stderr,
"Unsupported Log4J Configuration: %s",
- (char *) json_object_get_string(arg));
+ (char *) json_object_get_string(a));
} else {
- append(launcher, "JVM_ARGS", "-Dlog4j.configurationFile=LOG4J_XML_PATH");
+ arg(1, "-Dlog4j.configurationFile=LOG4J_XML_PATH");
}
}
}
}
static void fetch_assets(void) {
- get(assets_url);
+ get(assets_url, 1);
json_object *obj;
if (!json_object_object_get_ex(json, "objects", &obj)) {
cleanup();
@@ -570,7 +688,7 @@ static void out(const char *tag, enum source_type type) {
int main(int argc, char **argv) {
int opt;
- while ((opt = getopt(argc, argv, "o:O:v:m:M:")) != -1) {
+ while ((opt = getopt(argc, argv, "o:O:v:m:M:f:F:g:")) != -1) {
switch (opt) {
case 'o':
out_pkgbuild = optarg;
@@ -578,20 +696,37 @@ int main(int argc, char **argv) {
case 'O':
out_launcher = optarg;
break;
- case 'v':
- version = optarg;
+ case 'v': {
+ unsigned int len = strlen(optarg);
+ version = calloc(len + 1, sizeof(char));
+ if (!version) {
+ cleanup();
+ err(errno, "Cannot allocate memory");
+ }
+ memcpy(version, optarg, len + 1);
break;
+ }
case 'm':
version_manifest_url = optarg;
break;
case 'M':
all_version_manifest_url = optarg;
break;
+ case 'f':
+ fabric_manifest_url = optarg;
+ break;
+ case 'F':
+ all_fabric_manifest_url = optarg;
+ break;
+ case 'g':
+ out_fabric_launcher = optarg;
+ break;
default:
- errx(EX_USAGE, "-o %s -O %s -v %s",
+ errx(EX_USAGE, "-o %s -O %s -v %s -g %s",
out_pkgbuild,
out_launcher,
- version);
+ version,
+ out_fabric_launcher);
}
}
pkgbuild = try_fopen(out_pkgbuild);
@@ -607,29 +742,37 @@ int main(int argc, char **argv) {
cleanup();
errx(1, "Cannot initialize libcurl.");
}
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
tok = json_tokener_new();
if (!tok) {
cleanup();
errx(1, "Cannot initialize JSON tok.");
}
- fetch_version(version_manifest_url == NULL ? fetch_version_manifest() : version_manifest_url);
+ fetch_version(version_manifest_url == NULL ? fetch_version_manifest() : version_manifest_url, 0);
if (assets_url) fetch_assets();
-
out("CLIENT", client);
out("JAR", jar);
out("EXTRACT_JAR", extract_jar);
out("ASSET", asset);
out("LOG4J", log4j);
out("ASSET_INDEX", asset_index);
- if (!classpath_set) {
- /* Just for compatibility for old versions. */
- append(launcher, "JVM_ARGS", "-cp ${classpath}");
- }
- if (!libraries_set) {
- /* Just for compatibility for old versions. */
- append(launcher, "JVM_ARGS", "-Djava.library.path=${natives_directory}");
- }
+ fclose(launcher);
+
+ launcher = try_fopen(out_fabric_launcher);
+ char fabric_built_url[256];
+ if (!fabric_manifest_url) {
+ const char *ver = fetch_fabric_manifest();
+ set(pkgbuild, "_FABRIC", ver);
+ set(launcher, "FABRIC", ver);
+ sprintf(fabric_built_url,
+ "https://meta.fabricmc.net/v2/versions/loader/%s/%s/profile/json",
+ version,
+ ver);
+ fabric_manifest_url = fabric_built_url;
+ }
+ fetch_version(fabric_manifest_url, 1);
+ out("FABRIC_JAR", fabric);
cleanup();
return 0;
diff --git a/launcher b/launcher
index 255f6b3..6451b2a 100755
--- a/launcher
+++ b/launcher
@@ -22,6 +22,9 @@ export version_type=release
export assets_root=$game_directory/assets/$VERSION
source /usr/share/java/minecraft/$VERSION/launcher.gen
+if test -e /usr/share/java/minecraft/$VERSION/launcher.fabric.gen; then
+ source /usr/share/java/minecraft/$VERSION/launcher.fabric.gen
+fi
mkdir -p $assets_root
mkdir -p $assets_root/skin
diff --git a/mc/PKGBUILD b/mc/PKGBUILD
index e300a5e..9cbeeab 100644
--- a/mc/PKGBUILD
+++ b/mc/PKGBUILD
@@ -23,11 +23,7 @@ _dir=/usr/share/java/minecraft/$pkgver/
prepare() {
cd $srcdir
echo "natives_directory=\"${_dir}native/\"" > launcher.gen.add
- printf "classpath=\"" >> launcher.gen.add
- for jar in `echo $_MC_JAR`; do
- printf "%s/%s:" $_dir $jar >> launcher.gen.add
- done
- echo "$_dir/${_MC_ID}.jar\"" >> launcher.gen.add
+ echo "classpath=\$(find $_dir -name '*.jar' | tr '\n' ':')" >> launcher.gen.add
sed -e "s/LOG4J_XML_PATH/\/usr\/share\/java\/minecraft\/$pkgver\/$_LOG4J_FILE/" $srcdir/launcher.gen > launcher.gen.mod
diff --git a/switch b/switch
index 41fa57b..8c6d833 100755
--- a/switch
+++ b/switch
@@ -1,6 +1,11 @@
#!/bin/sh
+set -e
if test -z "$1"; then
echo "Usage: switch <Minecraft version>"
fi
cc -D_POSIX_C_SOURCE=200809L -std=c99 -ljson-c -lcurl -o gen gen.c
./gen -v "$1"
+#FABRIC_VERSION=$(curl -s "https://meta.fabricmc.net/v2/versions/loader" | jq -r ".[0].version")
+#./gen -m "https://meta.fabricmc.net/v2/versions/loader/$1/$FABRIC_VERSION/profile/json" -c -o PKGBUILD.fabric.gen -O launcher.fabric.gen
+#echo "_FABRIC_ID=\"$FABRIC_VERSION\"" >> PKGBUILD.fabric.gen
+#sed -i "/^ID.*$/d" launcher.fabric.gen