From 1eb06b6b60436a511589cdb6cb66ef64c31ff0f4 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sun, 6 Mar 2022 18:22:28 -0500 Subject: [PATCH] Add Back ~/.minecraft-pi/mods & Fix Segmentation Fault With Media Layer Proxy --- launcher/src/bootstrap.c | 28 +++++++++++++++----- launcher/src/server/launcher.c | 8 ++++++ libreborn/include/libreborn/home.h | 10 +++++++ libreborn/include/libreborn/libreborn.h | 31 ++-------------------- libreborn/include/libreborn/patch.h | 30 +++++++++++++++++++++ media-layer/proxy/src/client/client.cpp | 1 + media-layer/proxy/src/common/common.c | 21 ++++++++------- media-layer/proxy/src/common/common.h | 1 + media-layer/proxy/src/server/server.cpp | 1 + mods/src/home/home.c | 35 ++----------------------- 10 files changed, 87 insertions(+), 79 deletions(-) create mode 100644 libreborn/include/libreborn/home.h create mode 100644 libreborn/include/libreborn/patch.h diff --git a/launcher/src/bootstrap.c b/launcher/src/bootstrap.c index dfc9b13..40a2d0a 100644 --- a/launcher/src/bootstrap.c +++ b/launcher/src/bootstrap.c @@ -181,13 +181,27 @@ void bootstrap(int argc, char *argv[]) { char *new_ld_preload = NULL; safe_asprintf(&new_ld_preload, "%s", get_env_safe("LD_PRELOAD")); - // Get Mods Folder - char *mods_folder = NULL; - safe_asprintf(&mods_folder, "%s/mods/", binary_directory); - // Load Mods From ./mods - load(&new_ld_preload, mods_folder); - // Free Mods Folder - free(mods_folder); + // Built-In Mods + { + // Get Mods Folder + char *mods_folder = NULL; + safe_asprintf(&mods_folder, "%s/mods/", binary_directory); + // Load Mods From ./mods + load(&new_ld_preload, mods_folder); + // Free Mods Folder + free(mods_folder); + } + + // ~/.minecraft-pi/mods + { + // Get Mods Folder + char *mods_folder = NULL; + safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME")); + // Load Mods From ./mods + load(&new_ld_preload, mods_folder); + // Free Mods Folder + free(mods_folder); + } // Set LD_PRELOAD set_and_print_env("LD_PRELOAD", new_ld_preload); diff --git a/launcher/src/server/launcher.c b/launcher/src/server/launcher.c index c3f0bf5..6933fec 100644 --- a/launcher/src/server/launcher.c +++ b/launcher/src/server/launcher.c @@ -1,6 +1,14 @@ +#include +#include + #include "../bootstrap.h" int main(int argc, char *argv[]) { + // Set Home To Current Directory, So World Data Is Stored There + char *launch_directory = getcwd(NULL, 0); + setenv("HOME", launch_directory, 1); + free(launch_directory); + // Bootstrap bootstrap(argc, argv); } diff --git a/libreborn/include/libreborn/home.h b/libreborn/include/libreborn/home.h new file mode 100644 index 0000000..65da96b --- /dev/null +++ b/libreborn/include/libreborn/home.h @@ -0,0 +1,10 @@ +#pragma once + +// Minecraft Pi Game Data Root +#ifndef MCPI_SERVER_MODE +// Store Game Data In "~/.minecraft-pi" Instead Of "~/.minecraft" To Avoid Conflicts +#define HOME_SUBDIRECTORY_FOR_GAME_DATA "/.minecraft-pi" +#else +// Store Game Data In $HOME Root (In Server Mode, $HOME Is Changed To The Launch Directory) +#define HOME_SUBDIRECTORY_FOR_GAME_DATA "" +#endif diff --git a/libreborn/include/libreborn/libreborn.h b/libreborn/include/libreborn/libreborn.h index 93771b2..fc969c1 100644 --- a/libreborn/include/libreborn/libreborn.h +++ b/libreborn/include/libreborn/libreborn.h @@ -1,36 +1,9 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include "log.h" #include "util.h" #include "string.h" #include "exec.h" #include "elf.h" - -#ifdef REBORN_HAS_COMPILED_CODE - -// Patching Functions - -void _overwrite_call(const char *file, int line, void *start, void *target); -#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target); - -void _overwrite_calls(const char *file, int line, void *start, void *target); -#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target); - -void _overwrite(const char *file, int line, void *start, void *target); -#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target); - -void _patch(const char *file, int line, void *start, unsigned char patch[4]); -#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch); - -void _patch_address(const char *file, int line, void *start, void *target); -#define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target); - -#endif // #ifdef __arm__ - -#ifdef __cplusplus -} -#endif +#include "home.h" +#include "patch.h" diff --git a/libreborn/include/libreborn/patch.h b/libreborn/include/libreborn/patch.h new file mode 100644 index 0000000..e21eded --- /dev/null +++ b/libreborn/include/libreborn/patch.h @@ -0,0 +1,30 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// Patching Functions + +#ifdef REBORN_HAS_COMPILED_CODE + +void _overwrite_call(const char *file, int line, void *start, void *target); +#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target); + +void _overwrite_calls(const char *file, int line, void *start, void *target); +#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target); + +void _overwrite(const char *file, int line, void *start, void *target); +#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target); + +void _patch(const char *file, int line, void *start, unsigned char patch[4]); +#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch); + +void _patch_address(const char *file, int line, void *start, void *target); +#define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target); + +#endif // #ifdef REBORN_HAS_COMPILED_CODE + +#ifdef __cplusplus +} +#endif diff --git a/media-layer/proxy/src/client/client.cpp b/media-layer/proxy/src/client/client.cpp index 41eb73c..50e07eb 100644 --- a/media-layer/proxy/src/client/client.cpp +++ b/media-layer/proxy/src/client/client.cpp @@ -32,6 +32,7 @@ static void sigusr1_handler(__attribute__((unused)) int sig) { void _check_proxy_state() { // Check Server State if (!parent_is_alive) { + void_write_cache(); // Parent Is Dead, No Reason To Send A Dead Process Data PROXY_ERR("%s", "Server Terminated"); } } diff --git a/media-layer/proxy/src/common/common.c b/media-layer/proxy/src/common/common.c index 2aca691..684befe 100644 --- a/media-layer/proxy/src/common/common.c +++ b/media-layer/proxy/src/common/common.c @@ -10,8 +10,6 @@ _check_proxy_state(); \ if (!is_connection_open()) { \ PROXY_ERR("%s", "Attempting To Access Closed Connection"); \ - } else { \ - _check_proxy_state(); \ } \ } void safe_read(void *buf, size_t len) { @@ -63,27 +61,30 @@ void safe_write(void *buf, size_t len) { } // Flush Write Cache void flush_write_cache() { - // Check Connection - if (!is_connection_open()) { - // Connection Closed - return; - } // Check Cache if (_write_cache == NULL || _write_cache_position < 1) { // Nothing To Write return; } - // Write + // Check Connection + if (!is_connection_open()) { + // Connection Closed + return; + } + // Write & Reset size_t to_write = _write_cache_position; + size_t old_write_cache_position = _write_cache_position; + _write_cache_position = 0; while (to_write > 0) { CHECK_CONNECTION(); - ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (_write_cache_position - to_write)), to_write); + ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (old_write_cache_position - to_write)), to_write); if (x == -1 && errno != EINTR) { PROXY_ERR("Failed Writing Data To Connection: %s", strerror(errno)); } to_write -= x; } - // Reset +} +void void_write_cache() { _write_cache_position = 0; } diff --git a/media-layer/proxy/src/common/common.h b/media-layer/proxy/src/common/common.h index 97a30ed..18e6728 100644 --- a/media-layer/proxy/src/common/common.h +++ b/media-layer/proxy/src/common/common.h @@ -29,6 +29,7 @@ extern "C" { __attribute__((visibility("internal"))) void safe_read(void *buf, size_t len); __attribute__((visibility("internal"))) void safe_write(void *buf, size_t len); __attribute__((visibility("internal"))) void flush_write_cache(); +__attribute__((visibility("internal"))) void void_write_cache(); // Read/Write 32-Bit Integers __attribute__((visibility("internal"))) uint32_t read_int(); diff --git a/media-layer/proxy/src/server/server.cpp b/media-layer/proxy/src/server/server.cpp index 27fd1fb..f84b68e 100644 --- a/media-layer/proxy/src/server/server.cpp +++ b/media-layer/proxy/src/server/server.cpp @@ -25,6 +25,7 @@ static void update_client_state(int is_alive, int status) { void _check_proxy_state() { // Check Client State if (!_client_is_alive) { + void_write_cache(); // Child Is Dead, No Reason To Send A Dead Process Data if (WIFEXITED(_client_status)) { PROXY_ERR("Client Terminated: Exit Code: %i", WEXITSTATUS(_client_status)); } else if (WIFSIGNALED(_client_status)) { diff --git a/mods/src/home/home.c b/mods/src/home/home.c index cc72a37..b08362c 100644 --- a/mods/src/home/home.c +++ b/mods/src/home/home.c @@ -6,43 +6,12 @@ #include "home.h" #include "../init/init.h" -// Minecraft Pi User Data Root -#ifndef MCPI_SERVER_MODE -// Store Game Data In "~/.minecraft-pi" Instead Of "~/.minecraft" To Avoid Conflicts -#define NEW_PATH "/.minecraft-pi" -#else -// Store Game Data In Launch Directory -#define NEW_PATH "" - -// Store Launch Directory -__attribute__((constructor)) static char *get_launch_directory() { - static char *launch_directory = NULL; - if (launch_directory == NULL) { - launch_directory = getcwd(NULL, 0); - } - return launch_directory; -} -__attribute__((destructor)) static void free_launch_directory() { - free(get_launch_directory()); -} - -// Pretend $HOME Is Launch Directory -HOOK(getenv, char *, (const char *name)) { - if (strcmp(name, "HOME") == 0) { - return get_launch_directory(); - } else { - ensure_getenv(); - return (*real_getenv)(name); - } -} -#endif - // Get MCPI Home Directory char *home_get() { static char *dir = NULL; // Load if (dir == NULL) { - safe_asprintf(&dir, "%s" NEW_PATH, getenv("HOME")); + safe_asprintf(&dir, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME")); } // Return return dir; @@ -55,7 +24,7 @@ __attribute__((destructor)) static void _free_home() { // Init void init_home() { // Store Data In ~/.minecraft-pi Instead Of ~/.minecraft - patch_address((void *) default_path, (void *) NEW_PATH); + patch_address((void *) default_path, (void *) HOME_SUBDIRECTORY_FOR_GAME_DATA); // Change Directory To Binary Directory Manually unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"