diff --git a/VERSION b/VERSION index 276cbf9..2bf1c1c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3.0 +2.3.1 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 151aebc..b8e69b1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +**2.3.1** +* Internal Refactor Of ``libreborn`` +* Remove Use Of ``/bin/sh`` + **2.3.0** * Switch To AppImage For Packaging * Prevent OpenAL From Crashing When Out Of Memory diff --git a/images/start.png b/images/start.png index 22ac898..8e775c9 100644 Binary files a/images/start.png and b/images/start.png differ diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index d6dbe35..452545e 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -8,7 +8,7 @@ if(BUILD_NATIVE_COMPONENTS) else() target_sources(launcher PRIVATE src/client/launcher.cpp) endif() - target_link_libraries(launcher reborn-headers) + target_link_libraries(launcher reborn-util) # Install install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}") install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}") diff --git a/launcher/src/bootstrap.c b/launcher/src/bootstrap.c index 1c9f984..48d7264 100644 --- a/launcher/src/bootstrap.c +++ b/launcher/src/bootstrap.c @@ -313,7 +313,7 @@ void bootstrap(int argc, char *argv[]) { // Arguments int argv_start = 2; // argv = &new_args[argv_start] - char *new_args[argv_start /* 2 Potential Prefix Arguments (QEMU And Linker) */ + argc + 1 /* NULL-Terminator */]; // + const char *new_args[argv_start /* 2 Potential Prefix Arguments (QEMU And Linker) */ + argc + 1 /* NULL-Terminator */]; // // Copy Existing Arguments for (int i = 1; i < argc; i++) { @@ -344,6 +344,6 @@ void bootstrap(int argc, char *argv[]) { #endif // Run - char **new_argv = &new_args[argv_start]; - safe_execvpe(new_argv[0], new_argv, environ); + const char **new_argv = &new_args[argv_start]; + safe_execvpe(new_argv, (const char *const *) environ); } diff --git a/launcher/src/client/launcher.cpp b/launcher/src/client/launcher.cpp index 67e7b10..eb51ccb 100644 --- a/launcher/src/client/launcher.cpp +++ b/launcher/src/client/launcher.cpp @@ -37,49 +37,8 @@ static void load_available_feature_flags(std::function callba } } -// Run Command And Get Output -static char *run_command(char *command[], int *return_code) { - // Store Output - int output_pipe[2]; - safe_pipe2(output_pipe, 0); - // Run - pid_t ret = fork(); - if (ret == -1) { - ERR("Unable To Run Command: %s", strerror(errno)); - } else if (ret == 0) { - // Child Process - - // Pipe stdout - dup2(output_pipe[1], STDOUT_FILENO); - close(output_pipe[0]); - close(output_pipe[1]); - - // Run - safe_execvpe(command[0], command, environ); - } else { - // Parent Process - - // Read stdout - close(output_pipe[1]); - char *output = NULL; - char c; - int bytes_read = 0; - while ((bytes_read = read(output_pipe[0], (void *) &c, 1)) > 0) { - string_append(&output, "%c", c); - } - close(output_pipe[0]); - - // Get Return Code - int status; - waitpid(ret, &status, 0); - *return_code = WIFEXITED(status) ? WEXITSTATUS(status) : 1; - - // Return - return output; - } -} // Run Command And Set Environmental Variable -static void run_command_and_set_env(const char *env_name, char *command[]) { +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) { // Run @@ -93,6 +52,8 @@ static void run_command_and_set_env(const char *env_name, char *command[]) { } // Set set_and_print_env(env_name, output); + // Free + free(output); } // Check Return Code if (return_code != 0) { @@ -107,7 +68,7 @@ static void run_zenity_and_set_env(const char *env_name, std::vector full_command; full_command.push_back("zenity"); full_command.push_back("--class"); - full_command.push_back("Minecraft: Pi Edition: Reborn"); + full_command.push_back(GUI_TITLE); full_command.insert(full_command.end(), command.begin(), command.end()); // Convert To C Array const char *full_command_array[full_command.size() + 1]; @@ -116,7 +77,7 @@ static void run_zenity_and_set_env(const char *env_name, std::vector #include +#include + #include #include "ldconfig.h" char *get_full_library_search_path() { - std::string output; + std::string processed_output; // Run - FILE *file = popen("/sbin/ldconfig -NXv 2> /dev/null", "r"); + int return_code; + const char *ldconfig_argv[] = {"/sbin/ldconfig", "-NXv", NULL}; + char *output = run_command(ldconfig_argv, &return_code); + std::stringstream output_stream((std::string(output))); + // Check Exit Code + if (return_code != 0) { + ERR("ldconfig Failed: Exit Code: %i", return_code); + } + // Read int running = 1; while (running) { - char *line = NULL; - size_t length = 0; - if (getline(&line, &length, file) != -1) { - // Convert to C++ String - std::string str(line); + std::string line; + if (std::getline(output_stream, line)) { // Remove Newline - if (str.size() > 0 && str[str.size() - 1] == '\n') { - str.pop_back(); + if (line.size() > 0 && line[line.size() - 1] == '\n') { + line.pop_back(); } // Interpret - if (str.size() >= 2 && str[0] != '\t' && str[str.size() - 1] == ':') { + if (line.size() >= 2 && line[0] != '\t' && line[line.size() - 1] == ':') { // Blacklist RPI Legacy GL Drivers #define RPI_LEGACY_GL_PATH "/opt/vc" - if (str.rfind(RPI_LEGACY_GL_PATH ":", 0) != 0 && str.rfind(RPI_LEGACY_GL_PATH "/", 0) != 0) { - output.append(str); + if (line.rfind(RPI_LEGACY_GL_PATH ":", 0) != 0 && line.rfind(RPI_LEGACY_GL_PATH "/", 0) != 0) { + processed_output.append(line); } } } else { running = 0; } - free(line); } + // Free Output + free(output); + // Remove Colon - if (output.size() > 0 && output[output.size() - 1] == ':') { - output.pop_back(); - } - // Close Process - int ret = pclose(file); - if (ret == -1) { - ERR("ldconfig Failed: %s", strerror(errno)); - } else if (ret != 0) { - ERR("ldconfig Failed: Exit Code: %i", ret); + if (processed_output.size() > 0 && processed_output[processed_output.size() - 1] == ':') { + processed_output.pop_back(); } + // Return - char *output_str = strdup(output.c_str()); + char *output_str = strdup(processed_output.c_str()); ALLOC_CHECK(output_str); return output_str; } diff --git a/libreborn/CMakeLists.txt b/libreborn/CMakeLists.txt index 6bddb82..3739236 100644 --- a/libreborn/CMakeLists.txt +++ b/libreborn/CMakeLists.txt @@ -1,12 +1,12 @@ project(libreborn) -add_library(reborn-headers INTERFACE) -target_include_directories(reborn-headers INTERFACE include) +add_library(reborn-util STATIC src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c) +target_include_directories(reborn-util PUBLIC include) if(BUILD_ARM_COMPONENTS) - add_library(reborn SHARED src/patch.c) - target_link_libraries(reborn dl reborn-headers) - target_compile_definitions(reborn PUBLIC -DREBORN_HAS_COMPILED_CODE) + add_library(reborn-patch SHARED src/patch/patch.c) + target_link_libraries(reborn-patch dl reborn-util) + target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE) # Install - install(TARGETS reborn DESTINATION "${MCPI_LIB_DIR}") + install(TARGETS reborn-patch DESTINATION "${MCPI_LIB_DIR}") endif() diff --git a/libreborn/include/libreborn/config.h b/libreborn/include/libreborn/config.h new file mode 100644 index 0000000..596d4fd --- /dev/null +++ b/libreborn/include/libreborn/config.h @@ -0,0 +1,3 @@ +#pragma once + +#define GUI_TITLE "Minecraft: Pi Edition: Reborn" diff --git a/libreborn/include/libreborn/elf.h b/libreborn/include/libreborn/elf.h index 5922ee5..fd62ef2 100644 --- a/libreborn/include/libreborn/elf.h +++ b/libreborn/include/libreborn/elf.h @@ -9,55 +9,14 @@ #include "log.h" #include "exec.h" +#ifdef __cplusplus +extern "C" { +#endif + // Find And Iterate Over All .text Sections In Current Binary typedef void (*text_section_callback_t)(ElfW(Addr) section, ElfW(Word) size, void *data); -static inline void iterate_text_sections(text_section_callback_t callback, void *data) { - // Load Main Binary - FILE *file_obj = fopen(getenv("MCPI_EXECUTABLE_PATH"), "rb"); +void iterate_text_sections(text_section_callback_t callback, void *data); - // Verify Binary - if (!file_obj) { - ERR("%s", "Unable To Open Current Binary"); - } - - // Get File Size - fseek(file_obj, 0L, SEEK_END); - long int file_size = ftell(file_obj); - fseek(file_obj, 0L, SEEK_SET); - - // Map File To Pointer - unsigned char *file_map = (unsigned char *) mmap(0, file_size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0); - - // Parse ELF - ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_map; - ElfW(Shdr) *elf_section_headers = (ElfW(Shdr) *) (file_map + elf_header->e_shoff); - int elf_section_header_count = elf_header->e_shnum; - - // Locate Section Names - ElfW(Shdr) elf_shstrtab = elf_section_headers[elf_header->e_shstrndx]; - unsigned char *elf_shstrtab_p = file_map + elf_shstrtab.sh_offset; - - // Track .text Sections - int text_sections = 0; - - // Iterate Sections - for (int i = 0; i < elf_section_header_count; ++i) { - ElfW(Shdr) header = elf_section_headers[i]; - char *name = (char *) (elf_shstrtab_p + header.sh_name); - // Check Section Type - if (strcmp(name, ".text") == 0) { - // .text Section - (*callback)(header.sh_addr, header.sh_size, data); - text_sections++; - } - } - - // Ensure At Least .text Section Was Scanned - if (text_sections < 1) { - ERR("%s", "Unable To Find .text Sectons"); - } - - // Unmap And Close File - munmap(file_map, file_size); - fclose(file_obj); +#ifdef __cplusplus } +#endif diff --git a/libreborn/include/libreborn/exec.h b/libreborn/include/libreborn/exec.h index 0b6106e..9c1d5b3 100644 --- a/libreborn/include/libreborn/exec.h +++ b/libreborn/include/libreborn/exec.h @@ -4,60 +4,34 @@ #include #include #include +#include +#include #include "log.h" #include "string.h" #include "util.h" +#ifdef __cplusplus +extern "C" { +#endif + // Safe execvpe() -__attribute__((noreturn)) static inline void safe_execvpe(const char *pathname, char *argv[], char *const envp[]) { - argv[0] = (char *) pathname; - int ret = execvpe(pathname, argv, envp); - if (ret == -1) { - ERR("Unable To Execute Program: %s: %s", pathname, strerror(errno)); - } else { - ERR("%s", "Unknown execvpe() Error"); - } -} +__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]); // Chop Off Last Component -static inline void chop_last_component(char **str) { - size_t length = strlen(*str); - for (size_t i = 0; i < length; i++) { - size_t j = length - i - 1; - if ((*str)[j] == '/') { - (*str)[j] = '\0'; - break; - } - } -} +void chop_last_component(char **str); // Get Binary Directory (Remember To Free) -static inline char *get_binary_directory() { - // Get Path To Current Executable - char *exe = realpath("/proc/self/exe", NULL); - ALLOC_CHECK(exe); - - // Chop Off Last Component - chop_last_component(&exe); - - // Return - return exe; -} +char *get_binary_directory(); // Safe execvpe() Relative To Binary -__attribute__((noreturn)) static inline void safe_execvpe_relative_to_binary(const char *pathname, char *argv[], char *const envp[]) { - // Get Binary Directory - char *binary_directory = get_binary_directory(); - // Create Full Path - char *full_path = NULL; - safe_asprintf(&full_path, "%s/%s", binary_directory, pathname); - // Free Binary Directory - free(binary_directory); - // Run - safe_execvpe(full_path, argv, envp); -} +__attribute__((noreturn)) void safe_execvpe_relative_to_binary(const char *const argv[], const char *const envp[]); // Get MCPI Directory -static inline char *get_mcpi_directory() { - return getenv("MCPI_DIRECTORY"); +char *get_mcpi_directory(); + +// Run Command And Get Output +char *run_command(const char *const command[], int *return_code); + +#ifdef __cplusplus } +#endif diff --git a/libreborn/include/libreborn/libreborn.h b/libreborn/include/libreborn/libreborn.h index fc969c1..35766b0 100644 --- a/libreborn/include/libreborn/libreborn.h +++ b/libreborn/include/libreborn/libreborn.h @@ -1,5 +1,6 @@ #pragma once +#include "config.h" #include "log.h" #include "util.h" #include "string.h" diff --git a/libreborn/include/libreborn/patch.h b/libreborn/include/libreborn/patch.h index e21eded..268e60e 100644 --- a/libreborn/include/libreborn/patch.h +++ b/libreborn/include/libreborn/patch.h @@ -6,7 +6,7 @@ extern "C" { // Patching Functions -#ifdef REBORN_HAS_COMPILED_CODE +#ifdef REBORN_HAS_PATCH_CODE void _overwrite_call(const char *file, int line, void *start, void *target); #define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target); @@ -23,7 +23,7 @@ void _patch(const char *file, int line, void *start, unsigned char patch[4]); 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 +#endif #ifdef __cplusplus } diff --git a/libreborn/include/libreborn/string.h b/libreborn/include/libreborn/string.h index d04573b..5679ef1 100644 --- a/libreborn/include/libreborn/string.h +++ b/libreborn/include/libreborn/string.h @@ -26,26 +26,13 @@ } \ } +#ifdef __cplusplus +extern "C" { +#endif + // Sanitize String -#define MINIMUM_SAFE_CHARACTER 32 -#define MAXIMUM_SAFE_CHARACTER 126 -static inline void sanitize_string(char **str, int max_length, unsigned int allow_newlines) { - // Store Message Length - int length = strlen(*str); - // Truncate Message - if (max_length != -1 && length > max_length) { - (*str)[max_length] = '\0'; - length = max_length; - } - // Loop Through Message - for (int i = 0; i < length; i++) { - if (allow_newlines && ((*str)[i] == '\n' || (*str)[i] == '\r')) { - continue; - } - unsigned char c = (unsigned char) (*str)[i]; - if (c < MINIMUM_SAFE_CHARACTER || c > MAXIMUM_SAFE_CHARACTER) { - // Replace Illegal Character - (*str)[i] = '?'; - } - } +void sanitize_string(char **str, int max_length, unsigned int allow_newlines); + +#ifdef __cplusplus } +#endif diff --git a/libreborn/include/libreborn/util.h b/libreborn/include/libreborn/util.h index b8372a4..186dbaf 100644 --- a/libreborn/include/libreborn/util.h +++ b/libreborn/include/libreborn/util.h @@ -43,9 +43,13 @@ } \ } +#ifdef __cplusplus +extern "C" { +#endif + // Safe Version Of pipe() -static inline void safe_pipe2(int pipefd[2], int flags) { - if (pipe2(pipefd, flags) != 0) { - ERR("Unable To Create Pipe: %s", strerror(errno)); - } +void safe_pipe2(int pipefd[2], int flags); + +#ifdef __cplusplus } +#endif diff --git a/libreborn/src/patch.c b/libreborn/src/patch/patch.c similarity index 99% rename from libreborn/src/patch.c rename to libreborn/src/patch/patch.c index 09fbc9c..02f467f 100644 --- a/libreborn/src/patch.c +++ b/libreborn/src/patch/patch.c @@ -11,7 +11,7 @@ #ifndef __arm__ #error "Patching Code Is ARM Only" -#endif // #ifndef __arm__ +#endif // BL Instruction Magic Number #define BL_INSTRUCTION 0xeb diff --git a/libreborn/src/util/elf.c b/libreborn/src/util/elf.c new file mode 100644 index 0000000..a449843 --- /dev/null +++ b/libreborn/src/util/elf.c @@ -0,0 +1,53 @@ +#include + +// Find And Iterate Over All .text Sections In Current Binary +void iterate_text_sections(text_section_callback_t callback, void *data) { + // Load Main Binary + FILE *file_obj = fopen(getenv("MCPI_EXECUTABLE_PATH"), "rb"); + + // Verify Binary + if (!file_obj) { + ERR("%s", "Unable To Open Current Binary"); + } + + // Get File Size + fseek(file_obj, 0L, SEEK_END); + long int file_size = ftell(file_obj); + fseek(file_obj, 0L, SEEK_SET); + + // Map File To Pointer + unsigned char *file_map = (unsigned char *) mmap(0, file_size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0); + + // Parse ELF + ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_map; + ElfW(Shdr) *elf_section_headers = (ElfW(Shdr) *) (file_map + elf_header->e_shoff); + int elf_section_header_count = elf_header->e_shnum; + + // Locate Section Names + ElfW(Shdr) elf_shstrtab = elf_section_headers[elf_header->e_shstrndx]; + unsigned char *elf_shstrtab_p = file_map + elf_shstrtab.sh_offset; + + // Track .text Sections + int text_sections = 0; + + // Iterate Sections + for (int i = 0; i < elf_section_header_count; ++i) { + ElfW(Shdr) header = elf_section_headers[i]; + char *name = (char *) (elf_shstrtab_p + header.sh_name); + // Check Section Type + if (strcmp(name, ".text") == 0) { + // .text Section + (*callback)(header.sh_addr, header.sh_size, data); + text_sections++; + } + } + + // Ensure At Least .text Section Was Scanned + if (text_sections < 1) { + ERR("%s", "Unable To Find .text Sectons"); + } + + // Unmap And Close File + munmap(file_map, file_size); + fclose(file_obj); +} diff --git a/libreborn/src/util/exec.c b/libreborn/src/util/exec.c new file mode 100644 index 0000000..82be982 --- /dev/null +++ b/libreborn/src/util/exec.c @@ -0,0 +1,113 @@ +#include + +// Safe execvpe() +__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) { + int ret = execvpe(argv[0], (char *const *) argv, (char *const *) envp); + if (ret == -1) { + ERR("Unable To Execute Program: %s: %s", argv[0], strerror(errno)); + } else { + IMPOSSIBLE(); + } +} + +// Chop Off Last Component +void chop_last_component(char **str) { + size_t length = strlen(*str); + for (size_t i = 0; i < length; i++) { + size_t j = length - i - 1; + if ((*str)[j] == '/') { + (*str)[j] = '\0'; + break; + } + } +} +// Get Binary Directory (Remember To Free) +char *get_binary_directory() { + // Get Path To Current Executable + char *exe = realpath("/proc/self/exe", NULL); + ALLOC_CHECK(exe); + + // Chop Off Last Component + chop_last_component(&exe); + + // Return + return exe; +} + +// Safe execvpe() Relative To Binary +__attribute__((noreturn)) void safe_execvpe_relative_to_binary(const char *const argv[], const char *const envp[]) { + // Get Binary Directory + char *binary_directory = get_binary_directory(); + // Create Full Path + char *full_path = NULL; + safe_asprintf(&full_path, "%s/%s", binary_directory, argv[0]); + // Free Binary Directory + free(binary_directory); + + // Build New argv + int argc; + for (argc = 0; argv[argc] != NULL; argc++); + const char *new_argv[argc + 1]; + for (int i = 1; i < argc; i++) { + new_argv[i] = argv[i]; + } + new_argv[0] = full_path; + new_argv[argc] = NULL; + // Run + safe_execvpe(new_argv, envp); +} + +// Get MCPI Directory +char *get_mcpi_directory() { + return getenv("MCPI_DIRECTORY"); +} + +// Run Command And Get Output +char *run_command(const char *const command[], int *return_code) { + // Store Output + int output_pipe[2]; + safe_pipe2(output_pipe, 0); + // Run + pid_t ret = fork(); + if (ret == -1) { + ERR("Unable To Run Command: %s", strerror(errno)); + } else if (ret == 0) { + // Child Process + + // Pipe stdout + dup2(output_pipe[1], STDOUT_FILENO); + close(output_pipe[0]); + close(output_pipe[1]); + + // Close stderr (But Not In Debug Mode) + const char *is_debug = getenv("MCPI_DEBUG"); + if (is_debug == NULL || strlen(is_debug) < 1) { + int null_fd = open("/dev/null", O_WRONLY); + dup2(null_fd, STDERR_FILENO); + close(null_fd); + } + + // Run + safe_execvpe(command, (const char *const *) environ); + } else { + // Parent Process + + // Read stdout + close(output_pipe[1]); + char *output = NULL; + char c; + int bytes_read = 0; + while ((bytes_read = read(output_pipe[0], (void *) &c, 1)) > 0) { + string_append(&output, "%c", c); + } + close(output_pipe[0]); + + // Get Return Code + int status; + waitpid(ret, &status, 0); + *return_code = WIFEXITED(status) ? WEXITSTATUS(status) : -1; + + // Return + return output; + } +} diff --git a/libreborn/src/util/string.c b/libreborn/src/util/string.c new file mode 100644 index 0000000..55f2d63 --- /dev/null +++ b/libreborn/src/util/string.c @@ -0,0 +1,25 @@ +#include + +// Sanitize String +#define MINIMUM_SAFE_CHARACTER 32 +#define MAXIMUM_SAFE_CHARACTER 126 +void sanitize_string(char **str, int max_length, unsigned int allow_newlines) { + // Store Message Length + int length = strlen(*str); + // Truncate Message + if (max_length != -1 && length > max_length) { + (*str)[max_length] = '\0'; + length = max_length; + } + // Loop Through Message + for (int i = 0; i < length; i++) { + if (allow_newlines && ((*str)[i] == '\n' || (*str)[i] == '\r')) { + continue; + } + unsigned char c = (unsigned char) (*str)[i]; + if (c < MINIMUM_SAFE_CHARACTER || c > MAXIMUM_SAFE_CHARACTER) { + // Replace Illegal Character + (*str)[i] = '?'; + } + } +} diff --git a/libreborn/src/util/util.c b/libreborn/src/util/util.c new file mode 100644 index 0000000..38a9561 --- /dev/null +++ b/libreborn/src/util/util.c @@ -0,0 +1,8 @@ +#include + +// Safe Version Of pipe() +void safe_pipe2(int pipefd[2], int flags) { + if (pipe2(pipefd, flags) != 0) { + ERR("Unable To Create Pipe: %s", strerror(errno)); + } +} diff --git a/media-layer/core/CMakeLists.txt b/media-layer/core/CMakeLists.txt index 31c7781..41759bf 100644 --- a/media-layer/core/CMakeLists.txt +++ b/media-layer/core/CMakeLists.txt @@ -20,7 +20,7 @@ endif() # Configure Media Layer Core If Built if(TARGET media-layer-core) # Link - target_link_libraries(media-layer-core media-layer-headers reborn-headers pthread dl) + target_link_libraries(media-layer-core media-layer-headers reborn-util pthread dl) if(NOT MCPI_HEADLESS_MODE) # Find FreeImage find_library(FREEIMAGE_LIBRARY NAMES freeimage libfreeimage.so.3 REQUIRED) diff --git a/media-layer/core/src/media.c b/media-layer/core/src/media.c index 01c9f34..0e79e22 100644 --- a/media-layer/core/src/media.c +++ b/media-layer/core/src/media.c @@ -6,7 +6,7 @@ #ifndef MCPI_HEADLESS_MODE #define GLFW_INCLUDE_NONE #include -#endif // #ifndef MCPI_HEADLESS_MODE +#endif #include #include @@ -14,7 +14,7 @@ #ifndef MCPI_HEADLESS_MODE #include "audio/engine.h" -#endif // #ifndef MCPI_HEADLESS_MODE +#endif // Allow Disabling Interaction static void update_cursor(); @@ -222,7 +222,7 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_ } } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif // Track Media Layer State static int is_running = 0; @@ -235,7 +235,7 @@ void media_set_raw_mouse_motion_enabled(int enabled) { if (is_running) { glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif if (!raw_mouse_motion_enabled) { WARN("%s", "Raw mouse motion has been DISABLED, this IS NOT recommended, and should only ever be used on systems that don't support or have broken raw mouse motion."); } @@ -249,7 +249,7 @@ void media_disable_vsync() { if (is_running) { glfwSwapInterval(0); } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif } // Init Media Layer @@ -289,9 +289,9 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic // Init OpenAL _media_audio_init(); -#else // #ifndef MCPI_HEADLESS_MODE +#else (void) title; // Mark As Used -#endif // #ifndef MCPI_HEADLESS_MODE +#endif // Set State is_running = 1; @@ -307,7 +307,7 @@ void media_swap_buffers() { #ifndef MCPI_HEADLESS_MODE // Don't Swap Buffers In A Context-Less Window glfwSwapBuffers(glfw_window); -#endif // #ifndef MCPI_HEADLESS_MODE +#endif } // Fullscreen Not Needed In Headless Mode @@ -340,10 +340,10 @@ void media_toggle_fullscreen() { } is_fullscreen = !is_fullscreen; } -#else // #ifndef MCPI_HEADLESS_MODE +#else void media_toggle_fullscreen() { } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif // Intercept SDL Events void _media_handle_SDL_PollEvent() { @@ -359,7 +359,7 @@ void _media_handle_SDL_PollEvent() { SDL_PushEvent(&event); glfwSetWindowShouldClose(glfw_window, GLFW_FALSE); } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif } // Cleanup Media Layer @@ -376,7 +376,7 @@ void media_cleanup() { // Cleanup OpenAL _media_audio_cleanup(); -#endif // #ifndef MCPI_HEADLESS_MODE +#endif // Update State is_running = 0; @@ -437,7 +437,7 @@ static void update_cursor() { } } } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif } // Fix SDL Cursor Visibility/Grabbing @@ -483,7 +483,7 @@ void media_get_framebuffer_size(int *width, int *height) { glfwGetFramebufferSize(glfw_window, width, height); return; } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif *width = DEFAULT_WIDTH; *height = DEFAULT_HEIGHT; } diff --git a/media-layer/core/src/screenshot.c b/media-layer/core/src/screenshot.c index 42f00d0..f883bee 100644 --- a/media-layer/core/src/screenshot.c +++ b/media-layer/core/src/screenshot.c @@ -122,8 +122,8 @@ __attribute__((constructor)) static void init() { FreeImage_Initialise(0); } -#else // #ifndef MCPI_HEADLESS_MODE +#else void media_take_screenshot() { // NOP } -#endif // #ifndef MCPI_HEADLESS_MODE +#endif diff --git a/media-layer/proxy/CMakeLists.txt b/media-layer/proxy/CMakeLists.txt index 3e8d9fc..e421e91 100644 --- a/media-layer/proxy/CMakeLists.txt +++ b/media-layer/proxy/CMakeLists.txt @@ -9,7 +9,7 @@ if(BUILD_NATIVE_COMPONENTS) # Build Media Layer Proxy Client add_executable(media-layer-proxy-client src/client/client.cpp ${MEDIA_LAYER_PROXY_SRC}) - target_link_libraries(media-layer-proxy-client media-layer-headers reborn-headers ${MEDIA_LAYER_PROXY_LIBS}) + target_link_libraries(media-layer-proxy-client media-layer-headers reborn-util ${MEDIA_LAYER_PROXY_LIBS}) target_compile_definitions(media-layer-proxy-client PRIVATE -DMEDIA_LAYER_PROXY_CLIENT) # Install install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_BIN_DIR}") @@ -20,7 +20,7 @@ if(BUILD_ARM_COMPONENTS) # Build Media Layer Proxy Server add_library(media-layer-core SHARED src/server/server.cpp ${MEDIA_LAYER_PROXY_SRC}) - target_link_libraries(media-layer-core media-layer-headers reborn-headers) + target_link_libraries(media-layer-core media-layer-headers reborn-util) target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_PROXY_SERVER) # Symlink GLESv1_CM To Media Layer Proxy Server install_symlink("libmedia-layer-core.so" "${MCPI_LIB_DIR}/libGLESv1_CM.so.1") diff --git a/media-layer/proxy/src/server/server.cpp b/media-layer/proxy/src/server/server.cpp index f84b68e..606955d 100644 --- a/media-layer/proxy/src/server/server.cpp +++ b/media-layer/proxy/src/server/server.cpp @@ -77,10 +77,10 @@ static void start_media_layer_proxy_client(int read, int write) { safe_asprintf(&read_str, "%i", read); char *write_str = NULL; safe_asprintf(&write_str, "%i", write); - char *argv[] = {NULL /* Updated By safe_execvpe() */, read_str, write_str, NULL}; + const char *argv[] = {"media-layer-proxy-client", read_str, write_str, NULL}; // Run - safe_execvpe("media-layer-proxy-client", argv, environ); + safe_execvpe(argv, (const char *const *) environ); } else { // Parent Process _client_pid = ret; diff --git a/media-layer/stubs/CMakeLists.txt b/media-layer/stubs/CMakeLists.txt index ca0347a..10ac05c 100644 --- a/media-layer/stubs/CMakeLists.txt +++ b/media-layer/stubs/CMakeLists.txt @@ -14,11 +14,11 @@ if(BUILD_ARM_COMPONENTS) # Stub EGL add_library(EGL SHARED src/EGL.c) - target_link_libraries(EGL reborn-headers media-layer-headers) + target_link_libraries(EGL reborn-util media-layer-headers) set_target_properties(EGL PROPERTIES SOVERSION "1") # Stub X11 add_library(X11 SHARED src/X11.c) - target_link_libraries(X11 reborn-headers media-layer-headers) + target_link_libraries(X11 reborn-util media-layer-headers) set_target_properties(X11 PROPERTIES SOVERSION "6") # Install if(MCPI_HEADLESS_MODE OR MCPI_USE_MEDIA_LAYER_PROXY) diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 8231239..b454528 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -8,80 +8,80 @@ add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) ## Mods add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c) -target_link_libraries(compat reborn media-layer-core) +target_link_libraries(compat reborn-patch media-layer-core) add_library(readdir SHARED src/readdir/readdir.c) add_library(feature SHARED src/feature/feature.c) -target_link_libraries(feature reborn) +target_link_libraries(feature reborn-patch) add_library(version SHARED src/version/version.cpp) -target_link_libraries(version reborn symbols) +target_link_libraries(version reborn-patch symbols) add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c) -target_link_libraries(chat reborn symbols feature pthread) +target_link_libraries(chat reborn-patch symbols feature pthread) if(MCPI_SERVER_MODE) add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp) - target_link_libraries(server reborn symbols feature home misc compat dl media-layer-core pthread) + target_link_libraries(server reborn-patch symbols feature home misc compat dl media-layer-core pthread) else() target_link_libraries(compat input sign chat home dl) target_link_libraries(chat input) add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp) - target_link_libraries(multiplayer reborn symbols home feature) + target_link_libraries(multiplayer reborn-patch symbols home feature) add_library(sound SHARED src/sound/sound.cpp src/sound/repository.cpp) - target_link_libraries(sound reborn symbols feature override media-layer-core) + target_link_libraries(sound reborn-patch symbols feature override media-layer-core) add_library(camera SHARED src/camera/camera.cpp) - target_link_libraries(camera reborn symbols media-layer-core feature home) + target_link_libraries(camera reborn-patch symbols media-layer-core feature home) add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp) - target_link_libraries(input reborn symbols creative feature media-layer-core) + target_link_libraries(input reborn-patch symbols creative feature media-layer-core) add_library(sign SHARED src/sign/sign.cpp) - target_link_libraries(sign reborn symbols feature input) + target_link_libraries(sign reborn-patch symbols feature input) add_library(creative SHARED src/creative/creative.cpp) - target_link_libraries(creative reborn symbols feature) + target_link_libraries(creative reborn-patch symbols feature) add_library(touch SHARED src/touch/touch.c) - target_link_libraries(touch reborn symbols feature) + target_link_libraries(touch reborn-patch symbols feature) add_library(override SHARED src/override/override.c) - target_link_libraries(override reborn symbols dl home) + target_link_libraries(override reborn-patch symbols dl home) add_library(textures SHARED src/textures/textures.cpp) - target_link_libraries(textures reborn symbols media-layer-core feature) + target_link_libraries(textures reborn-patch symbols media-layer-core feature) add_library(atlas SHARED src/atlas/atlas.cpp) - target_link_libraries(atlas reborn symbols feature GLESv1_CM) + target_link_libraries(atlas reborn-patch symbols feature GLESv1_CM) if(NOT MCPI_HEADLESS_MODE) add_library(benchmark SHARED src/benchmark/benchmark.cpp) - target_link_libraries(benchmark reborn symbols compat misc media-layer-core) + target_link_libraries(benchmark reborn-patch symbols compat misc media-layer-core) endif() endif() add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp) -target_link_libraries(game-mode reborn symbols feature) +target_link_libraries(game-mode reborn-patch symbols feature) add_library(death SHARED src/death/death.cpp) -target_link_libraries(death reborn symbols feature) +target_link_libraries(death reborn-patch symbols feature) add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp) -target_link_libraries(misc reborn symbols feature GLESv1_CM) +target_link_libraries(misc reborn-patch symbols feature GLESv1_CM) add_library(options SHARED src/options/options.c) -target_link_libraries(options reborn symbols feature) +target_link_libraries(options reborn-patch symbols feature) add_library(home SHARED src/home/home.c) -target_link_libraries(home reborn symbols) +target_link_libraries(home reborn-patch symbols) add_library(test SHARED src/test/test.c) -target_link_libraries(test reborn home) +target_link_libraries(test reborn-patch home) add_library(init SHARED src/init/init.c) target_link_libraries(init compat game-mode misc death options chat home version test media-layer-core) diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index f086b7e..6435ce7 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -11,7 +11,7 @@ #include "../feature/feature.h" #ifndef MCPI_SERVER_MODE #include "../input/input.h" -#endif // #ifndef MCPI_SERVER_MODE +#endif #include "chat.h" // Store If Chat is Enabled @@ -39,7 +39,7 @@ static void send_api_chat_command(unsigned char *minecraft, char *str) { send_api_command(minecraft, command); free(command); } -#endif // #ifndef MCPI_SERVER_MODE +#endif // Send Message To Players static void send_message(unsigned char *server_side_network_handler, char *username, char *message) { @@ -115,7 +115,7 @@ static void send_queued_messages(unsigned char *minecraft) { // Unlock pthread_mutex_unlock(&queue_mutex); } -#endif // #ifndef MCPI_SERVER_MODE +#endif // Init void init_chat() { @@ -131,6 +131,6 @@ void init_chat() { // Send Messages On Input Tick #ifndef MCPI_SERVER_MODE input_run_on_tick(send_queued_messages); -#endif // #ifndef MCPI_SERVER_MODE +#endif } } diff --git a/mods/src/chat/ui.c b/mods/src/chat/ui.c index c316ab0..c303f4d 100644 --- a/mods/src/chat/ui.c +++ b/mods/src/chat/ui.c @@ -10,27 +10,13 @@ #include "../input/input.h" // Run Command -static char *run_command(char *command, int *return_code) { +static char *run_command_proper(const char *command[], int *return_code) { // Prepare Environment RESET_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH"); RESET_ENVIRONMENTAL_VARIABLE("LD_PRELOAD"); - // Start - FILE *out = popen(command, "r"); - if (!out) { - ERR("%s", "Failed To Run Command"); - } - - // Record - char *output = NULL; - int c; - while ((c = fgetc(out)) != EOF) { - string_append(&output, "%c", (char) c); - } - - // Return - *return_code = WEXITSTATUS(pclose(out)); - return output; + // Run + return run_command(command, return_code); } // Count Chat Windows @@ -44,7 +30,8 @@ unsigned int chat_get_counter() { static void *chat_thread(__attribute__((unused)) void *nop) { // Open int return_code; - char *output = run_command("zenity --title 'Chat' --class 'Minecraft: Pi Edition: Reborn' --entry --text 'Enter Chat Message:'", &return_code); + const char *command[] = {"zenity", "--title", "Chat", "--class", GUI_TITLE, "--entry", "--text", "Enter Chat Message:", NULL}; + char *output = run_command_proper(command, &return_code); // Handle Message if (output != NULL) { // Check Return Code @@ -87,4 +74,4 @@ void chat_open() { pthread_create(&thread, NULL, chat_thread, NULL); } } -#endif // #ifndef MCPI_SERVER_MODE +#endif diff --git a/mods/src/compat/compat.c b/mods/src/compat/compat.c index 5c2e0e8..4ed17dd 100644 --- a/mods/src/compat/compat.c +++ b/mods/src/compat/compat.c @@ -18,7 +18,7 @@ // Custom Title HOOK(SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) { ensure_SDL_WM_SetCaption(); - (*real_SDL_WM_SetCaption)("Minecraft: Pi Edition: Reborn", icon); + (*real_SDL_WM_SetCaption)(GUI_TITLE, icon); } // Mouse Cursor Is Always Invisible In Vanilla MCPI @@ -106,7 +106,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) { return ret; } -#endif // #ifndef MCPI_SERVER_MODE +#endif // Exit Handler static void exit_handler(__attribute__((unused)) int data) { diff --git a/mods/src/options/options.c b/mods/src/options/options.c index 81bfe09..dc1cf68 100644 --- a/mods/src/options/options.c +++ b/mods/src/options/options.c @@ -30,7 +30,7 @@ static int get_render_distance() { ERR("Invalid Render Distance: %s", distance_str); } } -#endif // #ifndef MCPI_SERVER_MODE +#endif // Get Custom Username static char *get_username() { @@ -86,9 +86,9 @@ void init_options() { #ifndef MCPI_SERVER_MODE render_distance = get_render_distance(); INFO("Setting Render Distance: %i", render_distance); -#else // #ifndef MCPI_SERVER_MODE +#else render_distance = 3; -#endif // #ifndef MCPI_SERVER_MODE +#endif // Server Visible server_visible = !feature_has("Disable Hosting LAN Worlds", 0); @@ -99,7 +99,7 @@ void init_options() { const char *username = get_username(); #ifndef MCPI_SERVER_MODE INFO("Setting Username: %s", username); -#endif // #ifndef MCPI_SERVER_MODE +#endif if (strcmp(*default_username, "StevePi") != 0) { ERR("%s", "Default Username Is Invalid"); }