From 4d54a9d28cf987beded546e98a6c4168a9c65274 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sun, 12 May 2024 03:19:01 -0400 Subject: [PATCH] Refactor Launcher --- cmake/options/extra-options.cmake | 3 + dependencies/qemu/CMakeLists.txt | 2 +- launcher/CMakeLists.txt | 15 +- launcher/src/bootstrap.c | 361 ------------------ launcher/src/bootstrap.cpp | 226 +++++++++++ launcher/src/bootstrap.h | 15 +- launcher/src/client/cache.cpp | 2 +- .../{launcher.cpp => configuration.cpp} | 172 ++++----- launcher/src/client/configuration.h | 23 ++ launcher/src/client/launcher.h | 12 - launcher/src/crash-report.c | 8 +- launcher/src/main.cpp | 154 ++++++++ launcher/src/mods.c | 110 ------ launcher/src/mods.cpp | 86 +++++ launcher/src/options/option-list.h | 12 + launcher/src/options/parser.cpp | 38 ++ launcher/src/options/parser.h | 10 + launcher/src/sdk.c | 67 ---- launcher/src/sdk.cpp | 59 +++ launcher/src/server/launcher.c | 19 - libreborn/include/libreborn/config.h.in | 1 + libreborn/include/libreborn/exec.h | 5 +- libreborn/include/libreborn/log.h | 1 + libreborn/src/util/exec.c | 8 +- libreborn/src/util/log.c | 2 +- media-layer/trampoline/src/GLESv1_CM.c | 98 ++--- media-layer/trampoline/src/media-layer-core.c | 34 +- mods/include/mods/init/init.h | 4 +- mods/src/benchmark/benchmark.cpp | 12 +- mods/src/init/init.cpp | 7 +- mods/src/options/info.cpp | 2 +- mods/src/server/server.cpp | 12 +- 32 files changed, 784 insertions(+), 796 deletions(-) delete mode 100644 launcher/src/bootstrap.c create mode 100644 launcher/src/bootstrap.cpp rename launcher/src/client/{launcher.cpp => configuration.cpp} (61%) create mode 100644 launcher/src/client/configuration.h delete mode 100644 launcher/src/client/launcher.h create mode 100644 launcher/src/main.cpp delete mode 100644 launcher/src/mods.c create mode 100644 launcher/src/mods.cpp create mode 100644 launcher/src/options/option-list.h create mode 100644 launcher/src/options/parser.cpp create mode 100644 launcher/src/options/parser.h delete mode 100644 launcher/src/sdk.c create mode 100644 launcher/src/sdk.cpp delete mode 100644 launcher/src/server/launcher.c diff --git a/cmake/options/extra-options.cmake b/cmake/options/extra-options.cmake index 75e622f1..08e9015d 100644 --- a/cmake/options/extra-options.cmake +++ b/cmake/options/extra-options.cmake @@ -77,3 +77,6 @@ mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}") # Skin Server mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data") + +# Discord Invite +mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779") \ No newline at end of file diff --git a/dependencies/qemu/CMakeLists.txt b/dependencies/qemu/CMakeLists.txt index 891a5b17..6ba096d6 100644 --- a/dependencies/qemu/CMakeLists.txt +++ b/dependencies/qemu/CMakeLists.txt @@ -30,7 +30,7 @@ ExternalProject_Add(qemu "--cross-prefix=" "--cc=${CMAKE_C_COMPILER}" "--cxx=${CMAKE_CXX_COMPILER}" - "--extra-ldflags=-ldl" + "--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags" "--disable-debug-info" "--target-list=arm-linux-user" "--without-default-features" diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index f0e92a9c..de635834 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -2,19 +2,19 @@ project(launcher) # Launcher add_executable(launcher - src/bootstrap.c + src/bootstrap.cpp src/patchelf.cpp src/util.c src/crash-report.c - src/sdk.c - src/mods.c + src/sdk.cpp + src/mods.cpp + src/options/parser.cpp + src/main.cpp ) -if(MCPI_SERVER_MODE) - target_sources(launcher PRIVATE src/server/launcher.c) -else() +if(NOT MCPI_SERVER_MODE) embed_resource(launcher src/client/available-feature-flags) target_sources(launcher PRIVATE - src/client/launcher.cpp + src/client/configuration.cpp src/client/cache.cpp src/client/available-feature-flags # Show In IDE ) @@ -22,6 +22,7 @@ endif() target_link_libraries(launcher reborn-util LIB_LIEF) # RPath set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native") +target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags") # Install install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}") diff --git a/launcher/src/bootstrap.c b/launcher/src/bootstrap.c deleted file mode 100644 index 000289e3..00000000 --- a/launcher/src/bootstrap.c +++ /dev/null @@ -1,361 +0,0 @@ -#define _FILE_OFFSET_BITS 64 - -#include - -#include "util.h" -#include "bootstrap.h" -#include "patchelf.h" -#include "crash-report.h" - -#define MCPI_BINARY "minecraft-pi" -#define QEMU_BINARY "qemu-arm" - -#define REQUIRED_PAGE_SIZE 4096 -#define _STR(x) #x -#define STR(x) _STR(x) - -// Exit Handler -static void exit_handler(__attribute__((unused)) int signal_id) { - // Pass Signal To Child - murder_children(); - while (wait(NULL) > 0) {} - _exit(EXIT_SUCCESS); -} - -// Debug Information -static void run_debug_command(const char *const command[], const char *prefix) { - int status = 0; - char *output = run_command(command, &status, NULL); - if (output != NULL) { - // Remove Newline - size_t length = strlen(output); - if (length > 0 && output[length - 1] == '\n') { - output[length - 1] = '\0'; - } - - // Print - DEBUG("%s: %s", prefix, output); - free(output); - } - if (!is_exit_status_success(status)) { - ERR("Unable To Gather Debug Information"); - } -} -static void print_debug_information() { - // System Information - const char *const command[] = {"uname", "-a", NULL}; - run_debug_command(command, "System Information"); - - // Version - DEBUG("Reborn Version: v%s", MCPI_VERSION); - - // Architecture - const char *arch = "Unknown"; -#ifdef __x86_64__ - arch = "AMD64"; -#elif defined(__aarch64__) - arch = "ARM64"; -#elif defined(__arm__) - arch = "ARM32"; -#endif - DEBUG("Reborn Target Architecture: %s", arch); -} - -// Pre-Bootstrap -void pre_bootstrap(int argc, char *argv[]) { - // Set Debug Tag - reborn_debug_tag = "(Launcher) "; - - // Disable stdout Buffering - setvbuf(stdout, NULL, _IONBF, 0); - - // Print Version - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) { - // Print - printf("Reborn v%s\n", MCPI_VERSION); - fflush(stdout); - exit(EXIT_SUCCESS); - } - } - - // Setup Logging - setup_log_file(); - - // --debug - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--debug") == 0) { - set_and_print_env("MCPI_DEBUG", "1"); - break; - } - } - - // Set Default Native Component Environment -#define set_variable_default(name) set_and_print_env("MCPI_NATIVE_" name, getenv(name)); - for_each_special_environmental_variable(set_variable_default); - - // GTK Dark Mode -#ifndef MCPI_SERVER_MODE - set_and_print_env("GTK_THEME", "Adwaita:dark"); -#endif - - // Configure PATH - { - // Get Binary Directory - char *binary_directory = get_binary_directory(); - - // Add Library Directory - char *new_path = NULL; - safe_asprintf(&new_path, "%s/bin", binary_directory); - // Add Existing PATH - { - char *value = getenv("PATH"); - if (value != NULL && strlen(value) > 0) { - string_append(&new_path, ":%s", value); - } - } - // Set And Free - set_and_print_env("PATH", new_path); - free(new_path); - - // Free Binary Directory - free(binary_directory); - } - - // --copy-sdk - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--copy-sdk") == 0) { - char *binary_directory = get_binary_directory(); - copy_sdk(binary_directory, 0); - free(binary_directory); - fflush(stdout); - exit(EXIT_SUCCESS); - } - } - - // Setup Crash Reports - setup_crash_report(); - - // AppImage -#ifdef MCPI_IS_APPIMAGE_BUILD - { - char *owd = getenv("OWD"); - if (owd != NULL && chdir(owd) != 0) { - ERR("AppImage: Unable To Fix Current Directory: %s", strerror(errno)); - } - } -#endif - - // Install Signal Handlers - struct sigaction act_sigint; - memset((void *) &act_sigint, 0, sizeof (struct sigaction)); - act_sigint.sa_flags = SA_RESTART; - act_sigint.sa_handler = &exit_handler; - sigaction(SIGINT, &act_sigint, NULL); - struct sigaction act_sigterm; - memset((void *) &act_sigterm, 0, sizeof (struct sigaction)); - act_sigterm.sa_flags = SA_RESTART; - act_sigterm.sa_handler = &exit_handler; - sigaction(SIGTERM, &act_sigterm, NULL); - - // Check Page Size (Not Needed When Using QEMU) -#ifndef MCPI_USE_QEMU - long page_size = sysconf(_SC_PAGESIZE); - if (page_size != REQUIRED_PAGE_SIZE) { - ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size); - } -#endif - - // Debug Information - print_debug_information(); -} - -// Bootstrap -void bootstrap(int argc, char *argv[]) { - INFO("Configuring Game..."); - - // Get Binary Directory - char *binary_directory = get_binary_directory(); - DEBUG("Binary Directory: %s", binary_directory); - - // Copy SDK - copy_sdk(binary_directory, 1); - - // Set MCPI_REBORN_ASSETS_PATH - { - char *assets_path = realpath("/proc/self/exe", NULL); - ALLOC_CHECK(assets_path); - chop_last_component(&assets_path); - string_append(&assets_path, "/data"); - set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path); - free(assets_path); - } - - // Resolve Binary Path & Set MCPI_DIRECTORY - char *resolved_path = NULL; - { - // Log - DEBUG("Resolving File Paths..."); - - // Resolve Full Binary Path - char *full_path = NULL; - safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory); - resolved_path = realpath(full_path, NULL); - ALLOC_CHECK(resolved_path); - free(full_path); - } - - // Fix MCPI Dependencies - char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX"; - { - // Log - DEBUG("Patching ELF Dependencies..."); - - // Find Linker - char *linker = NULL; - // Select Linker -#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN - // Use ARM Sysroot Linker - safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory); -#else - // Use Current Linker - linker = patch_get_interpreter(); -#endif - - // Patch - patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker); - - // Free Linker Path - if (linker != NULL) { - free(linker); - } - - // Verify - if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) { - IMPOSSIBLE(); - } - } - - // Set MCPI_VANILLA_ASSETS_PATH - { - char *assets_path = strdup(resolved_path); - ALLOC_CHECK(assets_path); - chop_last_component(&assets_path); - string_append(&assets_path, "/data"); - set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path); - free(assets_path); - } - - // Free Resolved Path - free(resolved_path); - - // Configure Library Search Path - { - // Log - DEBUG("Setting Linker Search Paths..."); - - // Prepare - char *transitive_ld_path = NULL; - char *mcpi_ld_path = NULL; - - // Library Search Path For Native Components - { - // Add Native Library Directory - safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory); - - // Add Host LD_LIBRARY_PATH - { - char *value = getenv("LD_LIBRARY_PATH"); - if (value != NULL && strlen(value) > 0) { - string_append(&transitive_ld_path, ":%s", value); - } - } - - // Set - set_and_print_env("MCPI_NATIVE_LD_LIBRARY_PATH", transitive_ld_path); - free(transitive_ld_path); - } - - // Library Search Path For ARM Components - { - // Add ARM Library Directory - safe_asprintf(&mcpi_ld_path, "%s/lib/arm", binary_directory); - - // Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System) -#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN - string_append(&mcpi_ld_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory); -#endif - - // Add Host LD_LIBRARY_PATH - { - char *value = getenv("LD_LIBRARY_PATH"); - if (value != NULL && strlen(value) > 0) { - string_append(&mcpi_ld_path, ":%s", value); - } - } - - // Set - set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path); - free(mcpi_ld_path); - } - } - - // Configure Preloaded Objects - { - // Log - DEBUG("Locating Mods..."); - - // Native Components - char *host_ld_preload = getenv("LD_PRELOAD"); - set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload); - - // ARM Components - bootstrap_mods(binary_directory); - } - - // Free Binary Directory - free(binary_directory); - - // Start Game - INFO("Starting Game..."); - - // Arguments - int argv_start = 1; // argv = &new_args[argv_start] - const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; // - - // Copy Existing Arguments - for (int i = 1; i < argc; i++) { - new_args[i + argv_start] = argv[i]; - } - // NULL-Terminator - new_args[argv_start + argc] = NULL; - - // Set Executable Argument - new_args[argv_start] = new_mcpi_exe_path; - - // Non-ARM Systems Need QEMU -#ifdef MCPI_USE_QEMU - argv_start--; - new_args[argv_start] = QEMU_BINARY; - // Use 4k Page Size - set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE)); -#endif - - // Setup Environment - setup_exec_environment(1); - - // Pass LD_* Variables Through QEMU -#ifdef MCPI_USE_QEMU - char *qemu_set_env = NULL; -#define pass_variable_through_qemu(name) string_append(&qemu_set_env, "%s%s=%s", qemu_set_env == NULL ? "" : ",", name, getenv(name)); - for_each_special_environmental_variable(pass_variable_through_qemu); - set_and_print_env("QEMU_SET_ENV", qemu_set_env); - free(qemu_set_env); - // Treat QEMU Itself As A Native Component - setup_exec_environment(0); -#endif - - // Run - const char **new_argv = &new_args[argv_start]; - safe_execvpe(new_argv, (const char *const *) environ); -} diff --git a/launcher/src/bootstrap.cpp b/launcher/src/bootstrap.cpp new file mode 100644 index 00000000..2263ba96 --- /dev/null +++ b/launcher/src/bootstrap.cpp @@ -0,0 +1,226 @@ +#define _FILE_OFFSET_BITS 64 + +#include +#include + +#include + +#include "util.h" +#include "bootstrap.h" +#include "patchelf.h" + +#define MCPI_BINARY "minecraft-pi" +#define QEMU_BINARY "qemu-arm" + +#define REQUIRED_PAGE_SIZE 4096 +#define _STR(x) #x +#define STR(x) _STR(x) + +// Debug Information +static void run_debug_command(const char *const command[], const char *prefix) { + int status = 0; + char *output = run_command(command, &status, nullptr); + if (output != nullptr) { + // Remove Newline + size_t length = strlen(output); + if (length > 0 && output[length - 1] == '\n') { + output[length - 1] = '\0'; + } + + // Print + DEBUG("%s: %s", prefix, output); + free(output); + } + if (!is_exit_status_success(status)) { + ERR("Unable To Gather Debug Information"); + } +} +static void print_debug_information() { + // System Information + const char *const command[] = {"uname", "-a", nullptr}; + run_debug_command(command, "System Information"); + + // Version + DEBUG("Reborn Version: v%s", MCPI_VERSION); + + // Architecture + const char *arch = "Unknown"; +#ifdef __x86_64__ + arch = "AMD64"; +#elif defined(__aarch64__) + arch = "ARM64"; +#elif defined(__arm__) + arch = "ARM32"; +#endif + DEBUG("Reborn Target Architecture: %s", arch); +} + +// Bootstrap +void bootstrap() { + // Debug Information + print_debug_information(); + + // Check Page Size (Not Needed When Using QEMU) +#ifndef MCPI_USE_QEMU + long page_size = sysconf(_SC_PAGESIZE); + if (page_size != REQUIRED_PAGE_SIZE) { + ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size); + } +#else + set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE)); +#endif + + // Get Binary Directory + char *binary_directory_raw = get_binary_directory(); + const std::string binary_directory = binary_directory_raw; + free(binary_directory_raw); + DEBUG("Binary Directory: %s", binary_directory.c_str()); + + // Copy SDK + copy_sdk(binary_directory, true); + + // Set MCPI_REBORN_ASSETS_PATH + { + char *assets_path = realpath("/proc/self/exe", nullptr); + ALLOC_CHECK(assets_path); + chop_last_component(&assets_path); + string_append(&assets_path, "/data"); + set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path); + free(assets_path); + } + + // Resolve Binary Path & Set MCPI_DIRECTORY + char *resolved_path = nullptr; + { + // Log + DEBUG("Resolving File Paths..."); + + // Resolve Full Binary Path + const std::string full_path = binary_directory + ("/" MCPI_BINARY); + resolved_path = realpath(full_path.c_str(), nullptr); + ALLOC_CHECK(resolved_path); + } + + // Fix MCPI Dependencies + char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX"; + { + // Log + DEBUG("Patching ELF Dependencies..."); + + // Find Linker + char *linker = nullptr; + // Select Linker +#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN + // Use ARM Sysroot Linker + safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory.c_str()); +#else + // Use Current Linker + linker = patch_get_interpreter(); +#endif + + // Patch + patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker); + + // Free Linker Path + if (linker != nullptr) { + free(linker); + } + + // Verify + if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) { + IMPOSSIBLE(); + } + } + + // Set MCPI_VANILLA_ASSETS_PATH + { + char *assets_path = strdup(resolved_path); + ALLOC_CHECK(assets_path); + chop_last_component(&assets_path); + string_append(&assets_path, "/data"); + set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path); + free(assets_path); + } + + // Free Resolved Path + free(resolved_path); + + // Configure Library Search Path + { + // Log + DEBUG("Setting Linker Search Paths..."); + + // Prepare + std::string mcpi_ld_path = ""; + + // Library Search Path For ARM Components + { + // Add ARM Library Directory + mcpi_ld_path += binary_directory + "/lib/arm:"; + + // Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System) +#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN + mcpi_ld_path += binary_directory + "/sysroot/lib:"; + mcpi_ld_path += binary_directory + "/sysroot/lib/arm-linux-gnueabihf:"; + mcpi_ld_path += binary_directory + "/sysroot/usr/lib:"; + mcpi_ld_path += binary_directory + "/sysroot/usr/lib/arm-linux-gnueabihf:"; +#endif + + // Add Host LD_LIBRARY_PATH + { + char *value = getenv("LD_LIBRARY_PATH"); + if (value != nullptr && strlen(value) > 0) { + mcpi_ld_path += value; + } + } + + // Set + set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_LIBRARY_PATH", mcpi_ld_path.c_str()); + } + } + + // Configure Preloaded Objects + { + // Log + DEBUG("Locating Mods..."); + + // ARM Components + bootstrap_mods(binary_directory); + } + + // Start Game + INFO("Starting Game..."); + + // Arguments + std::vector args; + // Non-ARM Systems Need QEMU +#ifdef MCPI_USE_QEMU + args.insert(args.begin(), QEMU_BINARY); +#endif + + // Preserve Existing LD_* Variables +#define preserve_variable(name) set_and_print_env(MCPI_ORIGINAL_LD_VARIABLE_PREFIX name, getenv(name)) + for_each_special_environmental_variable(preserve_variable); + set_and_print_env(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV, "1"); + // Setup Environment + setup_exec_environment(1); + + // Pass LD_* Variables Through QEMU +#ifdef MCPI_USE_QEMU +#define pass_variable_through_qemu(name) args.push_back("-E"); args.push_back(std::string(name) + "=" + getenv(name)) + for_each_special_environmental_variable(pass_variable_through_qemu); + // Treat QEMU Itself As A Native Component + setup_exec_environment(0); +#endif + + // Specify MCPI Binary + args.push_back(new_mcpi_exe_path); + + // Run + const char *new_argv[args.size() + 1]; + for (std::vector::size_type i = 0; i < args.size(); i++) { + new_argv[i] = args[i].c_str(); + } + new_argv[args.size()] = nullptr; + safe_execvpe(new_argv, environ); +} diff --git a/launcher/src/bootstrap.h b/launcher/src/bootstrap.h index 82452038..3f79573c 100644 --- a/launcher/src/bootstrap.h +++ b/launcher/src/bootstrap.h @@ -1,14 +1,7 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include -void pre_bootstrap(int argc, char *argv[]); -void bootstrap(int argc, char *argv[]); -void copy_sdk(char *binary_directory, int log_with_debug); -void bootstrap_mods(char *binary_directory); - -#ifdef __cplusplus -} -#endif +void bootstrap(); +void copy_sdk(const std::string &binary_directory, bool log_with_debug); +void bootstrap_mods(const std::string &binary_directory); diff --git a/launcher/src/client/cache.cpp b/launcher/src/client/cache.cpp index 52b156e9..ad116810 100644 --- a/launcher/src/client/cache.cpp +++ b/launcher/src/client/cache.cpp @@ -8,7 +8,7 @@ #include -#include "launcher.h" +#include "configuration.h" #include "cache.h" // Get Cache Path diff --git a/launcher/src/client/launcher.cpp b/launcher/src/client/configuration.cpp similarity index 61% rename from launcher/src/client/launcher.cpp rename to launcher/src/client/configuration.cpp index 5c564517..4b9416cc 100644 --- a/launcher/src/client/launcher.cpp +++ b/launcher/src/client/configuration.cpp @@ -10,25 +10,24 @@ #include #include "../util.h" -#include "../bootstrap.h" -#include "launcher.h" +#include "configuration.h" #include "cache.h" // Strip Feature Flag Default -std::string strip_feature_flag_default(std::string flag, bool *default_ret) { +std::string strip_feature_flag_default(const std::string &flag, bool *default_ret) { // Valid Values std::string true_str = "TRUE "; std::string false_str = "FALSE "; // Test if (flag.rfind(true_str, 0) == 0) { // Enabled By Default - if (default_ret != NULL) { + if (default_ret != nullptr) { *default_ret = true; } return flag.substr(true_str.length(), std::string::npos); } else if (flag.rfind(false_str, 0) == 0) { // Disabled By Default - if (default_ret != NULL) { + if (default_ret != nullptr) { *default_ret = false; } return flag.substr(false_str.length(), std::string::npos); @@ -41,7 +40,7 @@ std::string strip_feature_flag_default(std::string flag, bool *default_ret) { // Load Available Feature Flags extern unsigned char available_feature_flags[]; extern size_t available_feature_flags_len; -void load_available_feature_flags(std::function callback) { +void load_available_feature_flags(const std::function &callback) { // Get Path char *binary_directory = get_binary_directory(); std::string path = std::string(binary_directory) + "/available-feature-flags"; @@ -55,7 +54,7 @@ void load_available_feature_flags(std::function callback) { { std::string line; while (std::getline(stream, line)) { - if (line.length() > 0) { + if (!line.empty()) { // Verify Line if (line.find('|') == std::string::npos) { lines.push_back(line); @@ -67,15 +66,15 @@ void load_available_feature_flags(std::function callback) { } } // Sort - std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) { + std::sort(lines.begin(), lines.end(), [](const std::string &a, const std::string &b) { // Strip Defaults - std::string stripped_a = strip_feature_flag_default(a, NULL); - std::string stripped_b = strip_feature_flag_default(b, NULL); + std::string stripped_a = strip_feature_flag_default(a, nullptr); + std::string stripped_b = strip_feature_flag_default(b, nullptr); // Sort return stripped_a < stripped_b; }); // Run Callbacks - for (std::string &line : lines) { + for (const std::string &line : lines) { callback(line); } } @@ -83,11 +82,11 @@ void load_available_feature_flags(std::function callback) { // Run Command And Set Environmental Variable static void run_command_and_set_env(const char *env_name, const char *command[]) { // Only Run If Environmental Variable Is NULL - if (getenv(env_name) == NULL) { + if (getenv(env_name) == nullptr) { // Run int return_code; - char *output = run_command(command, &return_code, NULL); - if (output != NULL) { + char *output = run_command(command, &return_code, nullptr); + if (output != nullptr) { // Trim int length = strlen(output); if (output[length - 1] == '\n') { @@ -122,14 +121,14 @@ static void run_zenity_and_set_env(const char *env_name, std::vector::size_type i = 0; i < full_command.size(); i++) { full_command_array[i] = full_command[i].c_str(); } - full_command_array[full_command.size()] = NULL; + full_command_array[full_command.size()] = nullptr; // Run run_command_and_set_env(env_name, full_command_array); } // Set Variable If Not Already Set -static void set_env_if_unset(const char *env_name, std::function callback) { - if (getenv(env_name) == NULL) { +static void set_env_if_unset(const char *env_name, const std::function &callback) { + if (getenv(env_name) == nullptr) { char *value = strdup(callback().c_str()); ALLOC_CHECK(value); set_and_print_env(env_name, value); @@ -137,102 +136,74 @@ static void set_env_if_unset(const char *env_name, std::function } } -// Launch -#define LIST_DIALOG_SIZE "400" -int main(int argc, char *argv[]) { - // Don't Run As Root - if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) { - ERR("Don't Run As Root"); +// Handle Non-Launch Commands +void handle_non_launch_client_only_commands(const options_t &options) { + // Print Available Feature Flags + if (options.print_available_feature_flags) { + load_available_feature_flags([](const std::string &line) { + printf("%s\n", line.c_str()); + fflush(stdout); + }); + exit(EXIT_SUCCESS); } +} - // Ensure HOME - if (getenv("HOME") == NULL) { - ERR("$HOME Isn't Set"); +// Check Environment +void check_environment_client() { + // Don't Run As Root + if (getenv("_MCPI_SKIP_ROOT_CHECK") == nullptr && (getuid() == 0 || geteuid() == 0)) { + ERR("Don't Run As Root"); } // Check For Display #ifndef MCPI_HEADLESS_MODE - if (getenv("DISPLAY") == NULL && getenv("WAYLAND_DISPLAY") == NULL) { + if (getenv("DISPLAY") == nullptr && getenv("WAYLAND_DISPLAY") == nullptr) { ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set."); } #endif +} - // Print Features - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--print-available-feature-flags") == 0) { - // Print Available Feature Flags - load_available_feature_flags([](std::string line) { - printf("%s\n", line.c_str()); - fflush(stdout); - }); - return 0; - } +// Configure Client Options +#define LIST_DIALOG_SIZE "400" +void configure_client(const options_t &options) { + // Wipe Cache If Needed + if (options.wipe_cache) { + wipe_cache(); } - // Pre-Bootstrap - pre_bootstrap(argc, argv); - - // Create ~/.minecraft-pi If Needed - { - char *minecraft_folder = NULL; - safe_asprintf(&minecraft_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME")); - const char *const command[] = {"mkdir", "-p", minecraft_folder, NULL}; - run_simple_command(command, "Unable To Create Data Directory"); - free(minecraft_folder); - } - - // --wipe-cache - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--wipe-cache") == 0) { - wipe_cache(); - break; - } - } - - // --no-cache - bool no_cache = false; - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--no-cache") == 0) { - no_cache = true; - break; - } - } // Load Cache - launcher_cache cache = no_cache ? empty_cache : load_cache(); + launcher_cache cache = options.no_cache ? empty_cache : load_cache(); // --default - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--default") == 0) { - // Use Default Feature Flags - set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() { - std::string feature_flags = ""; - load_available_feature_flags([&feature_flags, &cache](std::string flag) { - bool value; - // Strip Default Value - std::string stripped_flag = strip_feature_flag_default(flag, &value); - // Use Cache - if (cache.feature_flags.count(stripped_flag) > 0) { - value = cache.feature_flags[stripped_flag]; - } - // Specify Default Value - if (value) { - // Enabled By Default - feature_flags += stripped_flag + '|'; - } - }); - if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') { - feature_flags.pop_back(); + if (options.use_default) { + // Use Default Feature Flags + set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() { + std::string feature_flags = ""; + load_available_feature_flags([&feature_flags, &cache](const std::string &flag) { + bool value; + // Strip Default Value + std::string stripped_flag = strip_feature_flag_default(flag, &value); + // Use Cache + if (cache.feature_flags.count(stripped_flag) > 0) { + value = cache.feature_flags[stripped_flag]; + } + // Specify Default Value + if (value) { + // Enabled By Default + feature_flags += stripped_flag + '|'; } - return feature_flags; }); - set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() { - return cache.render_distance; - }); - set_env_if_unset("MCPI_USERNAME", [&cache]() { - return cache.username; - }); - break; - } + if (!feature_flags.empty() && feature_flags[feature_flags.length() - 1] == '|') { + feature_flags.pop_back(); + } + return feature_flags; + }); + set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() { + return cache.render_distance; + }); + set_env_if_unset("MCPI_USERNAME", [&cache]() { + return cache.username; + }); } // Setup MCPI_FEATURE_FLAGS @@ -248,7 +219,7 @@ int main(int argc, char *argv[]) { command.push_back("Enabled"); command.push_back("--column"); command.push_back("Feature"); - load_available_feature_flags([&command, &cache](std::string flag) { + load_available_feature_flags([&command, &cache](const std::string &flag) { bool value; // Strip Default Value std::string stripped_flag = strip_feature_flag_default(flag, &value); @@ -287,7 +258,7 @@ int main(int argc, char *argv[]) { command.push_back("Name"); std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"}; for (std::string &render_distance : render_distances) { - command.push_back(render_distance.compare(cache.render_distance) == 0 ? "TRUE" : "FALSE"); + command.push_back(render_distance == cache.render_distance ? "TRUE" : "FALSE"); command.push_back(render_distance); } // Run @@ -306,10 +277,7 @@ int main(int argc, char *argv[]) { } // Save Cache - if (!no_cache) { + if (!options.no_cache) { save_cache(); } - - // Bootstrap - bootstrap(argc, argv); } diff --git a/launcher/src/client/configuration.h b/launcher/src/client/configuration.h new file mode 100644 index 00000000..eaa5afe7 --- /dev/null +++ b/launcher/src/client/configuration.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#include "../options/parser.h" + +// Defaults +#define DEFAULT_USERNAME "StevePi" +#define DEFAULT_RENDER_DISTANCE "Short" + +// Feature Flags +std::string strip_feature_flag_default(const std::string& flag, bool *default_ret); +void load_available_feature_flags(const std::function &callback); + +// Handle Non-Launch Commands +void handle_non_launch_client_only_commands(const options_t &options); + +// Check Environment +void check_environment_client(); + +// Configure Client Options +void configure_client(const options_t &options); \ No newline at end of file diff --git a/launcher/src/client/launcher.h b/launcher/src/client/launcher.h deleted file mode 100644 index ad5f32e2..00000000 --- a/launcher/src/client/launcher.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include - -// Defaults -#define DEFAULT_USERNAME "StevePi" -#define DEFAULT_RENDER_DISTANCE "Short" - -// Feature Flags -std::string strip_feature_flag_default(std::string flag, bool *default_ret); -void load_available_feature_flags(std::function callback); diff --git a/launcher/src/crash-report.c b/launcher/src/crash-report.c index 34c3780d..1751a9b1 100644 --- a/launcher/src/crash-report.c +++ b/launcher/src/crash-report.c @@ -34,7 +34,7 @@ static void show_report(const char *log_filename) { "--width", CRASH_REPORT_DIALOG_WIDTH, "--height", CRASH_REPORT_DIALOG_HEIGHT, "--text-info", - "--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the Discord server! If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.", + "--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the Discord server! If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.", "--filename", log_filename, "--no-wrap", "--font", "Monospace", @@ -121,13 +121,11 @@ void setup_crash_report() { track_child(ret); // Install Signal Handlers - struct sigaction act_sigint; - memset((void *) &act_sigint, 0, sizeof (struct sigaction)); + struct sigaction act_sigint = {0}; act_sigint.sa_flags = SA_RESTART; act_sigint.sa_handler = &exit_handler; sigaction(SIGINT, &act_sigint, NULL); - struct sigaction act_sigterm; - memset((void *) &act_sigterm, 0, sizeof (struct sigaction)); + struct sigaction act_sigterm = {0}; act_sigterm.sa_flags = SA_RESTART; act_sigterm.sa_handler = &exit_handler; sigaction(SIGTERM, &act_sigterm, NULL); diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp new file mode 100644 index 00000000..e9ac0a13 --- /dev/null +++ b/launcher/src/main.cpp @@ -0,0 +1,154 @@ +#include +#include +#include + +#include "bootstrap.h" +#include "options/parser.h" +#include "crash-report.h" +#include "util.h" +#ifndef MCPI_SERVER_MODE +#include "client/configuration.h" +#endif + +// Bind Options To Environmental Variable +static void bind_to_env(const char *env, const bool value) { + const bool force = env[0] == '_'; + if (force || value) { + set_and_print_env(env, value ? "1" : nullptr); + } +} +static void setup_environment(const options_t &options) { + // Passthrough Options To Game +#ifndef MCPI_SERVER_MODE + bind_to_env("_MCPI_BENCHMARK", options.benchmark); +#else + bind_to_env("_MCPI_ONLY_GENERATE", options.only_generate); +#endif + + // GTK Dark Mode +#ifndef MCPI_HEADLESS_MODE + set_and_print_env("GTK_THEME", "Adwaita:dark"); +#endif + + // Configure PATH + { + // Get Binary Directory + char *binary_directory = get_binary_directory(); + std::string new_path = std::string(binary_directory) + "/bin"; + free(binary_directory); + // Add Existing PATH + { + char *value = getenv("PATH"); + if (value != nullptr && strlen(value) > 0) { + new_path += std::string(":") + value; + } + } + // Set And Free + set_and_print_env("PATH", new_path.c_str()); + } +} + +// Non-Launch Commands +static void handle_non_launch_commands(const options_t &options) { + if (options.copy_sdk) { + char *binary_directory = get_binary_directory(); + copy_sdk(binary_directory, false); + free(binary_directory); + fflush(stdout); + exit(EXIT_SUCCESS); + } +} + +// Exit Handler +static void exit_handler(__attribute__((unused)) int signal_id) { + // Pass Signal To Child + murder_children(); + while (wait(nullptr) > 0) {} + _exit(EXIT_SUCCESS); +} + +// Start The Game +static void start_game(const options_t &options) { + // Disable stdout Buffering + setvbuf(stdout, nullptr, _IONBF, 0); + + // Environemntal Variable Options + setup_environment(options); + + // Setup Crash Reporting + if (!options.disable_crash_report) { + setup_log_file(); + setup_crash_report(); + } + + // Install Signal Handlers + struct sigaction act_sigint = {}; + act_sigint.sa_flags = SA_RESTART; + act_sigint.sa_handler = &exit_handler; + sigaction(SIGINT, &act_sigint, nullptr); + struct sigaction act_sigterm = {}; + act_sigterm.sa_flags = SA_RESTART; + act_sigterm.sa_handler = &exit_handler; + sigaction(SIGTERM, &act_sigterm, nullptr); + + // Setup Home +#ifndef MCPI_SERVER_MODE + // Ensure $HOME + const char *home = getenv("HOME"); + if (home == nullptr) { + ERR("$HOME Isn't Set"); + } + // Create If Needed + { + std::string minecraft_folder = std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA; + struct stat tmp_stat = {}; + bool exists = stat(minecraft_folder.c_str(), &tmp_stat) != 0 ? false : S_ISDIR(tmp_stat.st_mode); + if (!exists) { + // Doesn't Exist + if (mkdir(minecraft_folder.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) { + ERR("Unable To Create Data Directory: %s", strerror(errno)); + } + } + } +#else + // Set Home To Current Directory, So World Data Is Stored There + char *launch_directory = getcwd(NULL, 0); + set_and_print_env("HOME", launch_directory); + free(launch_directory); +#endif + + // Configure Client Options +#ifndef MCPI_SERVER_MODE + configure_client(options); +#endif + + // Bootstrap + bootstrap(); +} + +// Main +int main(int argc, char *argv[]) { + // Parse Options + options_t options = parse_options(argc, argv); + + // Set Debug Tag + reborn_debug_tag = "(Launcher) "; + + // Debug Logging + bind_to_env(MCPI_DEBUG_ENV, options.debug); + + // Handle Non-Launch Commands (Copy SDK, Print Feature Flags, Etc) + handle_non_launch_commands(options); +#ifndef MCPI_SERVER_MODE + handle_non_launch_client_only_commands(options); +#endif + + // Check Environment +#ifndef MCPI_SERVER_MODE + // Code After This Can Safely Open A Window + check_environment_client(); +#endif + + // Start The Game + start_game(options); +} \ No newline at end of file diff --git a/launcher/src/mods.c b/launcher/src/mods.c deleted file mode 100644 index 418ab9ae..00000000 --- a/launcher/src/mods.c +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "bootstrap.h" - -// Get All Mods In Folder -static void load(char **ld_preload, const char *folder) { - int folder_name_length = strlen(folder); - // Open Folder - DIR *dp = opendir(folder); - if (dp != NULL) { - // Loop Through Folder - struct dirent *entry = NULL; - errno = 0; - while (1) { - errno = 0; - entry = readdir(dp); - if (entry != NULL) { - // Check If File Is Regular - if (entry->d_type == DT_REG) { - // Get Full Name - int name_length = strlen(entry->d_name); - int total_length = folder_name_length + name_length; - char name[total_length + 1]; - - // Concatenate Folder Name And File Name - 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]; - } - // Add Terminator - name[total_length] = '\0'; - - // Check If File Is Accessible - int result = access(name, R_OK); - if (result == 0) { - // Add To LD_PRELOAD - string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name); - } else if (result == -1 && errno != 0) { - // Fail - WARN("Unable To Access: %s: %s", name, strerror(errno)); - errno = 0; - } - } - } else if (errno != 0) { - // Error Reading Contents Of Folder - ERR("Error Reading Directory: %s: %s", folder, strerror(errno)); - } else { - // Done! - break; - } - } - // Close Folder - closedir(dp); - } else if (errno == ENOENT) { - // Folder Doesn't Exist - } else { - // Unable To Open Folder - ERR("Error Opening Directory: %s: %s", folder, strerror(errno)); - } -} - -// Bootstrap Mods -void bootstrap_mods(char *binary_directory) { - // Prepare - char *preload = NULL; - - // ~/.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(&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(&preload, mods_folder); - // Free Mods Folder - free(mods_folder); - } - - // Add LD_PRELOAD - { - char *value = getenv("LD_PRELOAD"); - if (value != NULL && strlen(value) > 0) { - string_append(&preload, ":%s", value); - } - } - - // Set - set_and_print_env("MCPI_ARM_LD_PRELOAD", preload); - free(preload); -} diff --git a/launcher/src/mods.cpp b/launcher/src/mods.cpp new file mode 100644 index 00000000..1e346c88 --- /dev/null +++ b/launcher/src/mods.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +#include + +#include "bootstrap.h" + +// Get All Mods In Folder +static void load(std::string &ld_preload, const std::string &folder) { + // Open Folder + DIR *dp = opendir(folder.c_str()); + if (dp != nullptr) { + // Loop Through Folder + while (true) { + errno = 0; + dirent *entry = readdir(dp); + if (entry != nullptr) { + // Check If File Is Regular + if (entry->d_type == DT_REG) { + // Get Full Name + std::string name = folder + entry->d_name; + + // Check If File Is Accessible + int result = access(name.c_str(), R_OK); + if (result == 0) { + // Add To LD_PRELOAD + ld_preload += name + ":"; + } else if (result == -1 && errno != 0) { + // Fail + WARN("Unable To Access: %s: %s", name.c_str(), strerror(errno)); + errno = 0; + } + } + } else if (errno != 0) { + // Error Reading Contents Of Folder + ERR("Error Reading Directory: %s: %s", folder.c_str(), strerror(errno)); + } else { + // Done! + break; + } + } + // Close Folder + closedir(dp); + } else if (errno == ENOENT) { + // Folder Doesn't Exist + } else { + // Unable To Open Folder + ERR("Error Opening Directory: %s: %s", folder.c_str(), strerror(errno)); + } +} + +// Bootstrap Mods +#define SUBDIRECTORY_FOR_MODS "/mods/" +void bootstrap_mods(const std::string &binary_directory) { + // Prepare + std::string preload = ""; + + // ~/.minecraft-pi/mods + { + // Get Mods Folder + std::string mods_folder = std::string(getenv("HOME")) + HOME_SUBDIRECTORY_FOR_GAME_DATA SUBDIRECTORY_FOR_MODS; + // Load Mods From ./mods + load(preload, mods_folder); + } + + // Built-In Mods + { + // Get Mods Folder + std::string mods_folder = binary_directory + SUBDIRECTORY_FOR_MODS; + // Load Mods From ./mods + load(preload, mods_folder); + } + + // Add LD_PRELOAD + { + const char *value = getenv("LD_PRELOAD"); + if (value != nullptr && strlen(value) > 0) { + preload += value; + } + } + + // Set + set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_PRELOAD", preload.c_str()); +} diff --git a/launcher/src/options/option-list.h b/launcher/src/options/option-list.h new file mode 100644 index 00000000..b69d64e1 --- /dev/null +++ b/launcher/src/options/option-list.h @@ -0,0 +1,12 @@ +OPTION(debug, "debug", 'd', "Enable Debug Logging (" MCPI_DEBUG_ENV ")") +OPTION(copy_sdk, "copy-sdk", -2, "Extract Modding SDK And Exit") +OPTION(disable_crash_report, "disable-crash-report", -1, "Disable Crash Report Dialog") +#ifndef MCPI_SERVER_MODE +OPTION(use_default, "default", -3, "Skip Configuration Dialogs") +OPTION(no_cache, "no-cache", -4, "Disable Configuration Cache") +OPTION(wipe_cache, "wipe-cache", -5, "Wipe Cached Configuration") +OPTION(print_available_feature_flags, "print-available-feature-flags", -6, "Print Available Feature Flags") +OPTION(benchmark, "benchmark", -7, "Run Benchmark") +#else +OPTION(only_generate, "only-generate", -8, "Generate World And Exit") +#endif \ No newline at end of file diff --git a/launcher/src/options/parser.cpp b/launcher/src/options/parser.cpp new file mode 100644 index 00000000..416c3688 --- /dev/null +++ b/launcher/src/options/parser.cpp @@ -0,0 +1,38 @@ +#include + +#include "parser.h" + +// Globals +const char *argp_program_version = "Reborn v" MCPI_VERSION; +const char *argp_program_bug_address = "<" MCPI_DISCORD_INVITE ">"; +static char doc[] = "Minecraft: Pi Edition Modding Project"; + +// Options +#define OPTION(ignored, name, key, doc) {name, key, nullptr, 0, doc, 0}, +static argp_option options_data[] = { +#include "option-list.h" + {nullptr, 0, nullptr, 0, nullptr, 0} +}; +#undef OPTION + +// Parse Options +#define OPTION(name, ignored, key, ...) \ + case key: \ + options->name = true; \ + break; +static error_t parse_opt(int key, __attribute__((unused)) char *arg, argp_state *state) { + options_t *options = (options_t *) state->input; + switch (key) { +#include "option-list.h" + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} +#undef OPTION +static argp argp = {options_data, parse_opt, nullptr, doc, nullptr, nullptr, nullptr}; +options_t parse_options(int argc, char *argv[]) { + options_t options = {}; + argp_parse(&argp, argc, argv, 0, nullptr, &options); + return options; +} \ No newline at end of file diff --git a/launcher/src/options/parser.h b/launcher/src/options/parser.h new file mode 100644 index 00000000..b897c713 --- /dev/null +++ b/launcher/src/options/parser.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +#define OPTION(name, ...) bool name; +struct options_t { +#include "option-list.h" +}; +#undef OPTION +options_t parse_options(int argc, char *argv[]); \ No newline at end of file diff --git a/launcher/src/sdk.c b/launcher/src/sdk.c deleted file mode 100644 index 2547a904..00000000 --- a/launcher/src/sdk.c +++ /dev/null @@ -1,67 +0,0 @@ -#include - -#include "bootstrap.h" -#include "util.h" - -// Log -#define LOG(is_debug, ...) \ - { \ - if (is_debug) { \ - DEBUG(__VA_ARGS__); \ - } else { \ - INFO(__VA_ARGS__); \ - } \ - } - -// Copy SDK Into ~/.minecraft-pi -#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk" -void copy_sdk(char *binary_directory, int log_with_debug) { - // Ensure SDK Directory - { - char *sdk_path = NULL; - safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME")); - const char *const command[] = {"mkdir", "-p", sdk_path, NULL}; - run_simple_command(command, "Unable To Create SDK Directory"); - } - - // Lock File - char *lock_file_path = NULL; - safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME")); - int lock_file_fd = lock_file(lock_file_path); - - // Output Directory - char *output = NULL; - safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME")); - // Source Directory - char *source = NULL; - safe_asprintf(&source, "%s/sdk/.", binary_directory); - - // Clean - { - const char *const command[] = {"rm", "-rf", output, NULL}; - run_simple_command(command, "Unable To Clean SDK Output Directory"); - } - - // Make Directory - { - const char *const command[] = {"mkdir", "-p", output, NULL}; - run_simple_command(command, "Unable To Create SDK Output Directory"); - } - - // Copy - { - const char *const command[] = {"cp", "-ar", source, output, NULL}; - run_simple_command(command, "Unable To Copy SDK"); - } - - // Log - LOG(log_with_debug, "Copied SDK To: %s", output); - - // Free - free(output); - free(source); - - // Unlock File - unlock_file(lock_file_path, lock_file_fd); - free(lock_file_path); -} diff --git a/launcher/src/sdk.cpp b/launcher/src/sdk.cpp new file mode 100644 index 00000000..cd3b1bf4 --- /dev/null +++ b/launcher/src/sdk.cpp @@ -0,0 +1,59 @@ +#include + +#include "bootstrap.h" +#include "util.h" + +// Log +#define LOG(is_debug, ...) \ + { \ + if (is_debug) { \ + DEBUG(__VA_ARGS__); \ + } else { \ + INFO(__VA_ARGS__); \ + } \ + } + +// Copy SDK Into ~/.minecraft-pi +#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk" +void copy_sdk(const std::string &binary_directory, const bool log_with_debug) { + // Ensure SDK Directory + std::string sdk_path; + { + sdk_path = std::string(getenv("HOME")) + HOME_SUBDIRECTORY_FOR_SDK; + const char *const command[] = {"mkdir", "-p", sdk_path.c_str(), nullptr}; + run_simple_command(command, "Unable To Create SDK Directory"); + } + + // Lock File + std::string lock_file_path = sdk_path + "/.lock"; + int lock_file_fd = lock_file(lock_file_path.c_str()); + + // Output Directory + std::string output = sdk_path + "/" MCPI_SDK_DIR; + // Source Directory + std::string source = binary_directory + "/sdk/."; + + // Clean + { + const char *const command[] = {"rm", "-rf", output.c_str(), nullptr}; + run_simple_command(command, "Unable To Clean SDK Output Directory"); + } + + // Make Directory + { + const char *const command[] = {"mkdir", "-p", output.c_str(), nullptr}; + run_simple_command(command, "Unable To Create SDK Output Directory"); + } + + // Copy + { + const char *const command[] = {"cp", "-ar", source.c_str(), output.c_str(), nullptr}; + run_simple_command(command, "Unable To Copy SDK"); + } + + // Log + LOG(log_with_debug, "Copied SDK To: %s", output.c_str()); + + // Unlock File + unlock_file(lock_file_path.c_str(), lock_file_fd); +} diff --git a/launcher/src/server/launcher.c b/launcher/src/server/launcher.c deleted file mode 100644 index 58c9d0cf..00000000 --- a/launcher/src/server/launcher.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -#include - -#include "../bootstrap.h" - -int main(int argc, char *argv[]) { - // Pre-Bootstrap - pre_bootstrap(argc, argv); - - // Set Home To Current Directory, So World Data Is Stored There - char *launch_directory = getcwd(NULL, 0); - set_and_print_env("HOME", launch_directory); - free(launch_directory); - - // Bootstrap - bootstrap(argc, argv); -} diff --git a/libreborn/include/libreborn/config.h.in b/libreborn/include/libreborn/config.h.in index 8b165256..bd83fc44 100644 --- a/libreborn/include/libreborn/config.h.in +++ b/libreborn/include/libreborn/config.h.in @@ -14,3 +14,4 @@ #cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@" #cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@" #cmakedefine MCPI_USE_QEMU +#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@" diff --git a/libreborn/include/libreborn/exec.h b/libreborn/include/libreborn/exec.h index a4656ea9..115b397a 100644 --- a/libreborn/include/libreborn/exec.h +++ b/libreborn/include/libreborn/exec.h @@ -20,9 +20,12 @@ extern "C" { void set_and_print_env(const char *name, const char *value); // Safe execvpe() +#define MCPI_LD_VARIABLE_PREFIX "_MCPI_" +#define MCPI_ORIGINAL_LD_VARIABLE_PREFIX MCPI_LD_VARIABLE_PREFIX "ORIGINAL_" +#define MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV MCPI_ORIGINAL_LD_VARIABLE_PREFIX "PRESERVED" #define for_each_special_environmental_variable(handle) \ handle("LD_LIBRARY_PATH"); \ - handle("LD_PRELOAD"); + handle("LD_PRELOAD") void setup_exec_environment(int is_arm_component); __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]); diff --git a/libreborn/include/libreborn/log.h b/libreborn/include/libreborn/log.h index ba896f56..84420943 100644 --- a/libreborn/include/libreborn/log.h +++ b/libreborn/include/libreborn/log.h @@ -8,6 +8,7 @@ extern "C" { #endif // Debug +#define MCPI_DEBUG_ENV "MCPI_DEBUG" extern const char *reborn_debug_tag; int reborn_get_debug_fd(); diff --git a/libreborn/src/util/exec.c b/libreborn/src/util/exec.c index b3cb2f0c..45923a64 100644 --- a/libreborn/src/util/exec.c +++ b/libreborn/src/util/exec.c @@ -21,12 +21,14 @@ void set_and_print_env(const char *name, const char *value) { // Safe execvpe() #define handle_environmental_variable(var) \ { \ - const char *full_var = is_arm_component ? "MCPI_ARM_" var : "MCPI_NATIVE_" var; \ + const char *full_var = is_arm_component ? MCPI_LD_VARIABLE_PREFIX var : MCPI_ORIGINAL_LD_VARIABLE_PREFIX var; \ const char *var_value = getenv(full_var); \ set_and_print_env(var, var_value); \ } void setup_exec_environment(int is_arm_component) { - for_each_special_environmental_variable(handle_environmental_variable); + if (is_arm_component || getenv(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV) != NULL) { + for_each_special_environmental_variable(handle_environmental_variable); + } } __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) { // Log @@ -89,7 +91,7 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_ char buf[BUFFER_SIZE]; size_t position = 0; ssize_t bytes_read = 0; - while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE)) > 0) { + while ((bytes_read = read(output_pipe[0], buf, BUFFER_SIZE)) > 0) { // Grow Output If Needed size_t needed_size = position + bytes_read; if (needed_size > size) { diff --git a/libreborn/src/util/log.c b/libreborn/src/util/log.c index 139e2532..0217db63 100644 --- a/libreborn/src/util/log.c +++ b/libreborn/src/util/log.c @@ -7,7 +7,7 @@ const char *reborn_debug_tag = ""; // Debug FD int reborn_get_debug_fd() { - if (getenv("MCPI_DEBUG") != NULL) { + if (getenv(MCPI_DEBUG_ENV) != NULL) { return STDERR_FILENO; } else { static int debug_fd = -1; diff --git a/media-layer/trampoline/src/GLESv1_CM.c b/media-layer/trampoline/src/GLESv1_CM.c index 33bced81..ae64b09d 100644 --- a/media-layer/trampoline/src/GLESv1_CM.c +++ b/media-layer/trampoline/src/GLESv1_CM.c @@ -6,7 +6,7 @@ #include "common/common.h" CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pname, (uint32_t) params); #else GLenum pname = next_int(); @@ -17,7 +17,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) } // 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #define CALL_GL_POINTER(unique_id, name) \ CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \ trampoline(size, type, stride, (uint32_t) pointer); \ @@ -37,7 +37,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) CALL_GL_POINTER(12, glVertexPointer) CALL(13, glLineWidth, void, (GLfloat width)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, width)); #else GLfloat width = next_float(); @@ -47,7 +47,7 @@ CALL(13, glLineWidth, void, (GLfloat width)) } CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(sfactor, dfactor); #else GLenum sfactor = next_int(); @@ -58,7 +58,7 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) } CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(mode, first, count); #else GLenum mode = next_int(); @@ -70,7 +70,7 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) } CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha)); #else GLfloat red = next_float(); @@ -83,7 +83,7 @@ CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alp } CALL(17, glClear, void, (GLbitfield mask)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(mask); #else GLbitfield mask = next_int(); @@ -93,7 +93,7 @@ CALL(17, glClear, void, (GLbitfield mask)) } CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, size, (uint32_t) data, usage); #else GLenum target = next_int(); @@ -106,7 +106,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, } CALL(19, glFogx, void, (GLenum pname, GLfixed param)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pname, param); #else GLenum pname = next_int(); @@ -117,7 +117,7 @@ CALL(19, glFogx, void, (GLenum pname, GLfixed param)) } CALL(20, glFogf, void, (GLenum pname, GLfloat param)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pname, pun_to(uint32_t, param)); #else GLenum pname = next_int(); @@ -128,7 +128,7 @@ CALL(20, glFogf, void, (GLenum pname, GLfloat param)) } CALL(21, glMatrixMode, void, (GLenum mode)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(mode); #else GLenum mode = next_int(); @@ -140,7 +140,7 @@ CALL(21, glMatrixMode, void, (GLenum mode)) CALL_GL_POINTER(22, glColorPointer) CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(x, y, width, height); #else GLint x = next_int(); @@ -153,7 +153,7 @@ CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) } CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, pname, param); #else GLenum target = next_int(); @@ -165,7 +165,7 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) } CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels); #else GLenum target = next_int(); @@ -183,7 +183,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, } CALL(26, glEnable, void, (GLenum cap)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(cap); #else GLenum cap = next_int(); @@ -193,7 +193,7 @@ CALL(26, glEnable, void, (GLenum cap)) } CALL(27, glEnableClientState, void, (GLenum array)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(array); #else GLenum array = next_int(); @@ -203,7 +203,7 @@ CALL(27, glEnableClientState, void, (GLenum array)) } CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units)); #else GLfloat factor = next_float(); @@ -216,7 +216,7 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) CALL_GL_POINTER(41, glTexCoordPointer) CALL(29, glDisableClientState, void, (GLenum array)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(array); #else GLenum array = next_int(); @@ -226,7 +226,7 @@ CALL(29, glDisableClientState, void, (GLenum array)) } CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far)); #else GLclampf near = next_float(); @@ -237,7 +237,7 @@ CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) } CALL(31, glDepthFunc, void, (GLenum func)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(func); #else GLenum func2 = next_int(); @@ -247,7 +247,7 @@ CALL(31, glDepthFunc, void, (GLenum func)) } CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, buffer); #else GLenum target = next_int(); @@ -258,7 +258,7 @@ CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) } CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha)); #else GLclampf red = next_float(); @@ -271,7 +271,7 @@ CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLcla } CALL(34, glPopMatrix, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -280,7 +280,7 @@ CALL(34, glPopMatrix, void, ()) } CALL(35, glLoadIdentity, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -289,7 +289,7 @@ CALL(35, glLoadIdentity, void, ()) } CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); #else GLfloat x = next_float(); @@ -301,7 +301,7 @@ CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) } CALL(37, glPushMatrix, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -310,7 +310,7 @@ CALL(37, glPushMatrix, void, ()) } CALL(38, glDepthMask, void, (GLboolean flag)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(flag); #else GLboolean flag = next_int(); @@ -320,7 +320,7 @@ CALL(38, glDepthMask, void, (GLboolean flag)) } CALL(39, glHint, void, (GLenum target, GLenum mode)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, mode); #else GLenum target = next_int(); @@ -331,7 +331,7 @@ CALL(39, glHint, void, (GLenum target, GLenum mode)) } CALL(40, glMultMatrixf, void, (const GLfloat *m)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline((uint32_t) m); #else GLfloat *m = next_ptr(); @@ -341,7 +341,7 @@ CALL(40, glMultMatrixf, void, (const GLfloat *m)) } CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(n, (uint32_t) buffers); #else GLsizei n = next_int(); @@ -352,7 +352,7 @@ CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) } CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(red, green, blue, alpha); #else GLboolean red = next_int(); @@ -365,7 +365,7 @@ CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLb } CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels); #else GLenum target = next_int(); @@ -383,7 +383,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin } CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(n, (uint32_t) textures); #else GLsizei n = next_int(); @@ -394,7 +394,7 @@ CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures)) } CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(n, (uint32_t) textures); #else GLsizei n = next_int(); @@ -405,7 +405,7 @@ CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures)) } CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(func, pun_to(uint32_t, ref)); #else GLenum func2 = next_int(); @@ -416,7 +416,7 @@ CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref)) } CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pname, (uint32_t) params); #else GLenum pname = next_int(); @@ -427,7 +427,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) } CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(target, texture); #else GLenum target = next_int(); @@ -438,7 +438,7 @@ CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) } CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); #else GLfloat x = next_float(); @@ -450,7 +450,7 @@ CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) } CALL(51, glShadeModel, void, (GLenum mode)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(mode); #else GLenum mode = next_int(); @@ -460,7 +460,7 @@ CALL(51, glShadeModel, void, (GLenum mode)) } CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, left), pun_to(uint32_t, right), pun_to(uint32_t, bottom), pun_to(uint32_t, top), pun_to(uint32_t, near), pun_to(uint32_t, far)); #else GLfloat left = next_float(); @@ -475,7 +475,7 @@ CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat t } CALL(53, glDisable, void, (GLenum cap)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(cap); #else GLenum cap = next_int(); @@ -485,7 +485,7 @@ CALL(53, glDisable, void, (GLenum cap)) } CALL(54, glCullFace, void, (GLenum mode)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(mode); #else GLenum mode = next_int(); @@ -495,7 +495,7 @@ CALL(54, glCullFace, void, (GLenum mode)) } CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, angle), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); #else GLfloat angle = next_float(); @@ -508,7 +508,7 @@ CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) } CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(x, y, width, height); #else GLint x = next_int(); @@ -521,7 +521,7 @@ CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) } CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, nx), pun_to(uint32_t, ny), pun_to(uint32_t, nz)); #else GLfloat nx = next_float(); @@ -533,7 +533,7 @@ CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz)) } CALL(58, glIsEnabled, GLboolean, (GLenum cap)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(cap); #else GLenum cap = next_int(); @@ -543,7 +543,7 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap)) } CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pname, (uint32_t) params); #else GLenum pname = next_int(); @@ -554,7 +554,7 @@ CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) } CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(x, y, width, height, format, type, (uint32_t) data); #else GLint x = next_int(); @@ -570,7 +570,7 @@ CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, G } CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(n, (uint32_t) buffers); #else GLsizei n = next_int(); diff --git a/media-layer/trampoline/src/media-layer-core.c b/media-layer/trampoline/src/media-layer-core.c index 0808ce16..1bc5ad95 100644 --- a/media-layer/trampoline/src/media-layer-core.c +++ b/media-layer/trampoline/src/media-layer-core.c @@ -11,7 +11,7 @@ // SDL Functions CALL(0, SDL_Init, int, (uint32_t flags)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(flags); #else uint32_t flags = next_int(); @@ -21,7 +21,7 @@ CALL(0, SDL_Init, int, (uint32_t flags)) } CALL(1, SDL_PollEvent, int, (SDL_Event *event)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline((uint32_t) event); #else SDL_Event *event = next_ptr(); @@ -31,7 +31,7 @@ CALL(1, SDL_PollEvent, int, (SDL_Event *event)) } CALL(2, SDL_PushEvent, int, (SDL_Event *event)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline((uint32_t) event); #else SDL_Event *event = next_ptr(); @@ -41,7 +41,7 @@ CALL(2, SDL_PushEvent, int, (SDL_Event *event)) } CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline((uint32_t) title, (uint32_t) icon); #else char *title = next_ptr(); @@ -52,7 +52,7 @@ CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) } CALL(4, media_toggle_fullscreen, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -61,7 +61,7 @@ CALL(4, media_toggle_fullscreen, void, ()) } CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(mode); #else SDL_GrabMode mode = next_int(); @@ -71,7 +71,7 @@ CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) } CALL(6, SDL_ShowCursor, int, (int32_t toggle)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(toggle); #else int mode = next_int(); @@ -81,7 +81,7 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle)) } CALL(8, media_swap_buffers, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -90,7 +90,7 @@ CALL(8, media_swap_buffers, void, ()) } CALL(9, media_cleanup, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -99,7 +99,7 @@ CALL(9, media_cleanup, void, ()) } CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline((uint32_t) width, (uint32_t) height); #else int *width = next_ptr(); @@ -110,7 +110,7 @@ CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) } CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(pun_to(uint32_t, volume), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, yaw)); #else float volume = next_float(); @@ -124,7 +124,7 @@ CALL(59, media_audio_update, void, (float volume, float x, float y, float z, flo } CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline((uint32_t) source, (uint32_t) name, pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, pitch), pun_to(uint32_t, volume), is_ui); #else char *source = next_ptr(); @@ -141,7 +141,7 @@ CALL(60, media_audio_play, void, (const char *source, const char *name, float x, } CALL(62, media_set_interactable, void, (int is_interactable)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(is_interactable); #else int is_interactable = next_int(); @@ -151,7 +151,7 @@ CALL(62, media_set_interactable, void, (int is_interactable)) } CALL(63, media_disable_vsync, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -160,7 +160,7 @@ CALL(63, media_disable_vsync, void, ()) } CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(enabled); #else int enabled = next_int(); @@ -170,7 +170,7 @@ CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) } CALL(66, media_force_egl, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run @@ -179,7 +179,7 @@ CALL(66, media_force_egl, void, ()) } CALL(68, media_ensure_loaded, void, ()) -#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else // Run diff --git a/mods/include/mods/init/init.h b/mods/include/mods/init/init.h index 0107aec4..f8ad672e 100644 --- a/mods/include/mods/init/init.h +++ b/mods/include/mods/init/init.h @@ -1,7 +1,5 @@ #pragma once -#include - extern "C" { void run_tests(); void init_version(); @@ -10,7 +8,7 @@ void init_compat(); void init_server(); #else void init_multiplayer(); -void init_benchmark(int argc, char *argv[]); +void init_benchmark(); #endif #ifndef MCPI_HEADLESS_MODE void init_sound(); diff --git a/mods/src/benchmark/benchmark.cpp b/mods/src/benchmark/benchmark.cpp index aae2baba..65842323 100644 --- a/mods/src/benchmark/benchmark.cpp +++ b/mods/src/benchmark/benchmark.cpp @@ -158,17 +158,9 @@ static void Minecraft_update_injection(Minecraft *minecraft) { } // Init Benchmark -void init_benchmark(int argc, char *argv[]) { +void init_benchmark() { // --benchmark: Activate Benchmark - bool active = false; - for (int i = 1; i < argc; i++) { - // Check Argument - if (strcmp(argv[i], "--benchmark") == 0) { - // Enabled - active = true; - break; - } - } + bool active = getenv("_MCPI_BENCHMARK") != nullptr; if (active) { misc_run_on_update(Minecraft_update_injection); // Track Ticks diff --git a/mods/src/init/init.cpp b/mods/src/init/init.cpp index 31c16943..148e1271 100644 --- a/mods/src/init/init.cpp +++ b/mods/src/init/init.cpp @@ -3,7 +3,7 @@ #include #include -__attribute__((constructor)) static void init(int argc, char *argv[]) { +__attribute__((constructor)) static void init() { media_ensure_loaded(); reborn_init_patch(); run_tests(); @@ -37,9 +37,6 @@ __attribute__((constructor)) static void init(int argc, char *argv[]) { init_cake(); init_home(); #ifndef MCPI_SERVER_MODE - init_benchmark(argc, argv); -#else - (void) argc; - (void) argv; + init_benchmark(); #endif } diff --git a/mods/src/options/info.cpp b/mods/src/options/info.cpp index ec9c0900..ced07f47 100644 --- a/mods/src/options/info.cpp +++ b/mods/src/options/info.cpp @@ -234,7 +234,7 @@ CUSTOM_VTABLE(info_screen, Screen) { self->handleBackEvent(false); } else if (button->id == DISCORD_ID) { // Open Discord Invite - open_url("https://discord.gg/mcpi-revival-740287937727561779"); + open_url(MCPI_DISCORD_INVITE); } else if (button->id >= INFO_ID_START) { // Open Info URL int i = button->id - INFO_ID_START; diff --git a/mods/src/server/server.cpp b/mods/src/server/server.cpp index cc34df15..c69e9bba 100644 --- a/mods/src/server/server.cpp +++ b/mods/src/server/server.cpp @@ -31,16 +31,8 @@ // --only-generate: Ony Generate World And Then Exit static bool only_generate = false; -__attribute__((constructor)) static void _init_only_generate(int argc, char *argv[]) { - // Iterate Arguments - for (int i = 1; i < argc; i++) { - // Check Argument - if (strcmp(argv[i], "--only-generate") == 0) { - // Enabled - only_generate = true; - break; - } - } +__attribute__((constructor)) static void _init_only_generate() { + only_generate = getenv("_MCPI_ONLY_GENERATE") != nullptr; } // Server Properties