diff --git a/launcher/src/client/available-feature-flags b/launcher/src/client/available-feature-flags index 8ec6128b..c0988047 100644 --- a/launcher/src/client/available-feature-flags +++ b/launcher/src/client/available-feature-flags @@ -75,4 +75,5 @@ TRUE Fix Pigmen Burning In The Sun TRUE Fix Carried Grass's Bottom Texture TRUE Hide Crosshair In Third-Person TRUE Fix Camera Legs -TRUE Implement Crafting Remainders \ No newline at end of file +TRUE Implement Crafting Remainders +TRUE Fix Door Duplication \ No newline at end of file diff --git a/libreborn/src/patch/instruction.cpp b/libreborn/src/patch/instruction.cpp index eaea9b59..5e231c6b 100644 --- a/libreborn/src/patch/instruction.cpp +++ b/libreborn/src/patch/instruction.cpp @@ -1,6 +1,23 @@ #include #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)) { diff --git a/libreborn/src/patch/patch-internal.h b/libreborn/src/patch/patch-internal.h index 11f60472..1e3df421 100644 --- a/libreborn/src/patch/patch-internal.h +++ b/libreborn/src/patch/patch-internal.h @@ -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); diff --git a/libreborn/src/patch/patch.cpp b/libreborn/src/patch/patch.cpp index 6682c2d3..0a165a9e 100644 --- a/libreborn/src/patch/patch.cpp +++ b/libreborn/src/patch/patch.cpp @@ -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)); diff --git a/media-layer/core/src/media.cpp b/media-layer/core/src/media.cpp index 466e1df6..3ed8c627 100644 --- a/media-layer/core/src/media.cpp +++ b/media-layer/core/src/media.cpp @@ -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 diff --git a/mods/src/f3/f3.cpp b/mods/src/f3/f3.cpp index 1b8d9b26..0e4db6ed 100644 --- a/mods/src/f3/f3.cpp +++ b/mods/src/f3/f3.cpp @@ -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; } diff --git a/mods/src/misc/misc.cpp b/mods/src/misc/misc.cpp index 3e2c2344..b19977c8 100644 --- a/mods/src/misc/misc.cpp +++ b/mods/src/misc/misc.cpp @@ -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 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(); diff --git a/symbols/src/tile/Tile.def b/symbols/src/tile/Tile.def index d514b82e..023b4dc1 100644 --- a/symbols/src/tile/Tile.def +++ b/symbols/src/tile/Tile.def @@ -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;