minecraft.h/.cpp Changes
This commit is contained in:
parent
688bee1aaa
commit
d2b07f7661
@ -59,7 +59,7 @@ string(CONCAT COMPILE_FLAGS_SETUP
|
|||||||
# C Standard
|
# C Standard
|
||||||
"add_definitions(-D_GNU_SOURCE)\n"
|
"add_definitions(-D_GNU_SOURCE)\n"
|
||||||
"set(CMAKE_C_STANDARD 99)\n"
|
"set(CMAKE_C_STANDARD 99)\n"
|
||||||
"set(CMAKE_CXX_STANDARD 11)\n"
|
"set(CMAKE_CXX_STANDARD 20)\n"
|
||||||
|
|
||||||
# Skip RPath
|
# Skip RPath
|
||||||
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
|
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
|
||||||
|
2
dependencies/symbol-processor/src
vendored
2
dependencies/symbol-processor/src
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 6098f57b03cae72668c6d2c1624a3a3f01d13fa9
|
Subproject commit 11342dbb78b8897ddf75fb4c1b72d40915fab245
|
@ -5,82 +5,48 @@
|
|||||||
#if defined(REBORN_HAS_PATCH_CODE) && defined(__cplusplus)
|
#if defined(REBORN_HAS_PATCH_CODE) && defined(__cplusplus)
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void reborn_init_patch();
|
void reborn_init_patch();
|
||||||
|
|
||||||
// Replace Call Located At start With A Call To target
|
// Replace Call Located At start With A Call To target
|
||||||
void _overwrite_call(const char *file, int line, void *start, void *target);
|
void overwrite_call(void *start, void *target);
|
||||||
#define overwrite_call(...) \
|
|
||||||
_overwrite_call(__FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
// Replace All Calls To Method start With target
|
// Replace All Calls To Method start With target
|
||||||
void *_overwrite_calls_manual(const char *file, int line, void *start, void *target);
|
void *overwrite_calls_manual(void *start, void *target, bool allow_no_callsites = false);
|
||||||
#define overwrite_calls_manual(...) \
|
template <typename T>
|
||||||
_overwrite_calls_manual(__FILE__, __LINE__, __VA_ARGS__)
|
void overwrite_calls(T &target, typename T::overwrite_type replacement) {
|
||||||
template <typename overwrite_t>
|
DEBUG("Overwriting Method: %s", target.get_name());
|
||||||
void _overwrite_calls(const char *file, int line, std::string (*set_overwrite)(const overwrite_t &, const std::function<void *(void *, void *)> &), const overwrite_t &target) {
|
if (!target.overwrite(replacement)) {
|
||||||
std::string ret = set_overwrite(target, [&file, &line](void *start, void *target2) {
|
ERR("Unable To Overwrite Method: %s", target.get_name());
|
||||||
return _overwrite_calls_manual(file, line, start, target2);
|
|
||||||
});
|
|
||||||
if (!ret.empty()) {
|
|
||||||
ERR("%s", ret.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define overwrite_calls(start, ...) \
|
|
||||||
_overwrite_calls< \
|
// Thunk Enabler
|
||||||
__overwrite_##start##_t \
|
void *reborn_thunk_enabler(void *target, void *thunk);
|
||||||
>( \
|
|
||||||
__FILE__, __LINE__, \
|
|
||||||
__set_overwrite_for_##start, \
|
|
||||||
__VA_ARGS__ \
|
|
||||||
)
|
|
||||||
|
|
||||||
// Replace All Calls To start With target Within [to, from)
|
// Replace All Calls To start With target Within [to, from)
|
||||||
void _overwrite_calls_within_manual(const char *file, int line, void *from, void *to, void *start, void *target);
|
void overwrite_calls_within_manual(void *from, void *to, void *start, void *target);
|
||||||
#define overwrite_calls_within_manual(...) \
|
template <typename T>
|
||||||
_overwrite_calls_within(__FILE__, __LINE__, __VA_ARGS__)
|
void _overwrite_calls_within(void *from, void *to, const T &start, typename T::ptr_type target) {
|
||||||
template <typename start_t>
|
overwrite_calls_within_manual(from, to, (void *) start, (void *) target);
|
||||||
void _overwrite_calls_within(const char *file, int line, void *from, void *to, start_t start, start_t target) {
|
|
||||||
_overwrite_calls_within_manual(file, line, from, to, (void *) start, (void *) target);
|
|
||||||
}
|
}
|
||||||
#define overwrite_calls_within(from, to, start, ...) \
|
|
||||||
_overwrite_calls_within< \
|
|
||||||
__raw_##start##_t \
|
|
||||||
>( \
|
|
||||||
__FILE__, __LINE__, \
|
|
||||||
from, to, \
|
|
||||||
start, \
|
|
||||||
__VA_ARGS__ \
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get Target Address From BL Instruction
|
// Get Target Address From BL Instruction
|
||||||
void *extract_from_bl_instruction(unsigned char *from);
|
void *extract_from_bl_instruction(unsigned char *from);
|
||||||
|
|
||||||
// Patch Instruction
|
// Patch Instruction
|
||||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]);
|
void patch(void *start, unsigned char patch[4]);
|
||||||
#define patch(...) \
|
|
||||||
_patch(__FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
// Patch 4 Bytes Of Data
|
// Patch 4 Bytes Of Data
|
||||||
void _patch_address(const char *file, int line, void *start, void *target);
|
void patch_address(void *start, void *target);
|
||||||
#define patch_address(...) \
|
|
||||||
_patch_address(__FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
// Patch VTable Entry
|
// Patch VTable Entry
|
||||||
// This does not affect sub-classes.
|
// This does not affect subclasses.
|
||||||
template <typename start_t>
|
template <typename T>
|
||||||
void _patch_vtable(const char *file, int line, start_t *start, start_t target) {
|
void patch_vtable(const T &start, typename T::ptr_type target) {
|
||||||
_patch_address(file, line, (void *) start, (void *) target);
|
DEBUG("Patching VTable: %s", start.get_name());
|
||||||
|
patch_address((void *) start.get_vtable_addr(), (void *) target);
|
||||||
}
|
}
|
||||||
#define patch_vtable(start, ...) \
|
|
||||||
_patch_vtable< \
|
|
||||||
__raw_##start##_t \
|
|
||||||
>( \
|
|
||||||
__FILE__, __LINE__, \
|
|
||||||
start##_vtable_addr, \
|
|
||||||
__VA_ARGS__ \
|
|
||||||
)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,7 +84,7 @@ void ensure_directory(const char *path);
|
|||||||
/* Allocate VTable */ \
|
/* Allocate VTable */ \
|
||||||
if (vtable == NULL) { \
|
if (vtable == NULL) { \
|
||||||
/* Init */ \
|
/* Init */ \
|
||||||
vtable = dup_##parent##_vtable(parent##_vtable_base); \
|
vtable = dup_vtable(parent##_vtable_base); \
|
||||||
ALLOC_CHECK(vtable); \
|
ALLOC_CHECK(vtable); \
|
||||||
/* Setup */ \
|
/* Setup */ \
|
||||||
_setup_##name##_vtable(vtable); \
|
_setup_##name##_vtable(vtable); \
|
||||||
|
@ -5,28 +5,28 @@
|
|||||||
|
|
||||||
// Limit To 512 overwrite_calls() Uses
|
// Limit To 512 overwrite_calls() Uses
|
||||||
#define CODE_BLOCK_SIZE 4096
|
#define CODE_BLOCK_SIZE 4096
|
||||||
static unsigned char *code_block = NULL;
|
static unsigned char *code_block = nullptr;
|
||||||
#define CODE_SIZE 8
|
#define CODE_SIZE 8
|
||||||
static int code_block_remaining = CODE_BLOCK_SIZE;
|
static int code_block_remaining = CODE_BLOCK_SIZE;
|
||||||
|
|
||||||
// Create Long Overwrite At Current Position
|
// Create Long Overwrite At Current Position
|
||||||
static void long_overwrite(void *start, void *target) {
|
static void long_overwrite(void *start, void *target) {
|
||||||
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
||||||
_patch(NULL, -1, start, patch_data);
|
patch(start, patch_data);
|
||||||
_patch_address(NULL, -1, (void *) (((unsigned char *) start) + 4), target);
|
patch_address((void *) (((unsigned char *) start) + 4), target);
|
||||||
}
|
}
|
||||||
void *update_code_block(void *target) {
|
void *update_code_block(void *target) {
|
||||||
// BL Instructions can only access a limited portion of memory.
|
// BL Instructions can only access a limited portion of memory.
|
||||||
// So this allocates memory closer to the original instruction,
|
// So this allocates memory closer to the original instruction,
|
||||||
// that when run, will jump into the actual target.
|
// that when run, will jump into the actual target.
|
||||||
if (code_block == NULL) {
|
if (code_block == nullptr) {
|
||||||
code_block = (unsigned char *) mmap((void *) 0x200000, CODE_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
code_block = (unsigned char *) mmap((void *) 0x200000, CODE_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
if (code_block == MAP_FAILED) {
|
if (code_block == MAP_FAILED) {
|
||||||
ERR("Unable To Allocate Code Block: %s", strerror(errno));
|
ERR("Unable To Allocate Code Block: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
|
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
|
||||||
// Store Segment
|
// Store Segment
|
||||||
segment_data data;
|
segment_data data = {};
|
||||||
data.start = code_block;
|
data.start = code_block;
|
||||||
data.end = (void *) (((uintptr_t) code_block) + CODE_BLOCK_SIZE);
|
data.end = (void *) (((uintptr_t) code_block) + CODE_BLOCK_SIZE);
|
||||||
data.is_executable = true;
|
data.is_executable = true;
|
||||||
|
@ -10,20 +10,20 @@
|
|||||||
#include "patch-internal.h"
|
#include "patch-internal.h"
|
||||||
|
|
||||||
// Overwrite Specific B(L) Instruction
|
// Overwrite Specific B(L) Instruction
|
||||||
static void _overwrite_call_internal(const char *file, int line, void *start, void *target, int use_b_instruction) {
|
static void _overwrite_call_internal(void *start, void *target, const bool use_b_instruction) {
|
||||||
// Add New Target To Code Block
|
// Add New Target To Code Block
|
||||||
void *code_block = update_code_block(target);
|
void *code_block = update_code_block(target);
|
||||||
|
|
||||||
// Patch
|
// Patch
|
||||||
uint32_t new_instruction = generate_bl_instruction(start, code_block, use_b_instruction);
|
uint32_t new_instruction = generate_bl_instruction(start, code_block, use_b_instruction);
|
||||||
_patch(file, line, start, (unsigned char *) &new_instruction);
|
patch(start, (unsigned char *) &new_instruction);
|
||||||
|
|
||||||
// Increment Code Block Position
|
// Increment Code Block Position
|
||||||
increment_code_block();
|
increment_code_block();
|
||||||
}
|
}
|
||||||
void _overwrite_call(const char *file, int line, void *start, void *target) {
|
void overwrite_call(void *start, void *target) {
|
||||||
int use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
|
const bool use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
|
||||||
_overwrite_call_internal(file, line, start, target, use_b_instruction);
|
_overwrite_call_internal(start, target, use_b_instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// .rodata Information
|
// .rodata Information
|
||||||
@ -38,11 +38,11 @@ void _overwrite_call(const char *file, int line, void *start, void *target) {
|
|||||||
uint32_t *addr = (uint32_t *) i; \
|
uint32_t *addr = (uint32_t *) i; \
|
||||||
if (*addr == (uintptr_t) target) { \
|
if (*addr == (uintptr_t) target) { \
|
||||||
/* Found VTable Entry */ \
|
/* Found VTable Entry */ \
|
||||||
_patch_address(file, line, addr, replacement); \
|
patch_address(addr, replacement); \
|
||||||
found++; \
|
found++; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
static int _patch_vtables(const char *file, int line, void *target, void *replacement) {
|
static int _patch_vtables(void *target, void *replacement) {
|
||||||
int found = 0;
|
int found = 0;
|
||||||
scan_vtables(RODATA);
|
scan_vtables(RODATA);
|
||||||
scan_vtables(DATA_REL_RO);
|
scan_vtables(DATA_REL_RO);
|
||||||
@ -51,11 +51,11 @@ static int _patch_vtables(const char *file, int line, void *target, void *replac
|
|||||||
#undef scan_vtables
|
#undef scan_vtables
|
||||||
|
|
||||||
// Patch Calls Within Range
|
// Patch Calls Within Range
|
||||||
static int _overwrite_calls_within_internal(const char *file, int line, void *from, void *to, void *target, void *replacement) {
|
static int _overwrite_calls_within_internal(void *from, void *to, void *target, void *replacement) {
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (uintptr_t i = (uintptr_t) from; i < (uintptr_t) to; i = i + 4) {
|
for (uintptr_t i = (uintptr_t) from; i < (uintptr_t) to; i = i + 4) {
|
||||||
unsigned char *addr = (unsigned char *) i;
|
unsigned char *addr = (unsigned char *) i;
|
||||||
int use_b_instruction = addr[3] == B_INSTRUCTION;
|
const int use_b_instruction = addr[3] == B_INSTRUCTION;
|
||||||
// Check If Instruction is B Or BL
|
// Check If Instruction is B Or BL
|
||||||
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
|
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
|
||||||
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
|
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
|
||||||
@ -64,7 +64,7 @@ static int _overwrite_calls_within_internal(const char *file, int line, void *fr
|
|||||||
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
|
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
|
||||||
// Patch Instruction
|
// Patch Instruction
|
||||||
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
|
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
|
||||||
_patch(file, line, addr, (unsigned char *) &new_instruction);
|
patch(addr, (unsigned char *) &new_instruction);
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,57 +76,54 @@ static int _overwrite_calls_within_internal(const char *file, int line, void *fr
|
|||||||
#define TEXT_START 0xde60
|
#define TEXT_START 0xde60
|
||||||
#define TEXT_END 0x1020c0
|
#define TEXT_END 0x1020c0
|
||||||
// Overwrite All B(L) Intrusctions That Target The Specified Address
|
// Overwrite All B(L) Intrusctions That Target The Specified Address
|
||||||
#define NO_CALLSITE_ERROR "(%s:%i) Unable To Find Callsites For %p"
|
#define NO_CALLSITE_ERROR() ERR("Unable To Find Callsites")
|
||||||
void *_overwrite_calls_manual(const char *file, int line, void *start, void *target) {
|
void *overwrite_calls_manual(void *start, void *target, const bool allow_no_callsites) {
|
||||||
// Add New Target To Code Block
|
// Add New Target To Code Block
|
||||||
void *code_block = update_code_block(target);
|
void *code_block = update_code_block(target);
|
||||||
|
|
||||||
// Patch Code
|
// Patch Code
|
||||||
int found = _overwrite_calls_within_internal(file, line, (void *) TEXT_START, (void *) TEXT_END, start, code_block);
|
int found = _overwrite_calls_within_internal((void *) TEXT_START, (void *) TEXT_END, start, code_block);
|
||||||
// Patch VTables
|
// Patch VTables
|
||||||
found += _patch_vtables(file, line, start, code_block);
|
found += _patch_vtables(start, code_block);
|
||||||
|
|
||||||
// Increment Code Block Position
|
// Increment Code Block Position
|
||||||
increment_code_block();
|
increment_code_block();
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
if (found < 1) {
|
if (found < 1 && !allow_no_callsites) {
|
||||||
ERR(NO_CALLSITE_ERROR, file, line, start);
|
NO_CALLSITE_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return code_block;
|
return code_block;
|
||||||
}
|
}
|
||||||
void _overwrite_calls_within_manual(const char *file, int line, void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
|
void overwrite_calls_within_manual(void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
|
||||||
// Add New Target To Code Block
|
// Add New Target To Code Block
|
||||||
void *code_block = update_code_block(replacement);
|
void *code_block = update_code_block(replacement);
|
||||||
|
|
||||||
// Patch
|
// Patch
|
||||||
int found = _overwrite_calls_within_internal(file, line, from, to, target, code_block);
|
const int found = _overwrite_calls_within_internal(from, to, target, code_block);
|
||||||
// Check
|
// Check
|
||||||
if (found < 1) {
|
if (found < 1) {
|
||||||
ERR(NO_CALLSITE_ERROR, file, line, target);
|
NO_CALLSITE_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment Code Block Position
|
// Increment Code Block Position
|
||||||
increment_code_block();
|
increment_code_block();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Patch Debug Data
|
|
||||||
#define PATCH_PRINTF(file, line, start, str) if (file != NULL) DEBUG("(%s:%i): Patching (%p) - " str ": %02x %02x %02x %02x", file, line, start, data[0], data[1], data[2], data[3]);
|
|
||||||
|
|
||||||
// Patch Instruction
|
// Patch Instruction
|
||||||
static void safe_mprotect(void *addr, size_t len, int prot) {
|
static void safe_mprotect(void *addr, size_t len, int prot) {
|
||||||
long page_size = sysconf(_SC_PAGESIZE);
|
const long page_size = sysconf(_SC_PAGESIZE);
|
||||||
long diff = ((uintptr_t) addr) % page_size;
|
const long diff = uintptr_t(addr) % page_size;
|
||||||
void *aligned_addr = (void *) (((uintptr_t) addr) - diff);
|
void *aligned_addr = (void *) (((uintptr_t) addr) - diff);
|
||||||
size_t aligned_len = len + diff;
|
size_t aligned_len = len + diff;
|
||||||
int ret = mprotect(aligned_addr, aligned_len, prot);
|
const int ret = mprotect(aligned_addr, aligned_len, prot);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
ERR("Unable To Set Permissions: %p: %s", addr, strerror(errno));
|
ERR("Unable To Set Permissions: %p: %s", addr, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
|
void patch(void *start, unsigned char patch[4]) {
|
||||||
if (((uint32_t) start) % 4 != 0) {
|
if (((uint32_t) start) % 4 != 0) {
|
||||||
ERR("Invalid Address: %p", start);
|
ERR("Invalid Address: %p", start);
|
||||||
}
|
}
|
||||||
@ -142,14 +139,12 @@ void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allow Writing To Code Memory
|
// Allow Writing To Code Memory
|
||||||
uint32_t size = 4;
|
const uint32_t size = 4;
|
||||||
safe_mprotect(start, size, prot | PROT_WRITE);
|
safe_mprotect(start, size, prot | PROT_WRITE);
|
||||||
|
|
||||||
// Patch
|
// Patch
|
||||||
unsigned char *data = (unsigned char *) start;
|
unsigned char *data = (unsigned char *) start;
|
||||||
PATCH_PRINTF(file, line, start, "original");
|
|
||||||
memcpy(data, patch, 4);
|
memcpy(data, patch, 4);
|
||||||
PATCH_PRINTF(file, line, start, "result");
|
|
||||||
|
|
||||||
// Reset Code Memory Permissions
|
// Reset Code Memory Permissions
|
||||||
safe_mprotect(start, size, prot);
|
safe_mprotect(start, size, prot);
|
||||||
@ -159,8 +154,13 @@ void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Patch Address
|
// Patch Address
|
||||||
void _patch_address(const char *file, int line, void *start, void *target) {
|
void patch_address(void *start, void *target) {
|
||||||
uint32_t addr = (uint32_t) target;
|
uint32_t addr = (uint32_t) target;
|
||||||
unsigned char *patch_data = (unsigned char *) &addr;
|
unsigned char *patch_data = (unsigned char *) &addr;
|
||||||
_patch(file, line, start, patch_data);
|
patch(start, patch_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thunks
|
||||||
|
void *reborn_thunk_enabler(void *target, void *thunk) {
|
||||||
|
return overwrite_calls_manual(target, thunk, true);
|
||||||
|
}
|
@ -10,6 +10,9 @@ int32_t misc_get_real_selected_slot(Player *player);
|
|||||||
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height);
|
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height);
|
||||||
|
|
||||||
extern bool is_in_chat;
|
extern bool is_in_chat;
|
||||||
|
|
||||||
|
typedef RakNet_RakString *(*RakNet_RakString_constructor_t)(RakNet_RakString *self, const char *format, ...);
|
||||||
|
extern RakNet_RakString_constructor_t RakNet_RakString_constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void misc_run_on_update(const std::function<void(Minecraft *)> &func);
|
void misc_run_on_update(const std::function<void(Minecraft *)> &func);
|
||||||
|
@ -136,7 +136,7 @@ static int BucketItem_getUseDuration(__attribute__((unused)) FoodItem *item, Ite
|
|||||||
|
|
||||||
static ItemInstance BucketItem_useTimeDepleted(FoodItem *item, ItemInstance *item_instance, Level *level, Player *player) {
|
static ItemInstance BucketItem_useTimeDepleted(FoodItem *item, ItemInstance *item_instance, Level *level, Player *player) {
|
||||||
if (item_instance->auxiliary == 1) {
|
if (item_instance->auxiliary == 1) {
|
||||||
*item_instance = (*FoodItem_useTimeDepleted_vtable_addr)(item, item_instance, level, player);
|
*item_instance = FoodItem_useTimeDepleted.get()(item, item_instance, level, player);
|
||||||
// Set it to a empty bucket
|
// Set it to a empty bucket
|
||||||
item_instance->auxiliary = 0;
|
item_instance->auxiliary = 0;
|
||||||
item_instance->count = 1;
|
item_instance->count = 1;
|
||||||
@ -154,7 +154,7 @@ static bool BucketItem_isFood(__attribute__((unused)) FoodItem *item) {
|
|||||||
|
|
||||||
static ItemInstance *BucketItem_use(FoodItem *item, ItemInstance *item_instance, __attribute__((unused)) Level *level, Player *player) {
|
static ItemInstance *BucketItem_use(FoodItem *item, ItemInstance *item_instance, __attribute__((unused)) Level *level, Player *player) {
|
||||||
if (item_instance->auxiliary == 1) {
|
if (item_instance->auxiliary == 1) {
|
||||||
return (*FoodItem_use_vtable_addr)(item, item_instance, level, player);
|
return FoodItem_use.get()(item, item_instance, level, player);
|
||||||
}
|
}
|
||||||
return item_instance;
|
return item_instance;
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ static FoodItem *create_bucket(int32_t id, int32_t texture_x, int32_t texture_y,
|
|||||||
// Construct
|
// Construct
|
||||||
FoodItem *item = new FoodItem;
|
FoodItem *item = new FoodItem;
|
||||||
ALLOC_CHECK(item);
|
ALLOC_CHECK(item);
|
||||||
Item_constructor((Item *) item, id); // FoodItem's Constructor Was Inlined
|
Item_constructor.get()((Item *) item, id); // FoodItem's Constructor Was Inlined
|
||||||
|
|
||||||
// Set VTable
|
// Set VTable
|
||||||
item->vtable = get_bucket_vtable();
|
item->vtable = get_bucket_vtable();
|
||||||
|
@ -102,7 +102,7 @@ static int Cake_use(__attribute__((unused)) Tile *tile, Level *level, int x, int
|
|||||||
// Eat
|
// Eat
|
||||||
player->foodData.eat(3);
|
player->foodData.eat(3);
|
||||||
// Set the new tile
|
// Set the new tile
|
||||||
int data = level->getData(x, y, z);
|
const int data = level->getData(x, y, z);
|
||||||
if (data >= 5) {
|
if (data >= 5) {
|
||||||
// Remove the cake, it has been completely gobbled up
|
// Remove the cake, it has been completely gobbled up
|
||||||
level->setTileAndData(x, y, z, 0, 0);
|
level->setTileAndData(x, y, z, 0, 0);
|
||||||
@ -123,7 +123,7 @@ static void make_cake() {
|
|||||||
cake->texture = texture;
|
cake->texture = texture;
|
||||||
|
|
||||||
// Set VTable
|
// Set VTable
|
||||||
cake->vtable = dup_Tile_vtable(Tile_vtable_base);
|
cake->vtable = dup_vtable(Tile_vtable_base);
|
||||||
ALLOC_CHECK(cake->vtable);
|
ALLOC_CHECK(cake->vtable);
|
||||||
|
|
||||||
// Set shape
|
// Set shape
|
||||||
|
@ -93,7 +93,7 @@ static void Player_actuallyHurt_injection(Self *player, int32_t damage) {
|
|||||||
int32_t old_health = player->health;
|
int32_t old_health = player->health;
|
||||||
|
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
(*Mob_actuallyHurt_vtable_addr)((Mob *) player, damage);
|
Mob_actuallyHurt.get()((Mob *) player, damage);
|
||||||
if (is_hurt) {
|
if (is_hurt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ void init_death() {
|
|||||||
// Death Messages
|
// Death Messages
|
||||||
if (feature_has("Implement Death Messages", server_auto)) {
|
if (feature_has("Implement Death Messages", server_auto)) {
|
||||||
patch_vtable(ServerPlayer_die, [](ServerPlayer *player, Entity *cause) {
|
patch_vtable(ServerPlayer_die, [](ServerPlayer *player, Entity *cause) {
|
||||||
Player_die_injection<ServerPlayer, Player>(*Player_die_vtable_addr, player, cause);
|
Player_die_injection<ServerPlayer, Player>(Player_die.get(), player, cause);
|
||||||
});
|
});
|
||||||
overwrite_calls(LocalPlayer_die, Player_die_injection<LocalPlayer, LocalPlayer>);
|
overwrite_calls(LocalPlayer_die, Player_die_injection<LocalPlayer, LocalPlayer>);
|
||||||
patch_vtable(LocalPlayer_actuallyHurt, Player_actuallyHurt_injection);
|
patch_vtable(LocalPlayer_actuallyHurt, Player_actuallyHurt_injection);
|
||||||
|
@ -21,7 +21,7 @@ static void set_is_survival(bool new_is_survival) {
|
|||||||
patch((void *) 0x16ee4, size_patch);
|
patch((void *) 0x16ee4, size_patch);
|
||||||
|
|
||||||
// Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor
|
// Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor
|
||||||
overwrite_call((void *) 0x16ef4, new_is_survival ? (void *) SurvivalMode_constructor : (void *) CreatorMode_constructor);
|
overwrite_call((void *) 0x16ef4, new_is_survival ? (void *) SurvivalMode_constructor.get() : (void *) CreatorMode_constructor.get());
|
||||||
|
|
||||||
is_survival = new_is_survival;
|
is_survival = new_is_survival;
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ void init_game_mode() {
|
|||||||
overwrite_calls(Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection);
|
overwrite_calls(Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection);
|
||||||
|
|
||||||
// Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning)
|
// Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning)
|
||||||
overwrite_call((void *) 0x16f84, (void *) ServerLevel_constructor);
|
overwrite_call((void *) 0x16f84, (void *) ServerLevel_constructor.get());
|
||||||
|
|
||||||
// Allocate Correct Size For ServerLevel
|
// Allocate Correct Size For ServerLevel
|
||||||
uint32_t level_size = sizeof(ServerLevel);
|
uint32_t level_size = sizeof(ServerLevel);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <mods/init/init.h>
|
#include <mods/init/init.h>
|
||||||
#include <media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
__attribute__((constructor)) static void init() {
|
__attribute__((constructor)) static void init() {
|
||||||
|
thunk_enabler = reborn_thunk_enabler;
|
||||||
media_ensure_loaded();
|
media_ensure_loaded();
|
||||||
reborn_init_patch();
|
reborn_init_patch();
|
||||||
run_tests();
|
run_tests();
|
||||||
|
@ -15,7 +15,7 @@ void input_set_is_ctrl(const bool val) {
|
|||||||
|
|
||||||
// Handle Drop Item Presses
|
// Handle Drop Item Presses
|
||||||
static void _handle_drop(Minecraft *minecraft) {
|
static void _handle_drop(Minecraft *minecraft) {
|
||||||
if (!creative_is_restricted() || !Minecraft_isCreativeMode(minecraft)) {
|
if (!creative_is_restricted() || !minecraft->isCreativeMode()) {
|
||||||
// Get Player
|
// Get Player
|
||||||
LocalPlayer *player = minecraft->player;
|
LocalPlayer *player = minecraft->player;
|
||||||
if (player != nullptr) {
|
if (player != nullptr) {
|
||||||
|
@ -90,7 +90,7 @@ static void Gui_renderHearts_injection(Gui_renderHearts_t original, Gui *gui) {
|
|||||||
original(gui);
|
original(gui);
|
||||||
}
|
}
|
||||||
static GuiComponent_blit_t get_blit_with_classic_hud_offset() {
|
static GuiComponent_blit_t get_blit_with_classic_hud_offset() {
|
||||||
return use_classic_hud ? Gui_renderHearts_GuiComponent_blit_hearts_injection : GuiComponent_blit;
|
return use_classic_hud ? Gui_renderHearts_GuiComponent_blit_hearts_injection : GuiComponent_blit.get();
|
||||||
}
|
}
|
||||||
#define PINK_HEART_FULL 70
|
#define PINK_HEART_FULL 70
|
||||||
#define PINK_HEART_HALF 79
|
#define PINK_HEART_HALF 79
|
||||||
@ -130,7 +130,7 @@ static void Gui_renderChatMessages_injection(Gui_renderChatMessages_t original,
|
|||||||
// Handle Classic HUD
|
// Handle Classic HUD
|
||||||
if (use_classic_hud) {
|
if (use_classic_hud) {
|
||||||
Minecraft *minecraft = gui->minecraft;
|
Minecraft *minecraft = gui->minecraft;
|
||||||
if (!Minecraft_isCreativeMode(minecraft)) {
|
if (!minecraft->isCreativeMode()) {
|
||||||
y_offset -= (HUD_ELEMENT_HEIGHT * 2) + NEW_HUD_PADDING;
|
y_offset -= (HUD_ELEMENT_HEIGHT * 2) + NEW_HUD_PADDING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,6 +231,7 @@ static void LoginPacket_read_injection(LoginPacket_read_t original, LoginPacket
|
|||||||
// RakNet::RakString's format constructor is often given unsanitized user input and is never used for formatting,
|
// RakNet::RakString's format constructor is often given unsanitized user input and is never used for formatting,
|
||||||
// this is a massive security risk, allowing clients to run arbitrary format specifiers, this disables the
|
// this is a massive security risk, allowing clients to run arbitrary format specifiers, this disables the
|
||||||
// formatting functionality.
|
// formatting functionality.
|
||||||
|
RakNet_RakString_constructor_t RakNet_RakString_constructor = (RakNet_RakString_constructor_t) 0xea5cc;
|
||||||
static RakNet_RakString *RakNet_RakString_injection(RakNet_RakString *rak_string, const char *format, ...) {
|
static RakNet_RakString *RakNet_RakString_injection(RakNet_RakString *rak_string, const char *format, ...) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
return RakNet_RakString_constructor(rak_string, "%s", format);
|
return RakNet_RakString_constructor(rak_string, "%s", format);
|
||||||
@ -363,7 +364,7 @@ static void anGenBuffers_injection(__attribute__((unused)) Common_anGenBuffers_t
|
|||||||
|
|
||||||
// Fix Graphics Bug When Switching To First-Person While Sneaking
|
// Fix Graphics Bug When Switching To First-Person While Sneaking
|
||||||
static void PlayerRenderer_render_injection(PlayerRenderer *model_renderer, Entity *entity, float param_2, float param_3, float param_4, float param_5, float param_6) {
|
static void PlayerRenderer_render_injection(PlayerRenderer *model_renderer, Entity *entity, float param_2, float param_3, float param_4, float param_5, float param_6) {
|
||||||
(*HumanoidMobRenderer_render_vtable_addr)((HumanoidMobRenderer *) model_renderer, entity, param_2, param_3, param_4, param_5, param_6);
|
HumanoidMobRenderer_vtable_base->render((HumanoidMobRenderer *) model_renderer, entity, param_2, param_3, param_4, param_5, param_6);
|
||||||
HumanoidModel *model = model_renderer->model;
|
HumanoidModel *model = model_renderer->model;
|
||||||
model->is_sneaking = false;
|
model->is_sneaking = false;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ static Screen *last_screen = nullptr;
|
|||||||
static std::string current_splash;
|
static std::string current_splash;
|
||||||
static void StartMenuScreen_render_Screen_render_injection(Screen *screen, int x, int y, float param_1) {
|
static void StartMenuScreen_render_Screen_render_injection(Screen *screen, int x, int y, float param_1) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
(*Screen_render_vtable_addr)(screen, x, y, param_1);
|
Screen_render.get()(screen, x, y, param_1);
|
||||||
|
|
||||||
// Load Splashes
|
// Load Splashes
|
||||||
static std::vector<std::string> splashes;
|
static std::vector<std::string> splashes;
|
||||||
|
@ -73,10 +73,10 @@ void init_touch() {
|
|||||||
// Force Touch Inventory
|
// Force Touch Inventory
|
||||||
if (feature_has("Force Touch GUI Inventory", server_disabled)) {
|
if (feature_has("Force Touch GUI Inventory", server_disabled)) {
|
||||||
overwrite_call((void *) 0x2943c, (void *) operator_new_IngameBlockSelectionScreen_injection);
|
overwrite_call((void *) 0x2943c, (void *) operator_new_IngameBlockSelectionScreen_injection);
|
||||||
overwrite_call((void *) 0x29444, (void *) Touch_IngameBlockSelectionScreen_constructor);
|
overwrite_call((void *) 0x29444, (void *) Touch_IngameBlockSelectionScreen_constructor.get());
|
||||||
// Make "Craft" And "Armor" Buttons Use Classic GUI Style (Button And TButton Have The Same Size)
|
// Make "Craft" And "Armor" Buttons Use Classic GUI Style (Button And TButton Have The Same Size)
|
||||||
overwrite_call((void *) 0x3b060, (void *) Button_constructor);
|
overwrite_call((void *) 0x3b060, (void *) Button_constructor.get());
|
||||||
overwrite_call((void *) 0x3b08c, (void *) Button_constructor);
|
overwrite_call((void *) 0x3b08c, (void *) Button_constructor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force Touch Button Behavior
|
// Force Touch Button Behavior
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
constructor (const char *format, ...) = 0xea5cc;
|
//constructor (const char *format, ...) = 0xea5cc;
|
||||||
|
|
||||||
method void Assign(const char *str) = 0xe9e34;
|
method void Assign(const char *str) = 0xe9e34;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user