diff --git a/VERSION b/VERSION index 09843e3..7ec1d6d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.9 +2.1.0 diff --git a/dependencies/minecraft-pi/CMakeLists.txt b/dependencies/minecraft-pi/CMakeLists.txt index bd673e4..e9a8ee0 100644 --- a/dependencies/minecraft-pi/CMakeLists.txt +++ b/dependencies/minecraft-pi/CMakeLists.txt @@ -7,7 +7,7 @@ include(FetchContent) # Download FetchContent_Declare( minecraft-pi - URL "https://www.minecraft.net/content/dam/minecraft/edition-pi/minecraft-pi-0.1.1.tar.gz" + URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.1.tar.gz" URL_HASH "SHA256=e0d68918874cdd403de1fd399380ae2930913fcefdbf60a3fbfebb62e2cfacab" ) FetchContent_Populate(minecraft-pi) diff --git a/dependencies/minecraft-pi/minecraft-pi-0.1.1.tar.gz b/dependencies/minecraft-pi/minecraft-pi-0.1.1.tar.gz new file mode 100644 index 0000000..1bb0c93 Binary files /dev/null and b/dependencies/minecraft-pi/minecraft-pi-0.1.1.tar.gz differ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 59e2c84..8b717ed 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +**2.1.0** +* Allow Binding ``Q`` Key To Item Dropping +* Expose More Feature Flags +* Replace ``Mob Spawning`` Feature Flag With ``Force Mob Spawning`` +* Fix ``ESC`` Key In Options Menu When ``Miscellaneous Input Fixes`` Is Enabled + **2.0.9** * Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The ``gui_blocks`` Atlas Is Disabled diff --git a/launcher/client-data/opt/minecraft-pi-reborn-client/available-feature-flags b/launcher/client-data/opt/minecraft-pi-reborn-client/available-feature-flags index f6d73cd..0731817 100644 --- a/launcher/client-data/opt/minecraft-pi-reborn-client/available-feature-flags +++ b/launcher/client-data/opt/minecraft-pi-reborn-client/available-feature-flags @@ -1,7 +1,7 @@ TRUE Touch GUI TRUE Fix Bow & Arrow TRUE Fix Attacking -TRUE Mob Spawning +FALSE Force Mob Spawning TRUE Fancy Graphics TRUE Disable Autojump By Default TRUE Display Nametags By Default @@ -11,6 +11,16 @@ FALSE Expand Creative Inventory FALSE Peaceful Mode TRUE Animated Water TRUE Remove Invalid Item Background -TRUE Disable gui_blocks Atlas +TRUE Disable "gui_blocks" Atlas TRUE Smooth Lighting FALSE 3D Anaglyph +TRUE Fix Camera Rendering +TRUE Implement Chat +TRUE Implement Death Messages +TRUE Implement Game-Mode Switching +TRUE Miscellaneous Input Fixes +TRUE Bind "Q" Key To Item Dropping +TRUE Bind Common Toggleable Options To Function Keys +TRUE Render Selected Item Text +TRUE External Server Support +TRUE Load Language Files diff --git a/libreborn/include/libreborn/minecraft.h b/libreborn/include/libreborn/minecraft.h index d20dc20..18411d2 100644 --- a/libreborn/include/libreborn/minecraft.h +++ b/libreborn/include/libreborn/minecraft.h @@ -185,12 +185,32 @@ typedef int32_t (*MouseBuildInput_tickBuild_t)(unsigned char *mouse_build_input, static MouseBuildInput_tickBuild_t MouseBuildInput_tickBuild = (MouseBuildInput_tickBuild_t) 0x17c98; static void *MouseBuildInput_tickBuild_vtable_addr = (void *) 0x102564; +// ItemInstance + +typedef struct { + int32_t count; + int32_t id; + int32_t auxilary; +} ItemInstance; + +typedef ItemInstance *(*ItemInstance_constructor_t)(ItemInstance *item_instance, unsigned char *item); +static ItemInstance_constructor_t ItemInstance_constructor_item = (ItemInstance_constructor_t) 0x9992c; +static ItemInstance_constructor_t ItemInstance_constructor_tile = (ItemInstance_constructor_t) 0x998e4; + +typedef ItemInstance *(*ItemInstance_constructor_extra_t)(ItemInstance *item_instance, unsigned char *item, int32_t count, int32_t auxilary); +static ItemInstance_constructor_extra_t ItemInstance_constructor_tile_extra = (ItemInstance_constructor_extra_t) 0x99918; +static ItemInstance_constructor_extra_t ItemInstance_constructor_item_extra = (ItemInstance_constructor_extra_t) 0x99960; + // Player typedef int (*Player_isUsingItem_t)(unsigned char *player); static Player_isUsingItem_t Player_isUsingItem = (Player_isUsingItem_t) 0x8f15c; +typedef void (*Player_drop_t)(unsigned char *player, ItemInstance *item_instance); +static uint32_t Player_drop_vtable_offset = 0x204; + static uint32_t Player_username_property_offset = 0xbf4; // char * +static uint32_t Player_inventory_property_offset = 0xbe0; // Inventory * // Entity @@ -278,6 +298,10 @@ static void *TextEditScreen_updateEvents_vtable_addr = (void *) 0x10531c; typedef void *(*ProgressScreen_t)(unsigned char *obj); static ProgressScreen_t ProgressScreen = (ProgressScreen_t) 0x37044; +// OptionsScreen + +static void *OptionsScreen_handleBackEvent_vtable_addr = (void *) 0x10499c; + // Screen typedef void (*Screen_updateEvents_t)(unsigned char *screen); @@ -291,6 +315,8 @@ static uint32_t Screen_keyPressed_vtable_offset = 0x6c; typedef void (*Screen_tick_t)(unsigned char *screen); +typedef int32_t (*Screen_handleBackEvent_t)(unsigned char *screen, bool param_1); + static uint32_t Screen_minecraft_property_offset = 0x14; // Minecraft * // SelectWorldScreen @@ -309,27 +335,29 @@ static void *Touch_SelectWorldScreen_tick_vtable_addr = (void *) 0x105780; static uint32_t Touch_SelectWorldScreen_should_create_world_property_offset = 0x154; // bool static uint32_t Touch_SelectWorldScreen_world_created_property_offset = 0x151; // bool -// ItemInstance - -#define ITEM_INSTANCE_SIZE 0xc - -typedef unsigned char *(*ItemInstance_constructor_t)(unsigned char *item_instance, unsigned char *item); -static ItemInstance_constructor_t ItemInstance_constructor_item = (ItemInstance_constructor_t) 0x9992c; -static ItemInstance_constructor_t ItemInstance_constructor_tile = (ItemInstance_constructor_t) 0x998e4; - -typedef unsigned char *(*ItemInstance_constructor_extra_t)(unsigned char *item_instance, unsigned char *item, int32_t count, int32_t auxilary); -static ItemInstance_constructor_extra_t ItemInstance_constructor_tile_extra = (ItemInstance_constructor_extra_t) 0x99918; -static ItemInstance_constructor_extra_t ItemInstance_constructor_item_extra = (ItemInstance_constructor_extra_t) 0x99960; - -static uint32_t ItemInstance_count_property_offset = 0x0; // int32_t -static uint32_t ItemInstance_id_property_offset = 0x4; // int32_t -static uint32_t ItemInstance_auxilary_property_offset = 0x8; // int32_t - // FillingContainer -typedef int32_t (*FillingContainer_addItem_t)(unsigned char *filling_container, unsigned char *item_instance); +typedef int32_t (*FillingContainer_addItem_t)(unsigned char *filling_container, ItemInstance *item_instance); static FillingContainer_addItem_t FillingContainer_addItem = (FillingContainer_addItem_t) 0x92aa0; +typedef ItemInstance *(*FillingContainer_getItem_t)(unsigned char *filling_container, int32_t slot); +static uint32_t FillingContainer_getItem_vtable_offset = 0x8; + +typedef void (*FillingContainer_setItem_t)(unsigned char *filling_container, int32_t slot, ItemInstance *item_instance); +static uint32_t FillingContainer_setItem_vtable_offset = 0xc; + +typedef void (*FillingContainer_clearSlot_t)(unsigned char *filling_container, int32_t slot); +static FillingContainer_clearSlot_t FillingContainer_clearSlot = (FillingContainer_clearSlot_t) 0x922f8; + +typedef void (*FillingContainer_release_t)(unsigned char *filling_container, int32_t slot); +static FillingContainer_release_t FillingContainer_release = (FillingContainer_release_t) 0x92058; + +typedef void (*FillingContainer_compressLinkedSlotList_t)(unsigned char *filling_container, int32_t slot); +static FillingContainer_compressLinkedSlotList_t FillingContainer_compressLinkedSlotList = (FillingContainer_compressLinkedSlotList_t) 0x92280; + +static uint32_t FillingContainer_linked_slots_property_offset = 0xc; // int32_t[] +static uint32_t FillingContainer_linked_slots_length_property_offset = 0x14; // int32_t + // RakNet::RakString typedef void (*RakNet_RakString_Assign_t)(unsigned char *rak_string, const char *str); @@ -390,6 +418,8 @@ static void *ServerSideNetworkHandler_handle_ChatPacket_vtable_addr = (void *) 0 typedef void (*Inventory_selectSlot_t)(unsigned char *inventory, int32_t slot); static Inventory_selectSlot_t Inventory_selectSlot = (Inventory_selectSlot_t) 0x8d13c; +static uint32_t Inventory_selectedSlot_property_offset = 0x28; // int32_t + // TripodCameraRenderer #define TRIPOD_CAMERA_RENDERER_SIZE 0x193 @@ -411,10 +441,10 @@ static uint32_t TileEntity_id_property_offset = 0x18; // int32_t // ItemRenderer -typedef float (*ItemRenderer_renderGuiItem_t)(unsigned char *font, unsigned char *textures, unsigned char *item_instance, float param_1, float param_2, bool param_3); +typedef float (*ItemRenderer_renderGuiItem_t)(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, float param_1, float param_2, bool param_3); static ItemRenderer_renderGuiItem_t ItemRenderer_renderGuiItem = (ItemRenderer_renderGuiItem_t) 0x63e58; -typedef float (*ItemRenderer_renderGuiItemCorrect_t)(unsigned char *font, unsigned char *textures, unsigned char *item_instance, int32_t param_1, int32_t param_2); +typedef float (*ItemRenderer_renderGuiItemCorrect_t)(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, int32_t param_1, int32_t param_2); static ItemRenderer_renderGuiItemCorrect_t ItemRenderer_renderGuiItemCorrect = (ItemRenderer_renderGuiItemCorrect_t) 0x639a0; // Tesselator diff --git a/media-layer/core/src/media.c b/media-layer/core/src/media.c index b31ae69..183821a 100644 --- a/media-layer/core/src/media.c +++ b/media-layer/core/src/media.c @@ -22,6 +22,15 @@ static void glfw_error(__attribute__((unused)) int error, const char *descriptio WARN("GLFW Error: %s", description); } +// Pass Character Event +static void character_event(char c) { + // SDL_UserEvent Is Never Used In MCPI, So It Is Repurposed For Character Events + SDL_Event event; + event.type = SDL_USEREVENT; + event.user.code = (int) c; + SDL_PushEvent(&event); +} + // Convert GLFW Key To SDL Key static SDLKey glfw_key_to_sdl_key(int key) { switch (key) { @@ -43,6 +52,9 @@ static SDLKey glfw_key_to_sdl_key(int key) { // Inventory case GLFW_KEY_E: return SDLK_e; + // Drop Item + case GLFW_KEY_Q: + return SDLK_q; // Hotbar case GLFW_KEY_1: return SDLK_1; @@ -98,13 +110,23 @@ static SDLKey glfw_key_to_sdl_key(int key) { } } -// Pass Character Event -static void character_event(char c) { - // SDL_UserEvent Is Never Used In MCPI, So It Is Repurposed For Character Events - SDL_Event event; - event.type = SDL_USEREVENT; - event.user.code = (int) c; - SDL_PushEvent(&event); +// Convert GLFW Key Modifier To SDL Key Modifier +static SDLMod glfw_modifier_to_sdl_modifier(int mods) { + SDLMod ret = KMOD_NONE; + // Control + if ((mods & GLFW_MOD_CONTROL) != 0) { + ret |= KMOD_CTRL; + } + // Shift + if ((mods & GLFW_MOD_SHIFT) != 0) { + ret |= KMOD_SHIFT; + } + // Alt + if ((mods & GLFW_MOD_ALT) != 0) { + ret |= KMOD_ALT; + } + // Return + return ret; } // Pass Key Presses To SDL @@ -114,7 +136,7 @@ static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int sc event.type = up ? SDL_KEYUP : SDL_KEYDOWN; event.key.state = up ? SDL_RELEASED : SDL_PRESSED; event.key.keysym.scancode = scancode; - event.key.keysym.mod = KMOD_NONE; + event.key.keysym.mod = glfw_modifier_to_sdl_modifier(mods); event.key.keysym.sym = glfw_key_to_sdl_key(key); SDL_PushEvent(&event); if (key == GLFW_KEY_BACKSPACE && !up) { diff --git a/media-layer/include/SDL/SDL.h b/media-layer/include/SDL/SDL.h index a0746cb..23d572b 100644 --- a/media-layer/include/SDL/SDL.h +++ b/media-layer/include/SDL/SDL.h @@ -32,7 +32,7 @@ int SDL_ShowCursor(int toggle); void *SDL_SetVideoMode(int width, int height, int bpp, uint32_t flags); int SDL_GetWMInfo(SDL_SysWMinfo *info); -__attribute__ ((noreturn)) void SDL_Quit(); +__attribute__((noreturn)) void SDL_Quit(); #ifdef __cplusplus } diff --git a/media-layer/include/SDL/SDL_keysym.h b/media-layer/include/SDL/SDL_keysym.h index 3c918d2..a489b93 100644 --- a/media-layer/include/SDL/SDL_keysym.h +++ b/media-layer/include/SDL/SDL_keysym.h @@ -6,28 +6,11 @@ extern "C" { typedef enum { SDLK_UNKNOWN = 0, - SDLK_FIRST = 0, SDLK_BACKSPACE = 8, SDLK_TAB = 9, - SDLK_CLEAR = 12, SDLK_RETURN = 13, - SDLK_PAUSE = 19, SDLK_ESCAPE = 27, SDLK_SPACE = 32, - SDLK_EXCLAIM = 33, - SDLK_QUOTEDBL = 34, - SDLK_HASH = 35, - SDLK_DOLLAR = 36, - SDLK_AMPERSAND = 38, - SDLK_QUOTE = 39, - SDLK_LEFTPAREN = 40, - SDLK_RIGHTPAREN = 41, - SDLK_ASTERISK = 42, - SDLK_PLUS = 43, - SDLK_COMMA = 44, - SDLK_MINUS = 45, - SDLK_PERIOD = 46, - SDLK_SLASH = 47, SDLK_0 = 48, SDLK_1 = 49, SDLK_2 = 50, @@ -38,225 +21,40 @@ typedef enum { SDLK_7 = 55, SDLK_8 = 56, SDLK_9 = 57, - SDLK_COLON = 58, - SDLK_SEMICOLON = 59, - SDLK_LESS = 60, - SDLK_EQUALS = 61, - SDLK_GREATER = 62, - SDLK_QUESTION = 63, - SDLK_AT = 64, - SDLK_LEFTBRACKET = 91, - SDLK_BACKSLASH = 92, - SDLK_RIGHTBRACKET = 93, - SDLK_CARET = 94, - SDLK_UNDERSCORE = 95, - SDLK_BACKQUOTE = 96, SDLK_a = 97, - SDLK_b = 98, - SDLK_c = 99, SDLK_d = 100, SDLK_e = 101, - SDLK_f = 102, - SDLK_g = 103, - SDLK_h = 104, - SDLK_i = 105, - SDLK_j = 106, - SDLK_k = 107, - SDLK_l = 108, - SDLK_m = 109, - SDLK_n = 110, - SDLK_o = 111, - SDLK_p = 112, SDLK_q = 113, - SDLK_r = 114, SDLK_s = 115, SDLK_t = 116, - SDLK_u = 117, - SDLK_v = 118, SDLK_w = 119, - SDLK_x = 120, - SDLK_y = 121, - SDLK_z = 122, - SDLK_DELETE = 127, - SDLK_WORLD_0 = 160, - SDLK_WORLD_1 = 161, - SDLK_WORLD_2 = 162, - SDLK_WORLD_3 = 163, - SDLK_WORLD_4 = 164, - SDLK_WORLD_5 = 165, - SDLK_WORLD_6 = 166, - SDLK_WORLD_7 = 167, - SDLK_WORLD_8 = 168, - SDLK_WORLD_9 = 169, - SDLK_WORLD_10 = 170, - SDLK_WORLD_11 = 171, - SDLK_WORLD_12 = 172, - SDLK_WORLD_13 = 173, - SDLK_WORLD_14 = 174, - SDLK_WORLD_15 = 175, - SDLK_WORLD_16 = 176, - SDLK_WORLD_17 = 177, - SDLK_WORLD_18 = 178, - SDLK_WORLD_19 = 179, - SDLK_WORLD_20 = 180, - SDLK_WORLD_21 = 181, - SDLK_WORLD_22 = 182, - SDLK_WORLD_23 = 183, - SDLK_WORLD_24 = 184, - SDLK_WORLD_25 = 185, - SDLK_WORLD_26 = 186, - SDLK_WORLD_27 = 187, - SDLK_WORLD_28 = 188, - SDLK_WORLD_29 = 189, - SDLK_WORLD_30 = 190, - SDLK_WORLD_31 = 191, - SDLK_WORLD_32 = 192, - SDLK_WORLD_33 = 193, - SDLK_WORLD_34 = 194, - SDLK_WORLD_35 = 195, - SDLK_WORLD_36 = 196, - SDLK_WORLD_37 = 197, - SDLK_WORLD_38 = 198, - SDLK_WORLD_39 = 199, - SDLK_WORLD_40 = 200, - SDLK_WORLD_41 = 201, - SDLK_WORLD_42 = 202, - SDLK_WORLD_43 = 203, - SDLK_WORLD_44 = 204, - SDLK_WORLD_45 = 205, - SDLK_WORLD_46 = 206, - SDLK_WORLD_47 = 207, - SDLK_WORLD_48 = 208, - SDLK_WORLD_49 = 209, - SDLK_WORLD_50 = 210, - SDLK_WORLD_51 = 211, - SDLK_WORLD_52 = 212, - SDLK_WORLD_53 = 213, - SDLK_WORLD_54 = 214, - SDLK_WORLD_55 = 215, - SDLK_WORLD_56 = 216, - SDLK_WORLD_57 = 217, - SDLK_WORLD_58 = 218, - SDLK_WORLD_59 = 219, - SDLK_WORLD_60 = 220, - SDLK_WORLD_61 = 221, - SDLK_WORLD_62 = 222, - SDLK_WORLD_63 = 223, - SDLK_WORLD_64 = 224, - SDLK_WORLD_65 = 225, - SDLK_WORLD_66 = 226, - SDLK_WORLD_67 = 227, - SDLK_WORLD_68 = 228, - SDLK_WORLD_69 = 229, - SDLK_WORLD_70 = 230, - SDLK_WORLD_71 = 231, - SDLK_WORLD_72 = 232, - SDLK_WORLD_73 = 233, - SDLK_WORLD_74 = 234, - SDLK_WORLD_75 = 235, - SDLK_WORLD_76 = 236, - SDLK_WORLD_77 = 237, - SDLK_WORLD_78 = 238, - SDLK_WORLD_79 = 239, - SDLK_WORLD_80 = 240, - SDLK_WORLD_81 = 241, - SDLK_WORLD_82 = 242, - SDLK_WORLD_83 = 243, - SDLK_WORLD_84 = 244, - SDLK_WORLD_85 = 245, - SDLK_WORLD_86 = 246, - SDLK_WORLD_87 = 247, - SDLK_WORLD_88 = 248, - SDLK_WORLD_89 = 249, - SDLK_WORLD_90 = 250, - SDLK_WORLD_91 = 251, - SDLK_WORLD_92 = 252, - SDLK_WORLD_93 = 253, - SDLK_WORLD_94 = 254, - SDLK_WORLD_95 = 255, - SDLK_KP0 = 256, - SDLK_KP1 = 257, - SDLK_KP2 = 258, - SDLK_KP3 = 259, - SDLK_KP4 = 260, - SDLK_KP5 = 261, - SDLK_KP6 = 262, - SDLK_KP7 = 263, - SDLK_KP8 = 264, - SDLK_KP9 = 265, - SDLK_KP_PERIOD = 266, - SDLK_KP_DIVIDE = 267, - SDLK_KP_MULTIPLY = 268, - SDLK_KP_MINUS = 269, - SDLK_KP_PLUS = 270, - SDLK_KP_ENTER = 271, - SDLK_KP_EQUALS = 272, SDLK_UP = 273, SDLK_DOWN = 274, SDLK_RIGHT = 275, SDLK_LEFT = 276, - SDLK_INSERT = 277, - SDLK_HOME = 278, - SDLK_END = 279, - SDLK_PAGEUP = 280, - SDLK_PAGEDOWN = 281, SDLK_F1 = 282, SDLK_F2 = 283, - SDLK_F3 = 284, - SDLK_F4 = 285, SDLK_F5 = 286, - SDLK_F6 = 287, - SDLK_F7 = 288, - SDLK_F8 = 289, - SDLK_F9 = 290, - SDLK_F10 = 291, SDLK_F11 = 292, SDLK_F12 = 293, - SDLK_F13 = 294, - SDLK_F14 = 295, - SDLK_F15 = 296, - SDLK_NUMLOCK = 300, - SDLK_CAPSLOCK = 301, - SDLK_SCROLLOCK = 302, SDLK_RSHIFT = 303, - SDLK_LSHIFT = 304, - SDLK_RCTRL = 305, - SDLK_LCTRL = 306, - SDLK_RALT = 307, - SDLK_LALT = 308, - SDLK_RMETA = 309, - SDLK_LMETA = 310, - SDLK_LSUPER = 311, - SDLK_RSUPER = 312, - SDLK_MODE = 313, - SDLK_COMPOSE = 314, - SDLK_HELP = 315, - SDLK_PRINT = 316, - SDLK_SYSREQ = 317, - SDLK_BREAK = 318, - SDLK_MENU = 319, - SDLK_POWER = 320, - SDLK_EURO = 321, - SDLK_UNDO = 322, - SDLK_LAST + SDLK_LSHIFT = 304 } SDLKey; typedef enum { - KMOD_NONE = 0x0000, - KMOD_LSHIFT = 0x0001, - KMOD_RSHIFT = 0x0002, - KMOD_LCTRL = 0x0040, - KMOD_RCTRL = 0x0080, - KMOD_LALT = 0x0100, - KMOD_RALT = 0x0200, - KMOD_LMETA = 0x0400, - KMOD_RMETA = 0x0800, - KMOD_NUM = 0x1000, - KMOD_CAPS = 0x2000, - KMOD_MODE = 0x4000, - KMOD_RESERVED = 0x8000 + KMOD_NONE = 0x0, + KMOD_LSHIFT = 0x1, + KMOD_RSHIFT = 0x2, + KMOD_LCTRL = 0x40, + KMOD_RCTRL = 0x80, + KMOD_LALT = 0x100, + KMOD_RALT = 0x200 } SDLMod; +#define KMOD_SHIFT (KMOD_LSHIFT | KMOD_RSHIFT) +#define KMOD_CTRL (KMOD_LCTRL | KMOD_RCTRL) +#define KMOD_ALT (KMOD_LALT | KMOD_RALT) + #ifdef __cplusplus } #endif diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 04b650b..1206ed5 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -8,7 +8,7 @@ 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 feature input sign media-layer-core dl) +target_link_libraries(compat feature input chat sign media-layer-core dl) add_library(readdir SHARED src/readdir/readdir.c) @@ -23,23 +23,23 @@ if(MCPI_SERVER_MODE) target_link_libraries(server reborn feature home compat version dl media-layer-core pthread) else() add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp) - target_link_libraries(multiplayer reborn home) + target_link_libraries(multiplayer reborn home feature) endif() add_library(camera SHARED src/camera/camera.cpp) -target_link_libraries(camera reborn media-layer-core) +target_link_libraries(camera reborn media-layer-core feature) add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp) -target_link_libraries(game-mode reborn) +target_link_libraries(game-mode reborn feature) + +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 feature media-layer-core) add_library(sign SHARED src/sign/sign.cpp) -target_link_libraries(sign reborn feature) - -add_library(input SHARED src/input/input.c) -target_link_libraries(input reborn feature media-layer-core chat sign) +target_link_libraries(sign reborn feature input) add_library(death SHARED src/death/death.cpp) -target_link_libraries(death reborn) +target_link_libraries(death reborn feature) add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp) target_link_libraries(misc reborn feature) @@ -60,7 +60,7 @@ add_library(atlas SHARED src/atlas/atlas.cpp) target_link_libraries(atlas reborn feature GLESv1_CM) add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c) -target_link_libraries(chat reborn pthread) +target_link_libraries(chat reborn feature input pthread) add_library(home SHARED src/home/home.c) target_link_libraries(home reborn) diff --git a/mods/src/atlas/atlas.cpp b/mods/src/atlas/atlas.cpp index dbea0fa..bd0b4c3 100644 --- a/mods/src/atlas/atlas.cpp +++ b/mods/src/atlas/atlas.cpp @@ -7,23 +7,19 @@ #include "../init/init.h" // Fix Grass And Leaves Inventory Rendering When The gui_blocks Atlas Is Disabled -static float ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, unsigned char *textures, unsigned char *item_instance, int32_t param_1, int32_t param_2) { +static float ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, int32_t param_1, int32_t param_2) { int32_t leaves_id = *(int32_t *) (*Tile_leaves + Tile_id_property_offset); int32_t grass_id = *(int32_t *) (*Tile_grass + Tile_id_property_offset); // Replace Rendered Item With Carried Variant - unsigned char *carried_item_instance = NULL; + ItemInstance carried_item_instance; + bool use_carried = false; if (item_instance != NULL) { - int32_t id = *(int32_t *) (item_instance + ItemInstance_id_property_offset); - int32_t count = *(int32_t *) (item_instance + ItemInstance_count_property_offset); - int32_t auxilary = *(int32_t *) (item_instance + ItemInstance_auxilary_property_offset); - if (id == leaves_id) { - carried_item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE); - ALLOC_CHECK(carried_item_instance); - (*ItemInstance_constructor_tile_extra)(carried_item_instance, *Tile_leaves_carried, count, auxilary); - } else if (id == grass_id) { - carried_item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE); - ALLOC_CHECK(carried_item_instance); - (*ItemInstance_constructor_tile_extra)(carried_item_instance, *Tile_grass_carried, count, auxilary); + if (item_instance->id == leaves_id) { + (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_leaves_carried, item_instance->count, item_instance->auxilary); + use_carried = true; + } else if (item_instance->id == grass_id) { + (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_grass_carried, item_instance->count, item_instance->auxilary); + use_carried = true; } } @@ -32,18 +28,13 @@ static float ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, un glDisable(GL_DEPTH_TEST); // Call Original Method - float ret = (*ItemRenderer_renderGuiItemCorrect)(font, textures, carried_item_instance != NULL ? carried_item_instance : item_instance, param_1, param_2); + float ret = (*ItemRenderer_renderGuiItemCorrect)(font, textures, use_carried ? &carried_item_instance : item_instance, param_1, param_2); // Revert GL State Changes if (depth_test_was_enabled) { glEnable(GL_DEPTH_TEST); } - // Free Carried Item Instance Variant - if (carried_item_instance != NULL) { - ::operator delete(carried_item_instance); - } - // Return return ret; } @@ -86,7 +77,7 @@ static void Tesselator_color_injection(unsigned char *tesselator, int32_t r, int // Call Original Method (*Tesselator_color)(tesselator, r, g, b, a); } -static float FurnaceScreen_render_ItemRenderer_renderGuiItem_injection(unsigned char *font, unsigned char *textures, unsigned char *item_instance, float param_1, float param_2, bool param_3) { +static float FurnaceScreen_render_ItemRenderer_renderGuiItem_injection(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, float param_1, float param_2, bool param_3) { // Enable Furnace UI Fix use_furnace_fix = true; @@ -103,7 +94,7 @@ static float FurnaceScreen_render_ItemRenderer_renderGuiItem_injection(unsigned // Init void init_atlas() { // Disable The gui_blocks Atlas Which Contains Pre-Rendered Textures For Blocks In The Inventory - if (feature_has("Disable gui_blocks Atlas")) { + if (feature_has("Disable \"gui_blocks\" Atlas", 0)) { unsigned char disable_gui_blocks_atlas_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" patch((void *) 0x63c2c, disable_gui_blocks_atlas_patch); // Fix Grass And Leaves Inventory Rendering When The gui_blocks Atlas Is Disabled diff --git a/mods/src/camera/camera.cpp b/mods/src/camera/camera.cpp index b75b3df..a6585a6 100644 --- a/mods/src/camera/camera.cpp +++ b/mods/src/camera/camera.cpp @@ -1,10 +1,10 @@ #include - -#include "../init/init.h" - #include #include +#include "../init/init.h" +#include "../feature/feature.h" + // Take Screenshot Using TripodCamera static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) unsigned char *app_platform, __attribute__((unused)) std::string const& path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) { media_take_screenshot(); @@ -30,12 +30,16 @@ static void TripodCamera_tick_Level_addParticle_call_injection(unsigned char *le (*Level_addParticle)(level, particle, x, y + 0.5, z, deltaX, deltaY, deltaZ, count); } +// Init void init_camera() { // Implement AppPlatform_linux::saveScreenshot So Cameras Work patch_address(AppPlatform_linux_saveScreenshot_vtable_addr, (void *) AppPlatform_linux_saveScreenshot_injection); - // Enable TripodCameraRenderer - overwrite_calls((void *) EntityRenderDispatcher, (void *) EntityRenderDispatcher_injection); - // Display Smoke From TripodCamera Higher - overwrite_call((void *) 0x87dc4, (void *) TripodCamera_tick_Level_addParticle_call_injection); + // Fix Camera Rendering + if (feature_has("Fix Camera Rendering", 0)) { + // Enable TripodCameraRenderer + overwrite_calls((void *) EntityRenderDispatcher, (void *) EntityRenderDispatcher_injection); + // Display Smoke From TripodCamera Higher + overwrite_call((void *) 0x87dc4, (void *) TripodCamera_tick_Level_addParticle_call_injection); + } } diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index d90672c..f23aacb 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -8,9 +8,13 @@ #include #include "../init/init.h" - +#include "../feature/feature.h" +#include "../input/input.h" #include "chat.h" +// Store If Chat is Enabled +int _chat_enabled = 0; + // Message Limitations #define MAX_CHAT_MESSAGE_LENGTH 512 @@ -88,13 +92,14 @@ void _chat_queue_message(char *message) { } // Empty Queue unsigned int old_chat_counter = 0; -void chat_send_messages(unsigned char *minecraft) { +static void send_queued_messages(unsigned char *minecraft) { // Lock pthread_mutex_lock(&queue_mutex); // If Message Was Submitted, No Other Chat Windows Are Open, And The Game Is Not Paused, Then Re-Lock Cursor unsigned int new_chat_counter = chat_get_counter(); if (old_chat_counter > new_chat_counter && new_chat_counter == 0 && (*(unsigned char **) (minecraft + Minecraft_screen_property_offset)) == NULL) { - (*Minecraft_grabMouse)(minecraft); + // Grab Mouse + input_set_mouse_grab_state(-1); } old_chat_counter = new_chat_counter; // Loop @@ -108,11 +113,16 @@ void chat_send_messages(unsigned char *minecraft) { // Init void init_chat() { - // Disable Original ChatPacket Loopback - unsigned char disable_chat_packet_loopback_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" - patch((void *) 0x6b490, disable_chat_packet_loopback_patch); - // Manually Send (And Loopback) ChatPacket - overwrite_call((void *) 0x6b518, (void *) CommandServer_parse_CommandServer_dispatchPacket_injection); - // Re-Broadcast ChatPacket - patch_address(ServerSideNetworkHandler_handle_ChatPacket_vtable_addr, (void *) ServerSideNetworkHandler_handle_ChatPacket_injection); -} \ No newline at end of file + _chat_enabled = feature_has("Implement Chat", 1); + if (_chat_enabled) { + // Disable Original ChatPacket Loopback + unsigned char disable_chat_packet_loopback_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" + patch((void *) 0x6b490, disable_chat_packet_loopback_patch); + // Manually Send (And Loopback) ChatPacket + overwrite_call((void *) 0x6b518, (void *) CommandServer_parse_CommandServer_dispatchPacket_injection); + // Re-Broadcast ChatPacket + patch_address(ServerSideNetworkHandler_handle_ChatPacket_vtable_addr, (void *) ServerSideNetworkHandler_handle_ChatPacket_injection); + // Send Messages On Input Tick + input_run_on_tick(send_queued_messages); + } +} diff --git a/mods/src/chat/chat.h b/mods/src/chat/chat.h index 806c361..0beccbf 100644 --- a/mods/src/chat/chat.h +++ b/mods/src/chat/chat.h @@ -6,10 +6,10 @@ extern "C" { void chat_open(); unsigned int chat_get_counter(); -void chat_send_messages(unsigned char *minecraft); +__attribute__((visibility("internal"))) extern int _chat_enabled; __attribute__((visibility("internal"))) void _chat_queue_message(char *message); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/mods/src/chat/ui.c b/mods/src/chat/ui.c index 8eeddae..6fea101 100644 --- a/mods/src/chat/ui.c +++ b/mods/src/chat/ui.c @@ -6,6 +6,7 @@ #include #include "chat.h" +#include "../input/input.h" // Run Command static char *run_command(char *command, int *return_code) { @@ -72,11 +73,16 @@ static void *chat_thread(__attribute__((unused)) void *nop) { // Create Chat Thead void chat_open() { - // Update Counter - pthread_mutex_lock(&chat_counter_lock); - chat_counter++; - pthread_mutex_unlock(&chat_counter_lock); - // Start Thread - pthread_t thread; - pthread_create(&thread, NULL, chat_thread, NULL); + if (_chat_enabled) { + // Release Mouse + input_set_mouse_grab_state(1); + + // Update Counter + pthread_mutex_lock(&chat_counter_lock); + chat_counter++; + pthread_mutex_unlock(&chat_counter_lock); + // Start Thread + pthread_t thread; + pthread_create(&thread, NULL, chat_thread, NULL); + } } diff --git a/mods/src/compat/compat.c b/mods/src/compat/compat.c index d5fb5ef..00a3cf9 100644 --- a/mods/src/compat/compat.c +++ b/mods/src/compat/compat.c @@ -6,7 +6,6 @@ #include #include -#include "../feature/feature.h" #include "../input/input.h" #include "../sign/sign.h" #include "../chat/chat.h" @@ -65,8 +64,6 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) { } else if (event->key.keysym.sym == SDLK_t) { // Only When In-Game With No Other Chat Windows Open if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON && chat_get_counter() == 0) { - // Release Mouse - input_set_mouse_grab_state(1); // Open Chat chat_open(); } @@ -74,7 +71,10 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) { handled = 1; } else if (event->key.keysym.sym == SDLK_ESCAPE) { // Treat Escape As Back Button Press (This Fixes Issues With Signs) - input_back(); + handled = input_back(); + } else if (event->key.keysym.sym == SDLK_q) { + // Drop Item + input_drop((event->key.keysym.mod & KMOD_CTRL) != 0); handled = 1; } break; diff --git a/mods/src/death/death.cpp b/mods/src/death/death.cpp index b467b4d..70d603e 100644 --- a/mods/src/death/death.cpp +++ b/mods/src/death/death.cpp @@ -4,6 +4,7 @@ #include #include "../init/init.h" +#include "../feature/feature.h" // Death Messages static std::string get_death_message(unsigned char *player) { @@ -61,6 +62,8 @@ static void LocalPlayer_actuallyHurt_injection(unsigned char *player, int32_t da // Init void init_death() { // Death Messages - patch_address(ServerPlayer_actuallyHurt_vtable_addr, (void *) ServerPlayer_actuallyHurt_injection); - patch_address(LocalPlayer_actuallyHurt_vtable_addr, (void *) LocalPlayer_actuallyHurt_injection); + if (feature_has("Implement Death Messages", 1)) { + patch_address(ServerPlayer_actuallyHurt_vtable_addr, (void *) ServerPlayer_actuallyHurt_injection); + patch_address(LocalPlayer_actuallyHurt_vtable_addr, (void *) LocalPlayer_actuallyHurt_injection); + } } diff --git a/mods/src/feature/feature.c b/mods/src/feature/feature.c index b977360..476af7d 100644 --- a/mods/src/feature/feature.c +++ b/mods/src/feature/feature.c @@ -6,7 +6,17 @@ #include "feature.h" // Check For Feature -int feature_has(const char *name) { +int feature_has(const char *name, int server_default) { + // Default Value For Server Mode +#ifdef MCPI_SERVER_MODE + if (server_default != -1) { + return server_default; + } +#else + (void) server_default; +#endif + + // Get Value char *env = getenv("MCPI_FEATURE_FLAGS"); char *features = strdup(env != NULL ? env : ""); char *tok = strtok(features, "|"); diff --git a/mods/src/feature/feature.h b/mods/src/feature/feature.h index 740addc..922d74a 100644 --- a/mods/src/feature/feature.h +++ b/mods/src/feature/feature.h @@ -4,7 +4,7 @@ extern "C" { #endif -int feature_has(const char *name); +int feature_has(const char *name, int server_default); #ifdef __cplusplus } diff --git a/mods/src/game-mode/game-mode.c b/mods/src/game-mode/game-mode.c index 359ddf7..f61024d 100644 --- a/mods/src/game-mode/game-mode.c +++ b/mods/src/game-mode/game-mode.c @@ -1,8 +1,8 @@ -#include - #include "game-mode.h" #include "../init/init.h" +#include "../feature/feature.h" +#include #include static int is_survival = -1; @@ -35,23 +35,26 @@ static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t n (*Minecraft_setIsCreativeMode)(this, new_game_mode); } +// Init void init_game_mode() { - // Dynamic Game Mode Switching - set_is_survival(1); - overwrite_calls((void *) Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection); + if (feature_has("Implement Game-Mode Switching", 1)) { + // Dynamic Game Mode Switching + set_is_survival(1); + overwrite_calls((void *) Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection); - // Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning) - unsigned char level_patch[4] = {0x68, 0x7e, 0x01, 0xeb}; // "bl 0x7692c" - patch((void *) 0x16f84, level_patch); + // Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning) + unsigned char level_patch[4] = {0x68, 0x7e, 0x01, 0xeb}; // "bl 0x7692c" + patch((void *) 0x16f84, level_patch); - // Allocate Correct Size For ServerLevel - uint32_t level_size = SERVER_LEVEL_SIZE; - patch((void *) 0x17004, (unsigned char *) &level_size); + // Allocate Correct Size For ServerLevel + uint32_t level_size = SERVER_LEVEL_SIZE; + patch((void *) 0x17004, (unsigned char *) &level_size); - // Allow Connecting To Survival Servers - unsigned char server_patch[4] = {0x0f, 0x00, 0x00, 0xea}; // "b 0x6dcb4" - patch((void *) 0x6dc70, server_patch); + // Allow Connecting To Survival Servers + unsigned char server_patch[4] = {0x0f, 0x00, 0x00, 0xea}; // "b 0x6dcb4" + patch((void *) 0x6dc70, server_patch); - // Init C++ - _init_game_mode_cpp(); + // Init C++ + _init_game_mode_cpp(); + } } diff --git a/mods/src/input/README.md b/mods/src/input/README.md index 5ecb7b0..b2ab763 100644 --- a/mods/src/input/README.md +++ b/mods/src/input/README.md @@ -1,8 +1,10 @@ # ``input`` Mod This mod fixes various input-related bugs, including: -- Bows being broken. -- The cursor interacting with the hotbar while the it is locked. -- Being unable to attack mobs. +* Bows being broken. +* The cursor interacting with the toolbar while the it is locked. +* Being unable to attack mobs. +* The ``ESC`` key not behaving as expected. It also adds various features, including: -- Hide GUI and third person toggle keys. +* Hide GUI and third person toggle keys. +* Dropping items with ``Q``. diff --git a/mods/src/input/attack.c b/mods/src/input/attack.c new file mode 100644 index 0000000..3060ded --- /dev/null +++ b/mods/src/input/attack.c @@ -0,0 +1,45 @@ +#include +#include + +#include "../feature/feature.h" +#include "input.h" + +// Store Left Click (0 = Not Pressed, 1 = Pressed, 2 = Repeat) +// This Is Set To Repeat After First Attempted Left-Click Build Interaction +static int is_left_click = 0; +void input_set_is_left_click(int val) { + if ((is_left_click == 0 && val == 1) || (is_left_click != 0 && val == 0) || (is_left_click == 1 && val == 2)) { + is_left_click = val; + } +} + +// Add Attacking To MouseBuildInput +static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_input, unsigned char *local_player, uint32_t *build_action_intention_return) { + // Call Original Method + int32_t ret = (*MouseBuildInput_tickBuild)(mouse_build_input, local_player, build_action_intention_return); + + // Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click + if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) { + // Get Target HitResult + unsigned char *minecraft = *(unsigned char **) (local_player + LocalPlayer_minecraft_property_offset); + unsigned char *hit_result = minecraft + Minecraft_hit_result_property_offset; + int32_t hit_result_type = *(int32_t *) (hit_result + HitResult_type_property_offset); + // Check if The Target Is An Entity Using HitResult + if (hit_result_type == 1) { + // Change BuildActionIntention To Attack/Place Mode (Place Will Not Happen Because The HitResult Is An Entity) + *build_action_intention_return = 0x8; + } + // Block Repeat Changes Without Releasing Left Click + is_left_click = 2; + } + + return ret; +} + +// Init +void _init_attack() { + // Allow Attacking Mobs + if (feature_has("Fix Attacking", 0)) { + patch_address(MouseBuildInput_tickBuild_vtable_addr, (void *) MouseBuildInput_tickBuild_injection); + } +} diff --git a/mods/src/input/bow.c b/mods/src/input/bow.c new file mode 100644 index 0000000..deebbdf --- /dev/null +++ b/mods/src/input/bow.c @@ -0,0 +1,35 @@ +#include +#include + +#include "../feature/feature.h" +#include "input.h" + +// Store Right-Click Status +static int is_right_click = 0; +void input_set_is_right_click(int val) { + is_right_click = val; +} + +// Enable Bow & Arrow Fix +static int fix_bow = 0; + +// Handle Bow & Arrow +void _handle_bow(unsigned char *minecraft) { + if (fix_bow && !is_right_click) { + // GameMode Is Offset From minecraft By 0x160 + // Player Is Offset From minecraft By 0x18c + unsigned char *game_mode = *(unsigned char **) (minecraft + Minecraft_game_mode_property_offset); + unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); + if (player != NULL && game_mode != NULL && (*Player_isUsingItem)(player)) { + unsigned char *game_mode_vtable = *(unsigned char **) game_mode; + GameMode_releaseUsingItem_t GameMode_releaseUsingItem = *(GameMode_releaseUsingItem_t *) (game_mode_vtable + GameMode_releaseUsingItem_vtable_offset); + (*GameMode_releaseUsingItem)(game_mode, player); + } + } +} + +// Init +void _init_bow() { + // Enable Bow & Arrow Fix + fix_bow = feature_has("Fix Bow & Arrow", 0); +} diff --git a/mods/src/input/drop.cpp b/mods/src/input/drop.cpp new file mode 100644 index 0000000..2cc9650 --- /dev/null +++ b/mods/src/input/drop.cpp @@ -0,0 +1,88 @@ +#include +#include + +#include "input.h" +#include "../feature/feature.h" + +// Enable Item Dropping +static int enable_drop = 0; + +// Store Drop Item Presses +static int drop_item_presses = 0; +static bool drop_slot_pressed = false; +void input_drop(int drop_slot) { + if (enable_drop) { + if (drop_slot) { + drop_slot_pressed = true; + } else { + drop_item_presses++; + } + } +} + +// Handle Drop Item Presses +void _handle_drop(unsigned char *minecraft) { + if (!(*Minecraft_isCreativeMode)(minecraft) && (drop_item_presses > 0 || drop_slot_pressed)) { + // Get Player + unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); + if (player != NULL) { + // Get Selected Slot + unsigned char *inventory = *(unsigned char **) (player + Player_inventory_property_offset); + int32_t selected_slot = *(int32_t *) (inventory + Inventory_selectedSlot_property_offset); + + // Prepare + unsigned char *player_vtable = *(unsigned char **) player; + Player_drop_t Player_drop = *(Player_drop_t *) (player_vtable + Player_drop_vtable_offset); + unsigned char *inventory_vtable = *(unsigned char **) inventory; + FillingContainer_getItem_t FillingContainer_getItem = *(FillingContainer_getItem_t *) (inventory_vtable + FillingContainer_getItem_vtable_offset); + + // Linked Slots + int32_t linked_slots_length = *(int32_t *) (inventory + FillingContainer_linked_slots_length_property_offset); + if (selected_slot < linked_slots_length) { + int32_t *linked_slots = *(int32_t **) (inventory + FillingContainer_linked_slots_property_offset); + selected_slot = linked_slots[selected_slot]; + } + + // Get Item + ItemInstance *inventory_item = (*FillingContainer_getItem)(inventory, selected_slot); + // Check + if (inventory_item != NULL && inventory_item->count > 0) { + // Copy + ItemInstance *dropped_item = new ItemInstance; + *dropped_item = *inventory_item; + + // Update Inventory + if (drop_slot_pressed) { + // Drop Slot + + // Empty Slot + inventory_item->count = 0; + } else { + // Drop Item + + // Set Item Drop Count + int drop_count = drop_item_presses < inventory_item->count ? drop_item_presses : inventory_item->count; + dropped_item->count = drop_count; + inventory_item->count -= drop_count; + } + + // Empty Slot If Needed + if (inventory_item->count < 1) { + (*FillingContainer_release)(inventory, selected_slot); + (*FillingContainer_compressLinkedSlotList)(inventory, selected_slot); + } + + // Drop + (*Player_drop)(player, dropped_item); + } + } + } + // Reset + drop_item_presses = 0; + drop_slot_pressed = false; +} + +// Init +void _init_drop() { + enable_drop = feature_has("Bind \"Q\" Key To Item Dropping", 0); +} diff --git a/mods/src/input/input.c b/mods/src/input/input.c deleted file mode 100644 index 7478027..0000000 --- a/mods/src/input/input.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include - -#include "../feature/feature.h" -#include "../init/init.h" -#include "../chat/chat.h" -#include "../sign/sign.h" - -// Store Right-Click Status -static int is_right_click = 0; -void input_set_is_right_click(int val) { - is_right_click = val; -} - -// Enable Bow & Arrow Fix -static int fix_bow = 0; - -// Store Function Input -static int hide_gui_toggle = 0; -void input_hide_gui() { - hide_gui_toggle++; -} -static int third_person_toggle = 0; -void input_third_person() { - third_person_toggle++; -} - -// Set Mouse Grab State -static int mouse_grab_state = 0; -void input_set_mouse_grab_state(int state) { - mouse_grab_state = state; -} - -// Store Back Button Presses -static int back_button_presses =0; -void input_back() { - back_button_presses++; -} - -// Handle Input Fixes -static void Minecraft_tickInput_injection(unsigned char *minecraft) { - // Call Original Method - (*Minecraft_tickInput)(minecraft); - - if (fix_bow && !is_right_click) { - // GameMode Is Offset From minecraft By 0x160 - // Player Is Offset From minecraft By 0x18c - unsigned char *game_mode = *(unsigned char **) (minecraft + Minecraft_game_mode_property_offset); - unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); - if (player != NULL && game_mode != NULL && (*Player_isUsingItem)(player)) { - unsigned char *game_mode_vtable = *(unsigned char **) game_mode; - GameMode_releaseUsingItem_t GameMode_releaseUsingItem = *(GameMode_releaseUsingItem_t *) (game_mode_vtable + GameMode_releaseUsingItem_vtable_offset); - (*GameMode_releaseUsingItem)(game_mode, player); - } - } - - // Clear Unused Sign Input - sign_clear_input(); - - // Handle Functions - unsigned char *options = minecraft + Minecraft_options_property_offset; - if (hide_gui_toggle % 2 != 0) { - // Toggle Hide GUI - *(options + Options_hide_gui_property_offset) = *(options + Options_hide_gui_property_offset) ^ 1; - } - hide_gui_toggle = 0; - if (third_person_toggle % 2 != 0) { - // Toggle Third Person - *(options + Options_third_person_property_offset) = *(options + Options_third_person_property_offset) ^ 1; - } - third_person_toggle = 0; - - // Send Queued Chat Message - chat_send_messages(minecraft); - - // Set Mouse Grab State - if (mouse_grab_state == -1) { - // Grab - (*Minecraft_grabMouse)(minecraft); - } else if (mouse_grab_state == 1) { - // Un-Grab - (*Minecraft_releaseMouse)(minecraft); - } - mouse_grab_state = 0; - - // Handle Back Button - unsigned char *minecraft_vtable = *(unsigned char **) minecraft; - Minecraft_handleBack_t Minecraft_handleBack = *(Minecraft_handleBack_t *) (minecraft_vtable + Minecraft_handleBack_vtable_offset); - for (int i = 0; i < back_button_presses; i++) { - (*Minecraft_handleBack)(minecraft, 0); - } - back_button_presses = 0; -} - -#include - -// Block UI Interaction When Mouse Is Locked -static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned char *minecraft) { - if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { - // Call Original Method - return (*Minecraft_isCreativeMode)(minecraft); - } else { - // Disable Item Drop Ticking - return 1; - } -} - -// Block UI Interaction When Mouse Is Locked -static void Gui_handleClick_injection(unsigned char *this, int32_t param_2, int32_t param_3, int32_t param_4) { - if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { - // Call Original Method - (*Gui_handleClick)(this, param_2, param_3, param_4); - } -} - -// Store Left Click (0 = Not Pressed, 1 = Pressed, 2 = Repeat) -// This Is Set To Repeat After First Attempted Left-Click Build Interaction -static int is_left_click = 0; -void input_set_is_left_click(int val) { - if ((is_left_click == 0 && val == 1) || (is_left_click != 0 && val == 0) || (is_left_click == 1 && val == 2)) { - is_left_click = val; - } -} - -// Add Attacking To MouseBuildInput -static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_input, unsigned char *local_player, uint32_t *build_action_intention_return) { - // Call Original Method - int32_t ret = (*MouseBuildInput_tickBuild)(mouse_build_input, local_player, build_action_intention_return); - - // Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click - if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) { - // Get Target HitResult - unsigned char *minecraft = *(unsigned char **) (local_player + LocalPlayer_minecraft_property_offset); - unsigned char *hit_result = minecraft + Minecraft_hit_result_property_offset; - int32_t hit_result_type = *(int32_t *) (hit_result + HitResult_type_property_offset); - // Check if The Target Is An Entity Using HitResult - if (hit_result_type == 1) { - // Change BuildActionIntention To Attack/Place Mode (Place Will Not Happen Because The HitResult Is An Entity) - *build_action_intention_return = 0x8; - } - // Block Repeat Changes Without Releasing Left Click - is_left_click = 2; - } - - return ret; -} - -void init_input() { - // Disable Item Dropping Using The Cursor When Cursor Is Hidden - overwrite_call((void *) 0x27800, Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection); - // Disable Opening Inventory Using The Cursor When Cursor Is Hidden - overwrite_calls((void *) Gui_handleClick, Gui_handleClick_injection); - - // Enable Bow & Arrow Fix - fix_bow = feature_has("Fix Bow & Arrow"); - // Fix Bow & Arrow + Clear Unused Sign Input - overwrite_calls((void *) Minecraft_tickInput, Minecraft_tickInput_injection); - - if (feature_has("Fix Attacking")) { - // Allow Attacking Mobs - patch_address(MouseBuildInput_tickBuild_vtable_addr, (void *) MouseBuildInput_tickBuild_injection); - } -} diff --git a/mods/src/input/input.cpp b/mods/src/input/input.cpp new file mode 100644 index 0000000..4346ca0 --- /dev/null +++ b/mods/src/input/input.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include + +#include "../feature/feature.h" +#include "../init/init.h" +#include "input.h" + +// Run Functions On Input Tick +static std::vector &get_input_tick_functions() { + static std::vector functions; + return functions; +} +void input_run_on_tick(input_tick_function_t function) { + get_input_tick_functions().push_back(function); +} + +// Handle Input Fixes +static void Minecraft_tickInput_injection(unsigned char *minecraft) { + // Call Original Method + (*Minecraft_tickInput)(minecraft); + + // Handle Bow + _handle_bow(minecraft); + + // Handle Toggle Options + _handle_toggle_options(minecraft); + + // Set Mouse Grab State + _handle_mouse_grab(minecraft); + + // Handle Back Button + _handle_back(minecraft); + + // Handle Item Drops + _handle_drop(minecraft); + + // Run Input Tick Functions + for (input_tick_function_t function : get_input_tick_functions()) { + (*function)(minecraft); + } +} + +// Init +void init_input() { + // Miscellaneous + _init_misc(); + + // Toggleable Options + _init_toggle(); + + // Item Dropping + _init_drop(); + + // Enable Bow & Arrow Fix + _init_bow(); + + // Loop + overwrite_calls((void *) Minecraft_tickInput, (void *) Minecraft_tickInput_injection); + + // Allow Attacking Mobs + _init_attack(); +} diff --git a/mods/src/input/input.h b/mods/src/input/input.h index 40d9cc3..b18b374 100644 --- a/mods/src/input/input.h +++ b/mods/src/input/input.h @@ -4,15 +4,30 @@ extern "C" { #endif +typedef void (*input_tick_function_t)(unsigned char *minecraft); +void input_run_on_tick(input_tick_function_t function); + void input_set_is_right_click(int val); void input_hide_gui(); void input_third_person(); -void input_back(); +int input_back(); +void input_drop(int drop_slot); void input_set_is_left_click(int val); void input_set_mouse_grab_state(int state); +__attribute__((visibility("internal"))) void _init_attack(); +__attribute__((visibility("internal"))) void _init_bow(); +__attribute__((visibility("internal"))) void _handle_bow(unsigned char *minecraft); +__attribute__((visibility("internal"))) void _handle_toggle_options(unsigned char *minecraft); +__attribute__((visibility("internal"))) void _init_misc(); +__attribute__((visibility("internal"))) void _init_toggle(); +__attribute__((visibility("internal"))) void _handle_mouse_grab(unsigned char *minecraft); +__attribute__((visibility("internal"))) void _handle_back(unsigned char *minecraft); +__attribute__((visibility("internal"))) void _init_drop(); +__attribute__((visibility("internal"))) void _handle_drop(unsigned char *minecraft); + #ifdef __cplusplus } #endif diff --git a/mods/src/input/misc.c b/mods/src/input/misc.c new file mode 100644 index 0000000..b3c7030 --- /dev/null +++ b/mods/src/input/misc.c @@ -0,0 +1,89 @@ +#include +#include + +#include "input.h" +#include "../feature/feature.h" + +// Enable Miscellaneous Input Fixes +static int enable_misc = 0; + +// Store Back Button Presses +static int back_button_presses = 0; +int input_back() { + if (enable_misc) { + back_button_presses++; + return 1; // Handled + } else { + return 0; // Not Handled + } +} + +// Handle Back Button Presses +void _handle_back(unsigned char *minecraft) { + unsigned char *minecraft_vtable = *(unsigned char **) minecraft; + Minecraft_handleBack_t Minecraft_handleBack = *(Minecraft_handleBack_t *) (minecraft_vtable + Minecraft_handleBack_vtable_offset); + for (int i = 0; i < back_button_presses; i++) { + (*Minecraft_handleBack)(minecraft, 0); + } + back_button_presses = 0; +} + +// Fix OptionsScreen Ignoring The Back Button +static int32_t OptionsScreen_handleBackEvent_injection(unsigned char *screen, __attribute__((unused)) bool param_1) { + unsigned char *minecraft = *(unsigned char **) (screen + Screen_minecraft_property_offset); + (*Minecraft_setScreen)(minecraft, NULL); + return 1; +} + +// Set Mouse Grab State +static int mouse_grab_state = 0; +void input_set_mouse_grab_state(int state) { + mouse_grab_state = state; +} + +// Grab/Un-Grab Mouse +void _handle_mouse_grab(unsigned char *minecraft) { + if (mouse_grab_state == -1) { + // Grab + (*Minecraft_grabMouse)(minecraft); + } else if (mouse_grab_state == 1) { + // Un-Grab + (*Minecraft_releaseMouse)(minecraft); + } + mouse_grab_state = 0; +} + +#include + +// Block UI Interaction When Mouse Is Locked +static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned char *minecraft) { + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { + // Call Original Method + return (*Minecraft_isCreativeMode)(minecraft); + } else { + // Disable Item Drop Ticking + return 1; + } +} + +// Block UI Interaction When Mouse Is Locked +static void Gui_handleClick_injection(unsigned char *gui, int32_t param_2, int32_t param_3, int32_t param_4) { + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { + // Call Original Method + (*Gui_handleClick)(gui, param_2, param_3, param_4); + } +} + +// Init +void _init_misc() { + enable_misc = feature_has("Miscellaneous Input Fixes", 0); + if (enable_misc) { + // Fix OptionsScreen Ignoring The Back Button + patch_address(OptionsScreen_handleBackEvent_vtable_addr, (void *) OptionsScreen_handleBackEvent_injection); + + // Disable Item Dropping Using The Cursor When Cursor Is Hidden + overwrite_call((void *) 0x27800, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection); + // Disable Opening Inventory Using The Cursor When Cursor Is Hidden + overwrite_calls((void *) Gui_handleClick, (void *) Gui_handleClick_injection); + } +} diff --git a/mods/src/input/toggle.c b/mods/src/input/toggle.c new file mode 100644 index 0000000..8595a94 --- /dev/null +++ b/mods/src/input/toggle.c @@ -0,0 +1,41 @@ +#include +#include + +#include "input.h" +#include "../feature/feature.h" + +// Enable Toggles +static int enable_toggles = 0; + +// Store Function Input +static int hide_gui_toggle = 0; +void input_hide_gui() { + hide_gui_toggle++; +} +static int third_person_toggle = 0; +void input_third_person() { + third_person_toggle++; +} + +// Handle Toggle Options +void _handle_toggle_options(unsigned char *minecraft) { + if (enable_toggles) { + // Handle Functions + unsigned char *options = minecraft + Minecraft_options_property_offset; + if (hide_gui_toggle % 2 != 0) { + // Toggle Hide GUI + *(options + Options_hide_gui_property_offset) = *(options + Options_hide_gui_property_offset) ^ 1; + } + hide_gui_toggle = 0; + if (third_person_toggle % 2 != 0) { + // Toggle Third Person + *(options + Options_third_person_property_offset) = *(options + Options_third_person_property_offset) ^ 1; + } + third_person_toggle = 0; + } +} + +// Init +void _init_toggle() { + enable_toggles = feature_has("Bind Common Toggleable Options To Function Keys", 0); +} diff --git a/mods/src/misc/misc.c b/mods/src/misc/misc.c index c08721c..5c81525 100644 --- a/mods/src/misc/misc.c +++ b/mods/src/misc/misc.c @@ -66,16 +66,18 @@ static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit // Init void init_misc() { - if (feature_has("Remove Invalid Item Background")) { + if (feature_has("Remove Invalid Item Background", 0)) { // Remove Invalid Item Background (A Red Background That Appears For Items That Are Not Included In The gui_blocks Atlas) unsigned char invalid_item_background_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" patch((void *) 0x63c98, invalid_item_background_patch); } // Fix Selected Item Text - overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection); - overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection); - overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection); + if (feature_has("Render Selected Item Text", 0)) { + overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection); + overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection); + overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection); + } // Sanitize Username patch_address(LoginPacket_read_vtable_addr, (void *) LoginPacket_read_injection); diff --git a/mods/src/misc/misc.cpp b/mods/src/misc/misc.cpp index 31e85ee..5fc9094 100644 --- a/mods/src/misc/misc.cpp +++ b/mods/src/misc/misc.cpp @@ -27,14 +27,14 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio // Add Item To Inventory static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) { - unsigned char *item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE); + ItemInstance *item_instance = new ItemInstance; ALLOC_CHECK(item_instance); item_instance = (*(is_tile ? ItemInstance_constructor_tile : ItemInstance_constructor_item))(item_instance, item); (*FillingContainer_addItem)(inventory, item_instance); } // Expand Creative Inventory -static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container, unsigned char *item_instance) { +static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container, ItemInstance *item_instance) { // Call Original int32_t ret = (*FillingContainer_addItem)(filling_container, item_instance); @@ -48,7 +48,7 @@ static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(un // Bonemeal Is Already In The Creative Inventory continue; } - unsigned char *item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE); + ItemInstance *item_instance = new ItemInstance; ALLOC_CHECK(item_instance); item_instance = (*ItemInstance_constructor_item_extra)(item_instance, *Item_dye_powder, 1, i); (*FillingContainer_addItem)(filling_container, item_instance); @@ -101,10 +101,12 @@ static void Gui_addMessage_injection(unsigned char *gui, std::string const& text // Init void _init_misc_cpp() { // Implement AppPlatform::readAssetFile So Translations Work - overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); + if (feature_has("Load Language Files", 1)) { + overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); + } // Add Extra Items To Creative Inventory (Only Replace Specific Function Call) - if (feature_has("Expand Creative Inventory")) { + if (feature_has("Expand Creative Inventory", 0)) { overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection); } diff --git a/mods/src/multiplayer/multiplayer.cpp b/mods/src/multiplayer/multiplayer.cpp index c2da830..3e6a748 100644 --- a/mods/src/multiplayer/multiplayer.cpp +++ b/mods/src/multiplayer/multiplayer.cpp @@ -12,6 +12,7 @@ #include "../home/home.h" #include "../init/init.h" +#include "../feature/feature.h" // Load Server List struct server_list_entry { @@ -125,5 +126,7 @@ static void RakNetInstance_pingForHosts_injection(unsigned char *rak_net_instanc // Init void init_multiplayer() { // Inject Code - patch_address(RakNetInstance_pingForHosts_vtable_addr, (void *) RakNetInstance_pingForHosts_injection); + if (feature_has("External Server Support", 0)) { + patch_address(RakNetInstance_pingForHosts_vtable_addr, (void *) RakNetInstance_pingForHosts_injection); + } } diff --git a/mods/src/options/options.c b/mods/src/options/options.c index 34fa95a..5160daa 100644 --- a/mods/src/options/options.c +++ b/mods/src/options/options.c @@ -6,10 +6,9 @@ #include "../feature/feature.h" #include "../init/init.h" -static int mob_spawning = 0; -// Override Mob Spawning -static uint32_t LevelData_getSpawnMobs_injection(__attribute__((unused)) unsigned char *level_data) { - return mob_spawning; +// Force Mob Spawning +static bool LevelData_getSpawnMobs_injection(__attribute__((unused)) unsigned char *level_data) { + return 1; } #ifndef MCPI_SERVER_MODE @@ -69,16 +68,17 @@ static void Minecraft_init_injection(unsigned char *this) { // Init void init_options() { - mob_spawning = feature_has("Mob Spawning"); - // Set Mob Spawning - overwrite((void *) LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection); + // Force Mob Spawning + if (feature_has("Force Mob Spawning", -1)) { + overwrite((void *) LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection); + } // Enable Fancy Graphics - fancy_graphics = feature_has("Fancy Graphics"); + fancy_graphics = feature_has("Fancy Graphics", 0); // Peaceful Mode - peaceful_mode = feature_has("Peaceful Mode"); + peaceful_mode = feature_has("Peaceful Mode", -1); // 3D Anaglyph - anaglyph = feature_has("3D Anaglyph"); + anaglyph = feature_has("3D Anaglyph", 0); // Render Distance #ifndef MCPI_SERVER_MODE render_distance = get_render_distance(); @@ -100,18 +100,18 @@ void init_options() { } patch_address((void *) default_username, (void *) username); - if (feature_has("Disable Autojump By Default")) { + if (feature_has("Disable Autojump By Default", 0)) { // Disable Autojump By Default unsigned char autojump_patch[4] = {0x00, 0x30, 0xa0, 0xe3}; // "mov r3, #0x0" patch((void *) 0x44b90, autojump_patch); } - if (feature_has("Display Nametags By Default")) { + if (feature_has("Display Nametags By Default", 0)) { // Display Nametags By Default unsigned char display_nametags_patch[4] = {0x1d, 0x60, 0xc0, 0xe5}; // "strb r6, [r0, #0x1d]" patch((void *) 0xa6628, display_nametags_patch); } - smooth_lighting = feature_has("Smooth Lighting"); + smooth_lighting = feature_has("Smooth Lighting", 0); if (smooth_lighting) { // Enable Smooth Lighting unsigned char smooth_lighting_patch[4] = {0x01, 0x00, 0x53, 0xe3}; // "cmp r3, #0x1" diff --git a/mods/src/server/server.cpp b/mods/src/server/server.cpp index 26ccde4..c56fddd 100644 --- a/mods/src/server/server.cpp +++ b/mods/src/server/server.cpp @@ -53,7 +53,7 @@ static ServerProperties &get_server_properties() { #define DEFAULT_GAME_MODE "0" #define DEFAULT_PORT "19132" #define DEFAULT_SEED "" -#define DEFAULT_MOB_SPAWNING "true" +#define DEFAULT_FORCE_MOB_SPAWNING "false" #define DEFAULT_PEACEFUL_MODE "false" #define DEFAULT_WORLD_NAME "world" #define DEFAULT_MAX_PLAYERS "4" @@ -433,10 +433,7 @@ static const char *get_features() { if (!loaded_features) { loaded_features = true; - features = ""; - if (get_server_properties().get_bool("spawn-mobs", DEFAULT_MOB_SPAWNING)) { - features += "Mob Spawning|"; - } + features.clear(); if (get_server_properties().get_bool("peaceful-mode", DEFAULT_PEACEFUL_MODE)) { features += "Peaceful Mode|"; } @@ -476,8 +473,8 @@ static void server_init() { properties_file_output << "port=" DEFAULT_PORT "\n"; properties_file_output << "# World Seed (Blank = Random Seed)\n"; properties_file_output << "seed=" DEFAULT_SEED "\n"; - properties_file_output << "# Mob Spawning (false = Disabled, true = Enabled)\n"; - properties_file_output << "spawn-mobs=" DEFAULT_MOB_SPAWNING "\n"; + properties_file_output << "# Force Mob Spawning (false = Disabled, true = Enabled)\n"; + properties_file_output << "force-mob-spawning=" DEFAULT_FORCE_MOB_SPAWNING "\n"; properties_file_output << "# Peaceful Mode (false = Disabled, true = Enabled)\n"; properties_file_output << "peaceful-mode=" DEFAULT_PEACEFUL_MODE "\n"; properties_file_output << "# World To Select\n"; diff --git a/mods/src/sign/sign.cpp b/mods/src/sign/sign.cpp index 3bdf12f..7fc5b39 100644 --- a/mods/src/sign/sign.cpp +++ b/mods/src/sign/sign.cpp @@ -5,6 +5,7 @@ #include "../init/init.h" #include "../feature/feature.h" +#include "../input/input.h" #include "sign.h" // Open Sign Screen @@ -31,7 +32,7 @@ void sign_key_press(char key) { input.push_back(key); } } -void sign_clear_input() { +static void clear_input(__attribute__((unused)) unsigned char *minecraft) { input.clear(); } @@ -52,14 +53,16 @@ static void TextEditScreen_updateEvents_injection(unsigned char *screen) { } } } - sign_clear_input(); + clear_input(NULL); } // Init void init_sign() { - if (feature_has("Fix Sign Placement")) { + if (feature_has("Fix Sign Placement", 0)) { // Fix Signs patch_address(LocalPlayer_openTextEdit_vtable_addr, (void *) LocalPlayer_openTextEdit_injection); patch_address(TextEditScreen_updateEvents_vtable_addr, (void *) TextEditScreen_updateEvents_injection); + // Clear input On Input Tick + input_run_on_tick(clear_input); } } diff --git a/mods/src/sign/sign.h b/mods/src/sign/sign.h index 2775fb0..fd65431 100644 --- a/mods/src/sign/sign.h +++ b/mods/src/sign/sign.h @@ -5,7 +5,6 @@ extern "C" { #endif void sign_key_press(char key); -void sign_clear_input(); #ifdef __cplusplus } diff --git a/mods/src/textures/textures.cpp b/mods/src/textures/textures.cpp index 2aefe9d..897a7e4 100644 --- a/mods/src/textures/textures.cpp +++ b/mods/src/textures/textures.cpp @@ -19,7 +19,7 @@ static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1, // Init void init_textures() { // Tick Dynamic Textures (Animated Water) - if (feature_has("Animated Water")) { + if (feature_has("Animated Water", 0)) { overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection); } } diff --git a/mods/src/touch/touch.c b/mods/src/touch/touch.c index d31bc94..0c75710 100644 --- a/mods/src/touch/touch.c +++ b/mods/src/touch/touch.c @@ -31,7 +31,7 @@ static void GameRenderer_render_injection(unsigned char *game_renderer, float pa // Init void init_touch() { - int touch_gui = feature_has("Touch GUI"); + int touch_gui = feature_has("Touch GUI", 0); if (touch_gui) { // Main UI overwrite((void *) Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection); @@ -48,7 +48,7 @@ void init_touch() { } // Show Block Outlines - int block_outlines = feature_has("Show Block Outlines"); + int block_outlines = feature_has("Show Block Outlines", 0); unsigned char outline_patch[4] = {block_outlines ? !touch_gui : touch_gui, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1" or "cmp r0, #0x0" patch((void *) 0x4a210, outline_patch); }