2.1.0
minecraft-pi-reborn/pipeline/head This commit looks good
Details
minecraft-pi-reborn/pipeline/head This commit looks good
Details
parent
6e6537eea1
commit
7b4a8a4d4f
Binary file not shown.
@ -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();
|
||||
}
|