AppImage Fixes

pull/39/head
TheBrokenRail 10 months ago
parent 5467b5178f
commit bfcdd3c7e9

1
.gitignore vendored

@ -6,5 +6,6 @@ CMakeLists.txt.user
*.autosave
AppImageBuilder.yml
appimage-builder-cache
appimage-build
AppDir
*.zsync

@ -180,7 +180,7 @@ void pre_bootstrap() {
// Bootstrap
void bootstrap(int argc, char *argv[]) {
INFO("%s", "Configuring Game...");
INFO("Configuring Game...");
// Get Binary Directory
char *binary_directory = get_binary_directory();
@ -197,7 +197,7 @@ void bootstrap(int argc, char *argv[]) {
// Resolve Binary Path & Set MCPI_DIRECTORY
{
// Log
DEBUG("%s", "Resolving File Paths...");
DEBUG("Resolving File Paths...");
// Resolve Full Binary Path
char *full_path = NULL;
@ -218,21 +218,22 @@ void bootstrap(int argc, char *argv[]) {
// Fix MCPI Dependencies
{
// Log
DEBUG("%s", "Patching ELF Dependencies...");
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = NULL;
// Preserve Existing Linker On ARM
#ifndef __arm__
safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix);
#else
safe_asprintf(&linker, "/lib/ld-linux-armhf.so.3");
#endif
// Patch
patch_mcpi_elf_dependencies(linker);
// Free Linker Path
free(linker);
if (linker != NULL) {
free(linker);
}
// Verify
if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) {
@ -243,7 +244,7 @@ void bootstrap(int argc, char *argv[]) {
// Configure LD_LIBRARY_PATH
{
// Log
DEBUG("%s", "Setting Linker Search Paths...");
DEBUG("Setting Linker Search Paths...");
// Preserve
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
@ -271,7 +272,7 @@ void bootstrap(int argc, char *argv[]) {
// Configure LD_PRELOAD
{
// Log
DEBUG("%s", "Locating Mods...");
DEBUG("Locating Mods...");
// Preserve
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
@ -316,7 +317,7 @@ void bootstrap(int argc, char *argv[]) {
free(binary_directory);
// Start Game
INFO("%s", "Starting Game...");
INFO("Starting Game...");
// Arguments
int argv_start = 1; // argv = &new_args[argv_start]

@ -31,7 +31,7 @@ static std::string strip_feature_flag_default(std::string flag, bool *default_re
return flag.substr(false_str.length(), std::string::npos);
} else {
// Invalid
ERR("%s", "Invalid Feature Flag Default");
ERR("Invalid Feature Flag Default");
}
}
@ -55,7 +55,7 @@ static void load_available_feature_flags(std::function<void(std::string)> callba
lines.push_back(line);
} else {
// Invalid Line
ERR("%s", "Feature Flag Contains Invalid '|'");
ERR("Feature Flag Contains Invalid '|'");
}
}
}
@ -75,7 +75,7 @@ static void load_available_feature_flags(std::function<void(std::string)> callba
// Close File
stream.close();
} else {
ERR("%s", "Unable To Load Available Feature Flags");
ERR("Unable To Load Available Feature Flags");
}
}
@ -99,7 +99,7 @@ static void run_command_and_set_env(const char *env_name, const char *command[])
}
// Check Return Code
if (return_code != 0) {
ERR("%s", "Launch Interrupted");
ERR("Launch Interrupted");
}
}
}

@ -56,6 +56,25 @@ static void duplicate_mcpi_executable() {
}
// Fix MCPI Dependencies
#define patch_mcpi_elf_dependencies_with_extra_patchelf_args(...) \
({ \
const char *const _macro_command[] = { \
"patchelf", \
##__VA_ARGS__, \
"--remove-needed", "libbcm_host.so", \
"--remove-needed", "libX11.so.6", \
"--remove-needed", "libEGL.so", \
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
exe, \
NULL \
}; \
int _macro_return_code = 0; \
char *_macro_output = run_command(_macro_command, &_macro_return_code); \
if (_macro_output != NULL) { \
free(_macro_output); \
} \
_macro_return_code; \
})
void patch_mcpi_elf_dependencies(const char *linker) {
// Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable();
@ -64,20 +83,11 @@ void patch_mcpi_elf_dependencies(const char *linker) {
char *exe = getenv("MCPI_EXECUTABLE_PATH");
// Run patchelf
const char *const command[] = {
"patchelf",
"--set-interpreter", linker,
"--remove-needed", "libbcm_host.so",
"--remove-needed", "libX11.so.6",
"--remove-needed", "libEGL.so",
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1",
exe,
NULL
};
int return_code = 0;
char *output = run_command(command, &return_code);
if (output != NULL) {
free(output);
int return_code;
if (linker == NULL) {
return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args();
} else {
return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args("--set-interpreter", linker);
}
if (return_code != 0) {
ERR("patchelf Failed: Exit Code: %i", return_code);

@ -4,8 +4,8 @@
#include <stdlib.h>
// Logging
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); }
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); }
#define DEBUG(format, ...) { const char *debug = getenv("MCPI_DEBUG"); if (debug != NULL && strlen(debug) > 0) { fprintf(stderr, "[DEBUG]: " format "\n", __VA_ARGS__); } }
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, __VA_ARGS__); exit(EXIT_FAILURE); }
#define IMPOSSIBLE() ERR("%s", "This Should Never Be Called")
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", ##__VA_ARGS__); }
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", ##__VA_ARGS__); }
#define DEBUG(format, ...) { const char *debug = getenv("MCPI_DEBUG"); if (debug != NULL && strlen(debug) > 0) { fprintf(stderr, "[DEBUG]: " format "\n", ##__VA_ARGS__); } }
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); }
#define IMPOSSIBLE() ERR("This Should Never Be Called")

