This commit is contained in:
TheBrokenRail 2021-07-04 19:02:45 -04:00
parent 6e6537eea1
commit 7b4a8a4d4f
38 changed files with 648 additions and 533 deletions

View File

@ -1 +1 @@
2.0.9
2.1.0

View File

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

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
// 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);
}
}

View File

@ -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,6 +113,8 @@ void chat_send_messages(unsigned char *minecraft) {
// Init
void init_chat() {
_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);
@ -115,4 +122,7 @@ void init_chat() {
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);
}
}

View File

@ -6,8 +6,8 @@ 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

View File

@ -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,6 +73,10 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
// Create Chat Thead
void chat_open() {
if (_chat_enabled) {
// Release Mouse
input_set_mouse_grab_state(1);
// Update Counter
pthread_mutex_lock(&chat_counter_lock);
chat_counter++;
@ -80,3 +85,4 @@ void chat_open() {
pthread_t thread;
pthread_create(&thread, NULL, chat_thread, NULL);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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,7 +35,9 @@ static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t n
(*Minecraft_setIsCreativeMode)(this, new_game_mode);
}
// Init
void init_game_mode() {
if (feature_has("Implement Game-Mode Switching", 1)) {
// Dynamic Game Mode Switching
set_is_survival(1);
overwrite_calls((void *) Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection);
@ -55,3 +57,4 @@ void init_game_mode() {
// Init C++
_init_game_mode_cpp();
}
}

View File

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

45
mods/src/input/attack.c Normal file
View File

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

35
mods/src/input/bow.c Normal file
View File

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

88
mods/src/input/drop.cpp Normal file
View File

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

View File

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

64
mods/src/input/input.cpp Normal file
View File

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

View File

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

89
mods/src/input/misc.c Normal file
View File

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

41
mods/src/input/toggle.c Normal file
View File

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

View File

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

View File

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

View File

@ -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
if (feature_has("External Server Support", 0)) {
patch_address(RakNetInstance_pingForHosts_vtable_addr, (void *) RakNetInstance_pingForHosts_injection);
}
}

View File

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

View File

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

View File

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

View File

@ -5,7 +5,6 @@ extern "C" {
#endif
void sign_key_press(char key);
void sign_clear_input();
#ifdef __cplusplus
}

View File

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

View File

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