Fix Door Item Issues

This commit is contained in:
TheBrokenRail 2024-08-22 23:43:32 -04:00
parent 72372c7457
commit 18b25486e7
8 changed files with 48 additions and 16 deletions

View File

@ -75,4 +75,5 @@ TRUE Fix Pigmen Burning In The Sun
TRUE Fix Carried Grass's Bottom Texture TRUE Fix Carried Grass's Bottom Texture
TRUE Hide Crosshair In Third-Person TRUE Hide Crosshair In Third-Person
TRUE Fix Camera Legs TRUE Fix Camera Legs
TRUE Implement Crafting Remainders TRUE Implement Crafting Remainders
TRUE Fix Door Duplication

View File

@ -1,6 +1,23 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include "patch-internal.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 // Extract Target Address From B(L) Instruction
static void *extract_from_bl_instruction(unsigned char *from, const uint32_t instruction) { static void *extract_from_bl_instruction(unsigned char *from, const uint32_t instruction) {
// Extract The Signed 24-Bit Immediate Value // Extract The Signed 24-Bit Immediate Value
@ -19,7 +36,7 @@ void *extract_from_bl_instruction(unsigned char *from) {
} }
// Generate A BL Instruction // 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 from_addr = uint32_t(from);
const uint32_t to_addr = uint32_t(to); 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 const int32_t offset = int32_t((to_addr - from_addr - 8) >> 2); // Account For The 2-Bit Shift
// Create the instruction // Create the instruction
uint32_t instruction = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION; uint32_t instruction = opcode;
instruction *= 0x1000000; instruction *= 0x1000000;
// Set The Offset (Last 24 Bits) // Set The Offset (Last 24 Bits)
instruction |= (offset & 0x00FFFFFF); instruction |= (offset & 0x00ffffff);
// Check // Check
if (to != extract_from_bl_instruction((unsigned char *) from, instruction)) { if (to != extract_from_bl_instruction((unsigned char *) from, instruction)) {

View File

@ -23,4 +23,5 @@ __attribute__((visibility("internal"))) void increment_code_block();
// BL Instruction Magic Number // BL Instruction Magic Number
#define BL_INSTRUCTION 0xeb #define BL_INSTRUCTION 0xeb
#define B_INSTRUCTION 0xea #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);

View File

@ -15,7 +15,7 @@ static void _overwrite_call_internal(void *start, void *target, const bool use_b
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 ? B_INSTRUCTION : BL_INSTRUCTION);
patch(start, (unsigned char *) &new_instruction); patch(start, (unsigned char *) &new_instruction);
// Increment Code Block Position // Increment Code Block Position
@ -55,15 +55,15 @@ static int _overwrite_calls_within_internal(void *from, void *to, void *target,
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;
const int use_b_instruction = addr[3] == B_INSTRUCTION; const unsigned char opcode = addr[3];
// Check If Instruction is B Or BL // Check If Instruction is B Or BL
if (addr[3] == BL_INSTRUCTION || use_b_instruction) { if (is_branch_instruction(opcode)) {
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction); // Extract Instruction Target
unsigned char *check_instruction_array = (unsigned char *) &check_instruction; const void *instruction_target = extract_from_bl_instruction(addr);
// Check If Instruction Calls Target // 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 // 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); patch(addr, (unsigned char *) &new_instruction);
found++; found++;
} }
@ -113,11 +113,11 @@ void overwrite_calls_within_manual(void *from /* inclusive */, void *to /* exclu
} }
// Patch Instruction // 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 page_size = sysconf(_SC_PAGESIZE);
const 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; const size_t aligned_len = len + diff;
const 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));

View File

@ -380,7 +380,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
#endif #endif
// Debug // Debug
glGetString_t glGetString = (glGetString_t) glfwGetProcAddress("glGetString"); const glGetString_t glGetString = (glGetString_t) glfwGetProcAddress("glGetString");
DEBUG("Using %s", (*glGetString)(GL_VERSION)); DEBUG("Using %s", (*glGetString)(GL_VERSION));
// Init OpenAL // Init OpenAL

View File

@ -47,7 +47,7 @@ static int debug_background_padding = 1;
static int line_height = 8; static int line_height = 8;
static void render_debug_line(Gui *gui, std::string &line, const int x, const int y) { static void render_debug_line(Gui *gui, std::string &line, const int x, const int y) {
// Draw Background // Draw Background
int width = gui->minecraft->font->width(line); const int width = gui->minecraft->font->width(line);
if (width == 0) { if (width == 0) {
return; return;
} }

View File

@ -776,6 +776,11 @@ static int CarriedTile_getTexture2_injection(CarriedTile_getTexture2_t original,
return original(self, face, metadata); 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 // Init
template <typename... Args> template <typename... Args>
static void nop(__attribute__((unused)) Args... args) { static void nop(__attribute__((unused)) Args... args) {
@ -1043,6 +1048,13 @@ void init_misc() {
overwrite_calls(CarriedTile_getTexture2, CarriedTile_getTexture2_injection); 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 Logging
_init_misc_logging(); _init_misc_logging();
_init_misc_api(); _init_misc_api();

View File

@ -54,6 +54,7 @@ virtual-method Tile *setSoundType(const Tile_SoundType &sound_type) = 0xe8;
virtual-method Tile *setLightEmission(float light) = 0xf0; virtual-method Tile *setLightEmission(float light) = 0xf0;
virtual-method Tile *setExplodeable(float explodeable) = 0xf4; virtual-method Tile *setExplodeable(float explodeable) = 0xf4;
virtual-method Tile *setDestroyTime(float destroy_time) = 0xf8; 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 texture = 0x4;
property int id = 0x8; property int id = 0x8;