@ -11,7 +11,7 @@
#define ALLOC_CHECK(obj) \
{ \
if (obj == NULL) { \
ERR("%s", "Memory Allocation Failed"); \
ERR("Memory Allocation Failed"); \
} \
}

@ -82,7 +82,7 @@ static void update_code_block(void *target) {
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
}
if (code_block_remaining < CODE_SIZE) {
ERR("%s", "Maximum Amount Of overwrite_calls() Uses Reached");
ERR("Maximum Amount Of overwrite_calls() Uses Reached");
}
_overwrite(NULL, -1, code_block, target);
}
@ -115,7 +115,7 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) {
data.replacement = code_block;
data.found = 0;
iterate_text_sections("/proc/self/exe", overwrite_calls_callback, &data);
iterate_text_sections(getenv("MCPI_EXECUTABLE_PATH"), overwrite_calls_callback, &data);
// Increment Code Block Position
increment_code_block();
@ -141,7 +141,7 @@ void _overwrite(const char *file, int line, void *start, void *target) {
// Patch Instruction
void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
if (((uint32_t) start) % 4 != 0) {
ERR("%s", "Invalid Address");
ERR("Invalid Address");
}
size_t page_size = sysconf(_SC_PAGESIZE);

@ -7,7 +7,7 @@ void iterate_text_sections(const char *exe, text_section_callback_t callback, vo
// Verify Binary
if (!file_obj) {
ERR("%s", "Unable To Open Binary");
ERR("Unable To Open Binary");
}
// Get File Size
@ -44,7 +44,7 @@ void iterate_text_sections(const char *exe, text_section_callback_t callback, vo
// Ensure At Least .text Section Was Scanned
if (text_sections < 1) {
ERR("%s", "Unable To Find .text Sectons");
ERR("Unable To Find .text Sectons");
}
// Unmap And Close File

@ -100,7 +100,7 @@ char *run_command(const char *const command[], int *return_code) {
size_t bytes_read = 0;
while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */)) > 0) {
buf[bytes_read] = '\0';
string_append(&output, "%s", buf);
string_append(&output, buf);
}
close(output_pipe[0]);

@ -22,7 +22,7 @@ void _media_audio_init() {
// Open Device
device = alcOpenDevice(NULL);
if (!device) {
WARN("%s", "Unable To Load Audio Engine");
WARN("Unable To Load Audio Engine");
return;
}
@ -48,7 +48,7 @@ void _media_audio_init() {
}
// Log
INFO("%s", "Loaded Audio Engine");
INFO("Loaded Audio Engine");
is_loaded = 1;
}
@ -80,6 +80,6 @@ void _media_audio_cleanup() {
}
// Log
INFO("%s", "Unloaded Audio Engine");
INFO("Unloaded Audio Engine");
}
}

@ -225,7 +225,7 @@ ALuint _media_audio_get_buffer(const char *source, const char *name) {
return _media_audio_get_buffer(source, name);
}
} else {
ERR("%s", "Audio Engine Isn't Loaded");
ERR("Audio Engine Isn't Loaded");
}
}

@ -237,7 +237,7 @@ void media_set_raw_mouse_motion_enabled(int enabled) {
}
#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.");
WARN("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.");
}
}
@ -260,7 +260,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
glfwSetErrorCallback(glfw_error);
if (!glfwInit()) {
ERR("%s", "Unable To Initialize GLFW");
ERR("Unable To Initialize GLFW");
}
// Create OpenGL ES 1.1 Context
@ -275,7 +275,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
glfw_window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, NULL, NULL);
if (!glfw_window) {
ERR("%s", "Unable To Create GLFW Window");
ERR("Unable To Create GLFW Window");
}
// Don't Process Events In Headless Mode

