Fix Door Item Issues
This commit is contained in:
parent
72372c7457
commit
18b25486e7
@ -76,3 +76,4 @@ TRUE Fix Carried Grass's Bottom Texture
|
||||
TRUE Hide Crosshair In Third-Person
|
||||
TRUE Fix Camera Legs
|
||||
TRUE Implement Crafting Remainders
|
||||
TRUE Fix Door Duplication
|
@ -1,6 +1,23 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include "patch-internal.h"
|
||||
|
||||
// Check Instruction
|
||||
bool is_branch_instruction(unsigned char opcode) {
|
||||
// Remove Condition
|
||||
opcode &= 0xf;
|
||||
// Check
|
||||
if (opcode == 0b1010) {
|
||||
// B
|
||||
return true;
|
||||
} else if (opcode == 0b1011) {
|
||||
// BL
|
||||
return true;
|
||||
} else {
|
||||
// Not A Branch
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract Target Address From B(L) Instruction
|
||||
static void *extract_from_bl_instruction(unsigned char *from, const uint32_t instruction) {
|
||||
// Extract The Signed 24-Bit Immediate Value
|
||||
@ -19,7 +36,7 @@ void *extract_from_bl_instruction(unsigned char *from) {
|
||||
}
|
||||
|
||||
// Generate A BL Instruction
|
||||
uint32_t generate_bl_instruction(void *from, void *to, const int use_b_instruction) {
|
||||
uint32_t generate_bl_instruction(void *from, void *to, const unsigned char opcode) {
|
||||
const uint32_t from_addr = uint32_t(from);
|
||||
const uint32_t to_addr = uint32_t(to);
|
||||
|
||||
@ -27,11 +44,11 @@ uint32_t generate_bl_instruction(void *from, void *to, const int use_b_instructi
|
||||
const int32_t offset = int32_t((to_addr - from_addr - 8) >> 2); // Account For The 2-Bit Shift
|
||||
|
||||
// Create the instruction
|
||||
uint32_t instruction = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION;
|
||||
uint32_t instruction = opcode;
|
||||
instruction *= 0x1000000;
|
||||
|
||||
// Set The Offset (Last 24 Bits)
|
||||
instruction |= (offset & 0x00FFFFFF);
|
||||
instruction |= (offset & 0x00ffffff);
|
||||
|
||||
// Check
|
||||
if (to != extract_from_bl_instruction((unsigned char *) from, instruction)) {
|
||||
|
@ -23,4 +23,5 @@ __attribute__((visibility("internal"))) void increment_code_block();
|
||||
// BL Instruction Magic Number
|
||||
#define BL_INSTRUCTION 0xeb
|
||||
#define B_INSTRUCTION 0xea
|
||||
__attribute__((visibility("internal"))) uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruction);
|
||||
__attribute__((visibility("internal"))) bool is_branch_instruction(unsigned char opcode);
|
||||
__attribute__((visibility("internal"))) uint32_t generate_bl_instruction(void *from, void *to, unsigned char opcode = BL_INSTRUCTION);
|
||||
|
@ -15,7 +15,7 @@ static void _overwrite_call_internal(void *start, void *target, const bool use_b
|
||||
void *code_block = update_code_block(target);
|
||||
|
||||
// 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 ? B_INSTRUCTION : BL_INSTRUCTION);
|
||||
patch(start, (unsigned char *) &new_instruction);
|
||||
|
||||
// Increment Code Block Position
|
||||
@ -55,15 +55,15 @@ static int _overwrite_calls_within_internal(void *from, void *to, void *target,
|
||||
int found = 0;
|
||||
for (uintptr_t i = (uintptr_t) from; i < (uintptr_t) to; i = i + 4) {
|
||||
unsigned char *addr = (unsigned char *) i;
|
||||
const int use_b_instruction = addr[3] == B_INSTRUCTION;
|
||||
const unsigned char opcode = addr[3];
|
||||
// Check If Instruction is B Or BL
|
||||
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
|
||||
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
|
||||
unsigned char *check_instruction_array = (unsigned char *) &check_instruction;
|
||||
if (is_branch_instruction(opcode)) {
|
||||
// Extract Instruction Target
|
||||
const void *instruction_target = extract_from_bl_instruction(addr);
|
||||
// Check If Instruction Calls Target
|
||||
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
|
||||
if (instruction_target == target) {
|
||||
// Patch Instruction
|
||||
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
|
||||
uint32_t new_instruction = generate_bl_instruction(addr, replacement, opcode);
|
||||
patch(addr, (unsigned char *) &new_instruction);
|
||||
found++;
|
||||
}
|
||||
@ -113,11 +113,11 @@ void overwrite_calls_within_manual(void *from /* inclusive */, void *to /* exclu
|
||||
}
|
||||
|
||||
// Patch Instruction
|
||||
static void safe_mprotect(void *addr, size_t len, int prot) {
|
||||
static void safe_mprotect(void *addr, const size_t len, const int prot) {
|
||||
const long page_size = sysconf(_SC_PAGESIZE);
|
||||
const long diff = uintptr_t(addr) % page_size;
|
||||
void *aligned_addr = (void *) (((uintptr_t) addr) - diff);
|
||||
size_t aligned_len = len + diff;
|
||||
const size_t aligned_len = len + diff;
|
||||
const int ret = mprotect(aligned_addr, aligned_len, prot);
|
||||
if (ret == -1) {
|
||||
ERR("Unable To Set Permissions: %p: %s", addr, strerror(errno));
|
||||
|
@ -380,7 +380,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
||||
#endif
|
||||
|
||||
// Debug
|
||||
glGetString_t glGetString = (glGetString_t) glfwGetProcAddress("glGetString");
|
||||
const glGetString_t glGetString = (glGetString_t) glfwGetProcAddress("glGetString");
|
||||
DEBUG("Using %s", (*glGetString)(GL_VERSION));
|
||||
|
||||
// Init OpenAL
|
||||
|
@ -47,7 +47,7 @@ static int debug_background_padding = 1;
|
||||
static int line_height = 8;
|
||||
static void render_debug_line(Gui *gui, std::string &line, const int x, const int y) {
|
||||
// Draw Background
|
||||
int width = gui->minecraft->font->width(line);
|
||||
const int width = gui->minecraft->font->width(line);
|
||||
if (width == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -776,6 +776,11 @@ static int CarriedTile_getTexture2_injection(CarriedTile_getTexture2_t original,
|
||||
return original(self, face, metadata);
|
||||
}
|
||||
|
||||
// Fix Door Item Dropping
|
||||
static void DoorTile_neighborChanged_Tile_spawnResources_injection(DoorTile *self, Level *level, int x, int y, int z, int data2, __attribute__((unused)) float chance) {
|
||||
self->spawnResources(level, x, y, z, data2, 1);
|
||||
}
|
||||
|
||||
// Init
|
||||
template <typename... Args>
|
||||
static void nop(__attribute__((unused)) Args... args) {
|
||||
@ -1043,6 +1048,13 @@ void init_misc() {
|
||||
overwrite_calls(CarriedTile_getTexture2, CarriedTile_getTexture2_injection);
|
||||
}
|
||||
|
||||
// Fix Door Duplication
|
||||
if (feature_has("Fix Door Duplication", server_enabled)) {
|
||||
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||
patch((void *) 0xbe230, nop_patch);
|
||||
overwrite_call((void *) 0xbe110, (void *) DoorTile_neighborChanged_Tile_spawnResources_injection);
|
||||
}
|
||||
|
||||
// Init Logging
|
||||
_init_misc_logging();
|
||||
_init_misc_api();
|
||||
|
@ -54,6 +54,7 @@ virtual-method Tile *setSoundType(const Tile_SoundType &sound_type) = 0xe8;
|
||||
virtual-method Tile *setLightEmission(float light) = 0xf0;
|
||||
virtual-method Tile *setExplodeable(float explodeable) = 0xf4;
|
||||
virtual-method Tile *setDestroyTime(float destroy_time) = 0xf8;
|
||||
virtual-method void spawnResources(Level *level, int x, int y, int z, int data, float chance) = 0x80;
|
||||
|
||||
property int texture = 0x4;
|
||||
property int id = 0x8;
|
||||
|
Loading…
Reference in New Issue
Block a user