From f3d61494059cb6bb3033da126fc731f454a2e185 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sat, 3 Oct 2020 20:30:15 -0400 Subject: [PATCH] Add Fix Sign Placement --- debian/usr/bin/minecraft-pi | 2 +- mods/CMakeLists.txt | 10 ++-- mods/include/libcore/libcore.h | 6 +-- mods/src/compat.c | 15 ++++-- mods/src/core.c | 6 +-- mods/src/extra.c | 15 +++--- mods/src/extra.cpp | 84 +++++++++++++++++++++++++++++++++- mods/src/extra.h | 18 ++++++++ 8 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 mods/src/extra.h diff --git a/debian/usr/bin/minecraft-pi b/debian/usr/bin/minecraft-pi index 20b1592..d5a8078 100755 --- a/debian/usr/bin/minecraft-pi +++ b/debian/usr/bin/minecraft-pi @@ -4,7 +4,7 @@ set -e # Ensure Features Are Selected if [ -z "${MCPI_SUBSHELL}" ]; then - MCPI_FEATURES="$(zenity --class minecraft-pi --list --checklist --column 'Enabled' --column 'Feature' FALSE 'Touch GUI' FALSE 'Survival Mode' FALSE 'Fix Bow & Arrow' FALSE 'Fix Attacking' FALSE 'Mob Spawning' FALSE 'Fancy Graphics' FALSE 'Disable Autojump By Default')" + MCPI_FEATURES="$(zenity --class minecraft-pi --list --checklist --column 'Enabled' --column 'Feature' FALSE 'Touch GUI' FALSE 'Survival Mode' FALSE 'Fix Bow & Arrow' FALSE 'Fix Attacking' FALSE 'Mob Spawning' FALSE 'Fancy Graphics' FALSE 'Disable Autojump By Default' FALSE 'Fix Sign Placement')" MCPI_USERNAME="$(zenity --class minecraft-pi --entry --text 'Minecraft Username:' --entry-text 'StevePi')" fi export MCPI_FEATURES diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 9f6dfca..fb1fb47 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -11,13 +11,13 @@ include_directories(include) add_library(core SHARED src/core.c) target_link_libraries(core dl) -add_library(compat SHARED src/compat.c) -target_link_libraries(compat core SDL EGL GLESv1_CM GLESv2 X11 dl) -# Force GLESv1 Link -target_link_options(compat PRIVATE "-Wl,--no-as-needed") - add_library(extra SHARED src/extra.c src/extra.cpp) target_link_libraries(extra core dl) +add_library(compat SHARED src/compat.c) +target_link_libraries(compat core extra SDL EGL GLESv1_CM GLESv2 X11 dl) +# Force GLESv1 Link +target_link_options(compat PRIVATE "-Wl,--no-as-needed") + add_library(readdir SHARED src/readdir.c) target_link_libraries(readdir core) diff --git a/mods/include/libcore/libcore.h b/mods/include/libcore/libcore.h index 64f7353..6eb66e9 100644 --- a/mods/include/libcore/libcore.h +++ b/mods/include/libcore/libcore.h @@ -27,15 +27,15 @@ extern "C" { \ __attribute__((__used__)) return_type name args -void *_overwrite(char *file, int line, void *start, void *target); +void *_overwrite(const char *file, int line, void *start, void *target); #define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target); void revert_overwrite(void *start, void *original); -void _patch(char *file, int line, void *start, unsigned char patch[]); +void _patch(const char *file, int line, void *start, unsigned char patch[]); #define patch(start, patch) _patch(__FILE__, __LINE__, start, patch); -void _patch_address(char *file, int line, void *start, void *target); +void _patch_address(const char *file, int line, void *start, void *target); #define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target); #ifdef __cplusplus diff --git a/mods/src/compat.c b/mods/src/compat.c index 7483503..4bcde0f 100644 --- a/mods/src/compat.c +++ b/mods/src/compat.c @@ -8,6 +8,8 @@ #include +#include "extra.h" + static Display *x11_display; static EGLDisplay egl_display; static Window x11_window; @@ -106,6 +108,9 @@ EGLint const set_attrib_list[] = { // Init EGL HOOK(SDL_WM_SetCaption, void, (const char *title, const char *icon)) { + // Enable Unicode + SDL_EnableUNICODE(SDL_ENABLE); + ensure_SDL_SetVideoMode(); sdl_surface = (*real_SDL_SetVideoMode)(848, 480, 32, WINDOW_VIDEO_FLAGS); @@ -206,9 +211,13 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) { if (event->type == SDL_VIDEORESIZE) { resize(event->resize.w, event->resize.h, is_fullscreen); handled = 1; - } else if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_F11) { - toggle_fullscreen(); - handled = 1; + } else if (event->type == SDL_KEYDOWN) { + if (event->key.keysym.sym == SDLK_F11) { + toggle_fullscreen(); + handled = 1; + } else { + key_press((char) event->key.keysym.unicode); + } } if (handled) { diff --git a/mods/src/core.c b/mods/src/core.c index f450335..7f7725c 100644 --- a/mods/src/core.c +++ b/mods/src/core.c @@ -10,7 +10,7 @@ #define ORIGINAL_SIZE 8 -void *_overwrite(char *file, int line, void *start, void *target) { +void *_overwrite(const char *file, int line, void *start, void *target) { void *original = malloc(ORIGINAL_SIZE); memcpy(original, start, ORIGINAL_SIZE); @@ -50,7 +50,7 @@ void revert_overwrite(void *start, void *original) { free(temp); } -void _patch(char *file, int line, void *start, unsigned char patch[]) { +void _patch(const char *file, int line, void *start, unsigned char patch[]) { size_t page_size = sysconf(_SC_PAGESIZE); uintptr_t end = ((uintptr_t) start) + 4; uintptr_t page_start = ((uintptr_t) start) & -page_size; @@ -72,7 +72,7 @@ void _patch(char *file, int line, void *start, unsigned char patch[]) { __clear_cache(start, (void *) end); } -void _patch_address(char *file, int line, void *start, void *target) { +void _patch_address(const char *file, int line, void *start, void *target) { uint32_t addr = (uint32_t) target; unsigned char patch_data[4] = {addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, (addr >> 24) & 0xff}; _patch(file, line, start, patch_data); diff --git a/mods/src/extra.c b/mods/src/extra.c index 4686562..3c38a9f 100644 --- a/mods/src/extra.c +++ b/mods/src/extra.c @@ -1,14 +1,15 @@ #include #include +#include #include +#include "extra.h" + static uint32_t getSpawnMobs_injection(__attribute__((unused)) int32_t obj) { return 1; } -#include - typedef void (*releaseUsingItem_t)(unsigned char *t, unsigned char *player); static releaseUsingItem_t survival_releaseUsingItem = (releaseUsingItem_t) 0x1a598; static releaseUsingItem_t creative_releaseUsingItem = (releaseUsingItem_t) 0x1b1a0; @@ -35,6 +36,8 @@ static void handle_input_injection(unsigned char *param_1, unsigned char *param_ (*(is_survival ? survival_releaseUsingItem : creative_releaseUsingItem))(game_mode, player); } } + + clear_input(); } typedef void (*tickItemDrop_t)(unsigned char *); @@ -63,7 +66,7 @@ static void handleClick_injection(unsigned char *this, unsigned char *param_2, u } } -static int has_feature(const char *name) { +int has_feature(const char *name) { char *env = getenv("MCPI_FEATURES"); char *features = strdup(env != NULL ? env : ""); char *tok = strtok(features, "|"); @@ -80,9 +83,6 @@ static int has_feature(const char *name) { return ret; } -// Defined In extra.cpp -extern unsigned char *readAssetFile(unsigned char *app_platform, unsigned char *path); - // Patch Game Mode static void set_is_survival(int new_is_survival) { if (is_survival != new_is_survival) { @@ -180,9 +180,6 @@ __attribute__((constructor)) static void init() { // Allocate Correct Size For ServerLevel unsigned char patch_data_5[4] = {0x94, 0x0b, 0x00, 0x00}; patch((void *) 0x17004, patch_data_5); - - // Implement AppPlatform::readAssetFile So Translations Work - overwrite((void *) 0x12b10, readAssetFile); if (has_feature("Fancy Graphics")) { // Enable Fancy Graphics diff --git a/mods/src/extra.cpp b/mods/src/extra.cpp index ea0c9e8..7241813 100644 --- a/mods/src/extra.cpp +++ b/mods/src/extra.cpp @@ -1,15 +1,97 @@ #include #include #include +#include #include +#include + +#include "extra.h" + extern "C" { - std::string readAssetFile(__attribute__((unused)) unsigned char *obj, const std::string& path) { + static std::string readAssetFile(__attribute__((unused)) unsigned char *obj, const std::string& path) { std::string full_path("./data/"); full_path.append(path.c_str()); std::ifstream stream(full_path); std::string str((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); return str; } + + typedef unsigned char *(*TextEditScreen_t)(unsigned char *, unsigned char *); + static TextEditScreen_t TextEditScreen = (TextEditScreen_t) 0x3a840; + + typedef void (*setScreen_t)(unsigned char *, unsigned char *); + static setScreen_t setScreen = (setScreen_t) 0x15d6c; + + static void openTextEdit(unsigned char *local_player, unsigned char *sign) { + if (*(int *)(sign + 0x18) == 4) { + unsigned char *minecraft = *(unsigned char **) (local_player + 0xc90); + unsigned char *screen = (unsigned char *) ::operator new(0xd0); + screen = (*TextEditScreen)(screen, sign); + (*setScreen)(minecraft, screen); + } + } + + #define BACKSPACE_KEY 8 + + static int is_valid_key(char key) { + return (key >= 32 && key <= 126) || key == BACKSPACE_KEY; + } + + std::vector input; + int count = 0; + void key_press(char key) { + if (is_valid_key(key)) { + // Keys Are Sent Twice + if (count > 0) { + count = 0; + } else { + input.push_back(key); + count++; + } + } + } + void clear_input() { + input.clear(); + } + + typedef void (*updateEvents_t)(unsigned char *screen); + static updateEvents_t updateEvents = (updateEvents_t) 0x28eb8; + static void *updateEvents_original = NULL; + + typedef void (*keyboardNewChar_t)(unsigned char *screen, char key); + typedef void (*keyPressed_t)(unsigned char *screen, int32_t key); + + static void updateEvents_injection(unsigned char *screen) { + // Call Original + revert_overwrite((void *) updateEvents, updateEvents_original); + (*updateEvents)(screen); + revert_overwrite((void *) updateEvents, updateEvents_original); + + if (*(char *)(screen + 4) == '\0') { + uint32_t vtable = *((uint32_t *) screen); + for (char key : input) { + if (key == BACKSPACE_KEY) { + // Handle Backspace + (*(keyPressed_t *) (vtable + 0x6c))(screen, BACKSPACE_KEY); + } else { + // Handle Nrmal Key + (*(keyboardNewChar_t *) (vtable + 0x70))(screen, key); + } + } + } + clear_input(); + } + + __attribute((constructor)) static void init() { + // Implement AppPlatform::readAssetFile So Translations Work + overwrite((void *) 0x12b10, (void *) readAssetFile); + + if (has_feature("Fix Sign Placement")) { + // Fix Signs + patch_address((void *) 0x106460, (void *) openTextEdit); + updateEvents_original = overwrite((void *) updateEvents, (void *) updateEvents_injection); + } + } } diff --git a/mods/src/extra.h b/mods/src/extra.h new file mode 100644 index 0000000..be0085d --- /dev/null +++ b/mods/src/extra.h @@ -0,0 +1,18 @@ +#ifndef EXTRA_H + +#define EXTRA_H + +#ifdef __cplusplus +extern "C" { +#endif + +int has_feature(const char *name); + +void key_press(char key); +void clear_input(); + +#ifdef __cplusplus +} +#endif + +#endif