@ -36,6 +36,6 @@ __attribute__ ((noreturn)) void SDL_Quit() {
while (wait(NULL) > 0) {}
// Exit
INFO("%s", "Stopped");
INFO("Stopped");
exit(EXIT_SUCCESS);
}

@ -58,7 +58,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
GLint current_buffer = 0; \
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_buffer); \
if (current_buffer == 0) { \
PROXY_ERR("%s", "gl*Pointer() Functions Are Only Supported When A Buffer Is Bound To GL_ARRAY_BUFFER"); \
PROXY_ERR("gl*Pointer() Functions Are Only Supported When A Buffer Is Bound To GL_ARRAY_BUFFER"); \
} \
GLint size = (GLint) read_int(); \
GLenum type = (GLenum) read_int(); \

@ -33,7 +33,7 @@ void _check_proxy_state() {
// Check Server State
if (!parent_is_alive) {
void_write_cache(); // Parent Is Dead, No Reason To Send A Dead Process Data
PROXY_ERR("%s", "Server Terminated");
PROXY_ERR("Server Terminated");
}
}
@ -54,12 +54,12 @@ int main(int argc, char *argv[]) {
// Get Connection
if (argc != 3) {
PROXY_ERR("%s", "Invalid Arguments");
PROXY_ERR("Invalid Arguments");
}
char *read_str = argv[1];
char *write_str = argv[2];
set_connection(atoi(read_str), atoi(write_str));
PROXY_INFO("%s", "Connected");
PROXY_INFO("Connected");
// Send Connection Message
write_string((char *) CONNECTED_MSG);
@ -86,6 +86,6 @@ int main(int argc, char *argv[]) {
}
// Exit
PROXY_INFO("%s", "Stopped");
PROXY_INFO("Stopped");
return 0;
}

