From 73afa13af4a16d8dc1640fec4385db9a8dec4e77 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Fri, 2 Oct 2020 18:43:43 -0400 Subject: [PATCH] Load Mods From ~/.minecraft-pi; Prompt User For Custom Username On Startup --- core/src/launcher.c | 95 +++++++++++-------- debian/usr/bin/minecraft-pi | 2 + .../usr/share/minecraft-pi/docker-compose.yml | 1 + mods/src/extra.c | 15 +++ 4 files changed, 76 insertions(+), 37 deletions(-) diff --git a/core/src/launcher.c b/core/src/launcher.c index d1ff6f6..58d6626 100644 --- a/core/src/launcher.c +++ b/core/src/launcher.c @@ -19,8 +19,6 @@ static int ends_with(const char *s, const char *t) { return strcmp(s + slen - tlen, t) == 0; } -#define MODS_FOLDER "./mods/" - static void set_and_print_env(char *name, char *value) { int length = strlen(value); if (value[length - 1] == ':') { @@ -36,54 +34,77 @@ static char *get_env_safe(const char *name) { return ret != NULL ? ret : ""; } +static void load(char **ld_preload, char *folder) { + int folder_name_length = strlen(folder); + while (1) { + DIR *dp = opendir(folder); + if (dp != NULL) { + struct dirent *entry = NULL; + errno = 0; + while (1) { + entry = readdir(dp); + if (entry != NULL) { + if (starts_with(entry->d_name, "lib") && ends_with(entry->d_name, ".so")) { + int name_length = strlen(entry->d_name); + int total_length = folder_name_length + name_length; + char name[total_length + 1]; + + for (int i = 0; i < folder_name_length; i++) { + name[i] = folder[i]; + } + for (int i = 0; i < name_length; i++) { + name[folder_name_length + i] = entry->d_name[i]; + } + + name[total_length] = '\0'; + + asprintf(ld_preload, "%s:%s", name, *ld_preload); + } + } else if (errno != 0) { + fprintf(stderr, "Error Reading Directory: %s\n", strerror(errno)); + exit(1); + } else { + break; + } + } + closedir(dp); + return; + } else if (errno == ENOENT) { + char *cmd = NULL; + asprintf(&cmd, "mkdir -p %s", folder); + int ret = system(cmd); + if (ret != 0) { + exit(ret); + } + } else { + fprintf(stderr, "Error Opening Directory: %s\n", strerror(errno)); + exit(1); + } + } +} + int main(__attribute__((unused)) int argc, char *argv[]) { fprintf(stderr, "Configuring Game...\n"); char *ld_path = NULL; + char *cwd = getcwd(NULL, 0); asprintf(&ld_path, "%s:/usr/arm-linux-gnueabihf/lib:%s", cwd, get_env_safe("LD_LIBRARY_PATH")); free(cwd); + set_and_print_env("LD_LIBRARY_PATH", ld_path); free(ld_path); - + char *ld_preload = NULL; asprintf(&ld_preload, "%s", get_env_safe("LD_PRELOAD")); - int folder_name_length = strlen(MODS_FOLDER); - DIR *dp = opendir(MODS_FOLDER); - if (dp != NULL) { - struct dirent *entry = NULL; - errno = 0; - while (1) { - entry = readdir(dp); - if (entry != NULL) { - if (starts_with(entry->d_name, "lib") && ends_with(entry->d_name, ".so")) { - int name_length = strlen(entry->d_name); - int total_length = folder_name_length + name_length; - char name[total_length + 1]; - for (int i = 0; i < folder_name_length; i++) { - name[i] = MODS_FOLDER[i]; - } - for (int i = 0; i < name_length; i++) { - name[folder_name_length + i] = entry->d_name[i]; - } - - name[total_length] = '\0'; + load(&ld_preload, "./mods/"); + + char *home_mods = NULL; + asprintf(&home_mods, "%s/.minecraft/mods/", getenv("HOME")); + load(&ld_preload, home_mods); + free(home_mods); - asprintf(&ld_preload, "%s:%s", name, ld_preload); - } - } else if (errno != 0) { - fprintf(stderr, "Error Reading Directory: %s\n", strerror(errno)); - exit(1); - } else { - break; - } - } - } else { - fprintf(stderr, "Error Opening Directory: %s\n", strerror(errno)); - exit(1); - } - closedir(dp); set_and_print_env("LD_PRELOAD", ld_preload); free(ld_preload); diff --git a/debian/usr/bin/minecraft-pi b/debian/usr/bin/minecraft-pi index ebdaa91..f8c975f 100755 --- a/debian/usr/bin/minecraft-pi +++ b/debian/usr/bin/minecraft-pi @@ -5,8 +5,10 @@ set -e # Ensure Features Are Selected if [ -z "${MCPI_SUBSHELL}" ]; then MCPI_FEATURES="$(zenity --class minecraft-pi --list --checklist --column 'Enabled' --column 'Feature' FALSE 'Touch GUI' FALSE 'Survival Mode' FALSE 'Fix Bow & Arrow' FALSE 'Fix Attacking' FALSE 'Mob Spawning' FALSE 'Show Clouds')" + MCPI_USERNAME="$(zenity --class minecraft-pi --entry --text 'Minecraft Username:' --entry-text 'StevePi')" fi export MCPI_FEATURES +export MCPI_USERNAME # Start VirGL virgl_test_server & diff --git a/debian/usr/share/minecraft-pi/docker-compose.yml b/debian/usr/share/minecraft-pi/docker-compose.yml index f51e653..4732da7 100644 --- a/debian/usr/share/minecraft-pi/docker-compose.yml +++ b/debian/usr/share/minecraft-pi/docker-compose.yml @@ -10,3 +10,4 @@ services: environment: - 'DISPLAY=unix${DISPLAY}' - 'MCPI_FEATURES=${MCPI_FEATURES}' + - 'MCPI_USERNAME=${MCPI_USERNAME}' diff --git a/mods/src/extra.c b/mods/src/extra.c index a5bf947..7ab35e1 100644 --- a/mods/src/extra.c +++ b/mods/src/extra.c @@ -118,6 +118,14 @@ static void setIsCreativeMode_injection(unsigned char *this, int32_t new_game_mo revert_overwrite((void *) setIsCreativeMode, setIsCreativeMode_original); } +static char *get_username() { + char *username = getenv("MCPI_USERNAME"); + if (username == NULL) { + username = "StevePi"; + } + return username; +} + __attribute__((constructor)) static void init() { if (has_feature("Touch GUI")) { // Use Touch UI @@ -174,4 +182,11 @@ __attribute__((constructor)) static void init() { // Allow Connecting To Non-Pi Servers unsigned char patch_data_9[4] = {0x0f, 0x00, 0x00, 0xea}; patch((void *) 0x6dc70, patch_data_9); + + // Change Username + const char *username = get_username(); + uint32_t username_addr = (uint32_t) username; + fprintf(stderr, "0x%08x", username_addr); + unsigned char username_patch[4] = {username_addr & 0xff, (username_addr >> 8) & 0xff, (username_addr >> 16) & 0xff, (username_addr >> 24) & 0xff}; + patch((void *) 0x18fd4, username_patch); }