2.1.0
minecraft-pi-reborn/pipeline/head This commit looks good Details

pull/23/head
TheBrokenRail 2 years ago
parent 6e6537eea1
commit 7b4a8a4d4f

@ -1 +1 @@
2.0.9
2.1.0

@ -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)

@ -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

@ -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

@ -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,26 +335,28 @@ 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
// FillingContainer
#define ITEM_INSTANCE_SIZE 0xc
typedef int32_t (*FillingContainer_addItem_t)(unsigned char *filling_container, ItemInstance *item_instance);
static FillingContainer_addItem_t FillingContainer_addItem = (FillingContainer_addItem_t) 0x92aa0;
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 ItemInstance *(*FillingContainer_getItem_t)(unsigned char *filling_container, int32_t slot);
static uint32_t FillingContainer_getItem_vtable_offset = 0x8;
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;
typedef void (*FillingContainer_setItem_t)(unsigned char *filling_container, int32_t slot, ItemInstance *item_instance);
static uint32_t FillingContainer_setItem_vtable_offset = 0xc;
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
typedef void (*FillingContainer_clearSlot_t)(unsigned char *filling_container, int32_t slot);
static FillingContainer_clearSlot_t FillingContainer_clearSlot = (FillingContainer_clearSlot_t) 0x922f8;
// FillingContainer
typedef void (*FillingContainer_release_t)(unsigned char *filling_container, int32_t slot);
static FillingContainer_release_t FillingContainer_release = (FillingContainer_release_t) 0x92058;
typedef int32_t (*FillingContainer_addItem_t)(unsigned char *filling_container, unsigned char *item_instance);
static FillingContainer_addItem_t FillingContainer_addItem = (FillingContainer_addItem_t) 0x92aa0;
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
@ -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

@ -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) {

@ -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
}

@ -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

@ -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(sign SHARED src/sign/sign.cpp)
target_link_libraries(sign 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(input SHARED src/input/input.c)
target_link_libraries(input reborn feature media-layer-core chat sign)
add_library(sign SHARED src/sign/sign.cpp)
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)

@ -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

@ -1,10 +1,10 @@
#include <libreborn/libreborn.h>
#include "../init/init.h"
#include <libreborn/media-layer/core.h>
#include <libreborn/minecraft.h>
#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);
}
}

@ -8,9 +8,13 @@
#include <libreborn/minecraft.h>
#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);
}
_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);
}
}

@ -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
#endif

@ -6,6 +6,7 @@
#include <libreborn/libreborn.h>
#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);
}
}

@ -6,7 +6,6 @@
#include <libreborn/media-layer/core.h>
#include <libreborn/libreborn.h>
#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;

@ -4,6 +4,7 @@
#include <libreborn/minecraft.h>
#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);
}
}

@ -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, "|");

@ -4,7 +4,7 @@
extern "C" {
#endif
int feature_has(const char *name);
int feature_has(const char *name, int server_default);
#ifdef __cplusplus
}

@ -1,8 +1,8 @@
#include <libreborn/libreborn.h>
#include "game-mode.h"
#include "../init/init.h"
#include "../feature/feature.h"
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
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();
}
}

@ -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``.

@ -0,0 +1,45 @@
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#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);
}
}

@ -0,0 +1,35 @@
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#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);
}

@ -0,0 +1,88 @@
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#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);
}

@ -1,163 +0,0 @@
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#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 <SDL/SDL.h>
// 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);
}
}

@ -0,0 +1,64 @@
#include <vector>
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#include "../feature/feature.h"
#include "../init/init.h"
#include "input.h"
// Run Functions On Input Tick
static std::vector<input_tick_function_t> &get_input_tick_functions() {
static std::vector<input_tick_function_t> 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();
}

@ -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();