@ -9,13 +9,13 @@
{ \
_check_proxy_state(); \
if (!is_connection_open()) { \
PROXY_ERR("%s", "Attempting To Access Closed Connection"); \
PROXY_ERR("Attempting To Access Closed Connection"); \
} \
}
void safe_read(void *buf, size_t len) {
// Check Data
if (buf == NULL) {
PROXY_ERR("%s", "Attempting To Read Into NULL Buffer");
PROXY_ERR("Attempting To Read Into NULL Buffer");
}
// Flush Write Cache
flush_write_cache();
@ -42,7 +42,7 @@ static size_t _write_cache_position = 0;
void safe_write(void *buf, size_t len) {
// Check Data
if (buf == NULL) {
PROXY_ERR("%s", "Attempting To Send NULL Data");
PROXY_ERR("Attempting To Send NULL Data");
}
// Expand Write Cache If Needed
size_t needed_size = _write_cache_position + len;
@ -165,7 +165,7 @@ void close_connection() {
}
set_connection(-1, -1);
if (state_changed) {
PROXY_INFO("%s", "Connection Closed");
PROXY_INFO("Connection Closed");
}
}
// Check If Connection Is Open

@ -22,8 +22,8 @@ extern "C" {
#define CONNECTED_MSG "Connected"
#define PROXY_INFO(format, ...) INFO(PROXY_LOG_TAG format, __VA_ARGS__);
#define PROXY_ERR(format, ...) { close_connection(); ERR(PROXY_LOG_TAG format, __VA_ARGS__); }
#define PROXY_INFO(format, ...) INFO(PROXY_LOG_TAG format, ##__VA_ARGS__);
#define PROXY_ERR(format, ...) { close_connection(); ERR(PROXY_LOG_TAG format, ##__VA_ARGS__); }
// Safely Send/Receive Data From The Connection
__attribute__((visibility("internal"))) void safe_read(void *buf, size_t len);

@ -31,7 +31,7 @@ void _check_proxy_state() {
} else if (WIFSIGNALED(_client_status)) {
PROXY_ERR("Client Terminated: Signal: %i%s", WTERMSIG(_client_status), WCOREDUMP(_client_status) ? " (Core Dumped)" : "");
} else {
PROXY_ERR("%s", "Client Terminated");
PROXY_ERR("Client Terminated");
}
}
}
@ -95,7 +95,7 @@ __attribute__((constructor)) void media_ensure_loaded() {
loaded = 1;
// Log
PROXY_INFO("%s", "Starting...");
PROXY_INFO("Starting...");
// Create Connection
int server_to_client_pipe[2];
@ -111,9 +111,9 @@ __attribute__((constructor)) void media_ensure_loaded() {
// Wait For Connection Message
char *str = read_string();
if (strcmp(str, CONNECTED_MSG) == 0) {
PROXY_INFO("%s", "Connected");
PROXY_INFO("Connected");
} else {
PROXY_ERR("%s", "Unable To Connect");
PROXY_ERR("Unable To Connect");
}
// Free
free(str);

@ -38,7 +38,7 @@ __attribute__((constructor)) static void _init_active(int argc, char *argv[]) {
// Create/Start World
static void start_world(unsigned char *minecraft) {
// Log
INFO("%s", "Loading Benchmark");
INFO("Loading Benchmark");
// Specify Level Settings
LevelSettings settings;

@ -89,7 +89,7 @@ static void Minecraft_update_injection(unsigned char *minecraft) {
// Log When Game Is Saved
void Level_saveLevelData_injection(unsigned char *level) {
// Print Log Message
INFO("%s", "Saving Game");
INFO("Saving Game");
// Call Original Method
(*Level_saveLevelData)(level);

@ -92,7 +92,7 @@ static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit
// formatting functionality.
static unsigned char *RakNet_RakString_injection(unsigned char *rak_string, const char *format, ...) {
// Call Original Method
return (*RakNet_RakString)(rak_string, "%s", format);
return (*RakNet_RakString)(rak_string, format);
}
// Print Error Message If RakNet Startup Fails

@ -100,7 +100,7 @@ void init_options() {
INFO("Setting Username: %s", username);
#endif
if (strcmp(*default_username, "StevePi") != 0) {
ERR("%s", "Default Username Is Invalid");
ERR("Default Username Is Invalid");
}
patch_address((void *) default_username, (void *) username);

@ -205,7 +205,7 @@ static void list_callback(unsigned char *minecraft, std::string username, unsign
// Handle Server Stop
static void handle_server_stop(unsigned char *minecraft) {
if (compat_check_exit_requested()) {
INFO("%s", "Stopping Server");
INFO("Stopping Server");
// Save And Exit
unsigned char *level = get_level(minecraft);
if (level != NULL) {
@ -294,21 +294,21 @@ static void handle_commands(unsigned char *minecraft) {
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, message);
} else if (data == list_command) {
// List Players
INFO("%s", "All Players:");
INFO("All Players:");
find_players(minecraft, "", list_callback, true);
} else if (data == stop_command) {
// Stop Server
compat_request_exit();
} else if (data == help_command) {
INFO("%s", "All Commands:");
INFO("All Commands:");
if (!is_whitelist()) {
INFO("%s", " ban <Username> - IP-Ban All Players With Specifed Username");
INFO(" ban <Username> - IP-Ban All Players With Specifed Username");
}
INFO("%s", " kill <Username> - Kill All Players With Specifed Username");
INFO("%s", " say <Message> - Print Specified Message To Chat");
INFO("%s", " list - List All Players");
INFO("%s", " stop - Stop Server");
INFO("%s", " help - Print This Message");
INFO(" kill <Username> - Kill All Players With Specifed Username");
INFO(" say <Message> - Print Specified Message To Chat");
INFO(" list - List All Players");
INFO(" stop - Stop Server");
INFO(" help - Print This Message");
} else {
INFO("Invalid Command: %s", data.c_str());
}
@ -378,7 +378,7 @@ static bool RakNet_RakPeer_IsBanned_injection(__attribute__((unused)) unsigned c
return ret;
}
} else {
ERR("%s", "Unable To Read Blacklist/Whitelist");
ERR("Unable To Read Blacklist/Whitelist");
}
}

@ -38,7 +38,7 @@ std::string _sound_get_source_file() {
// Check If Sound Exists
if (access(full_path, F_OK) == -1) {
// Fail
WARN("%s", "Audio Source File Doesn't Exist: " SOURCE_FILE_BASE);
WARN("Audio Source File Doesn't Exist: " SOURCE_FILE_BASE);
source.assign("");
} else {
// Set

@ -16,7 +16,7 @@ void run_tests() {
if (!can_write) {
// Failure
ERR("%s", "Invalid Data Directory Permissions");
ERR("Invalid Data Directory Permissions");
}
}
}

@ -145,7 +145,7 @@ static void Textures_tick_glTexSubImage2D_injection(GLenum target, GLint level,
// Check
if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
// Pixels Must Be 4 Bytes
ERR("%s", "Unsupported Texture Format For Scaling");
ERR("Unsupported Texture Format For Scaling");
}
// Scale

@ -118,4 +118,4 @@ sudo rm -f /usr/local/bin/appimagetool
sudo ln -s /opt/appimagetool.AppDir/AppRun /usr/local/bin/appimagetool
# Install appimage-builder
sudo pip3 install 'git+https//github.com/AppImageCrafters/appimage-builder.git'
sudo pip3 install 'git+https://github.com/AppImageCrafters/appimage-builder.git'

Loading…
Cancel
Save