From f0439e96830447a5594535e16172b3afb664d0a3 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Mon, 21 Jun 2021 21:50:26 -0400 Subject: [PATCH] Make "kill" Admin Command Print Death Message --- VERSION | 2 +- docs/CHANGELOG.md | 3 ++ libreborn/include/libreborn/minecraft.h | 1 + mods/CMakeLists.txt | 9 ++-- mods/src/death/death.cpp | 66 +++++++++++++++++++++++++ mods/src/init/init.c | 1 + mods/src/init/init.h | 1 + mods/src/misc/misc.c | 1 + mods/src/misc/misc.cpp | 58 +--------------------- mods/src/server/server.cpp | 4 +- 10 files changed, 84 insertions(+), 62 deletions(-) create mode 100644 mods/src/death/death.cpp diff --git a/VERSION b/VERSION index e9307ca57..50ffc5aa7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.2 +2.0.3 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ef49956b9..04981045e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +**2.0.3** +* Make "kill" Admin Command Print Death Message + **2.0.2** * Fix Mouse Cursor Bugs diff --git a/libreborn/include/libreborn/minecraft.h b/libreborn/include/libreborn/minecraft.h index 57e1811fa..39c79e341 100644 --- a/libreborn/include/libreborn/minecraft.h +++ b/libreborn/include/libreborn/minecraft.h @@ -197,6 +197,7 @@ static uint32_t Entity_die_vtable_offset = 0x130; typedef void (*Mob_actuallyHurt_t)(unsigned char *entity, int32_t damage); static Mob_actuallyHurt_t Mob_actuallyHurt = (Mob_actuallyHurt_t) 0x7f11c; +static uint32_t Mob_actuallyHurt_vtable_offset = 0x16c; static uint32_t Mob_health_property_offset = 0xec; // int32_t diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 47acfcbc9..66bec6e00 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -29,8 +29,11 @@ target_link_libraries(game_mode reborn) add_library(input SHARED src/input/input.c src/input/input.cpp) target_link_libraries(input reborn feature media-layer-core chat) +add_library(death SHARED src/death/death.cpp) +target_link_libraries(death reborn) + add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp) -target_link_libraries(misc reborn feature util) +target_link_libraries(misc reborn feature) add_library(options SHARED src/options/options.c) target_link_libraries(options reborn feature) @@ -54,13 +57,13 @@ add_library(test SHARED src/test/test.c) target_link_libraries(test reborn home) add_library(init SHARED src/init/init.c) -target_link_libraries(init compat game_mode camera input misc options touch textures chat home test) +target_link_libraries(init compat game_mode camera input misc death options touch textures chat home test) if(MCPI_SERVER_MODE) target_link_libraries(init server) endif() ## Install Mods -install(TARGETS init compat readdir feature override game_mode camera input misc options touch textures chat home test DESTINATION "${MCPI_INSTALL_DIR}/mods") +install(TARGETS init compat readdir feature override game_mode camera input misc death options touch textures chat home test DESTINATION "${MCPI_INSTALL_DIR}/mods") if(MCPI_SERVER_MODE) install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods") endif() diff --git a/mods/src/death/death.cpp b/mods/src/death/death.cpp new file mode 100644 index 000000000..b467b4d9c --- /dev/null +++ b/mods/src/death/death.cpp @@ -0,0 +1,66 @@ +#include + +#include +#include + +#include "../init/init.h" + +// Death Messages +static std::string get_death_message(unsigned char *player) { + // Get Username + char *username = *(char **) (player + Player_username_property_offset); + + // Prepare Death Message + std::string message; + message.append(username); + message.append(" has died"); + + // Return + return message; +} + +// Common Death Message Logic +static void Player_actuallyHurt_injection_helper(unsigned char *player, int32_t damage, bool is_local_player) { + // Store Old Health + int32_t old_health = *(int32_t *) (player + Mob_health_property_offset); + + // Call Original Method + (*(is_local_player ? LocalPlayer_actuallyHurt : Mob_actuallyHurt))(player, damage); + + // Store New Health + int32_t new_health = *(int32_t *) (player + Mob_health_property_offset); + + // Get Variables + unsigned char *minecraft = *(unsigned char **) (player + (is_local_player ? LocalPlayer_minecraft_property_offset : ServerPlayer_minecraft_property_offset)); + unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); + unsigned char *rak_net_instance_vtable = *(unsigned char **) rak_net_instance; + // Only Run On Server-Side + RakNetInstance_isServer_t RakNetInstance_isServer = *(RakNetInstance_isServer_t *) (rak_net_instance_vtable + RakNetInstance_isServer_vtable_offset); + if ((*RakNetInstance_isServer)(rak_net_instance)) { + // Check Health + if (new_health < 1 && old_health >= 1) { + // Get Death Message + std::string message = get_death_message(player); + + // Post Death Message + unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset); + (*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, message); + } + } +} + +// ServerPlayer Death Message Logic +static void ServerPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) { + Player_actuallyHurt_injection_helper(player, damage, false); +} +// LocalPlayer Death Message Logic +static void LocalPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) { + Player_actuallyHurt_injection_helper(player, damage, true); +} + +// Init +void init_death() { + // Death Messages + patch_address(ServerPlayer_actuallyHurt_vtable_addr, (void *) ServerPlayer_actuallyHurt_injection); + patch_address(LocalPlayer_actuallyHurt_vtable_addr, (void *) LocalPlayer_actuallyHurt_injection); +} diff --git a/mods/src/init/init.c b/mods/src/init/init.c index 9e07d9f50..5a71d8821 100644 --- a/mods/src/init/init.c +++ b/mods/src/init/init.c @@ -9,6 +9,7 @@ __attribute__((constructor)) static void init() { init_game_mode(); init_input(); init_misc(); + init_death(); init_camera(); init_options(); init_touch(); diff --git a/mods/src/init/init.h b/mods/src/init/init.h index 0dc1bee6c..ac501a1be 100644 --- a/mods/src/init/init.h +++ b/mods/src/init/init.h @@ -12,6 +12,7 @@ void init_server(); void init_game_mode(); void init_input(); void init_misc(); +void init_death(); void init_camera(); void init_options(); void init_touch(); diff --git a/mods/src/misc/misc.c b/mods/src/misc/misc.c index a382802af..c08721ca2 100644 --- a/mods/src/misc/misc.c +++ b/mods/src/misc/misc.c @@ -64,6 +64,7 @@ static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit free(new_username); } +// Init void init_misc() { if (feature_has("Remove Invalid Item Background")) { // Remove Invalid Item Background (A Red Background That Appears For Items That Are Not Included In The gui_blocks Atlas) diff --git a/mods/src/misc/misc.cpp b/mods/src/misc/misc.cpp index 55fd21228..eaeb311dc 100644 --- a/mods/src/misc/misc.cpp +++ b/mods/src/misc/misc.cpp @@ -98,57 +98,7 @@ static void Gui_addMessage_injection(unsigned char *gui, std::string const& text free(new_message); } -// Death Messages -static std::string get_death_message(unsigned char *player) { - // Get Username - char *username = *(char **) (player + Player_username_property_offset); - - // Prepare Death Message - std::string message; - message.append(username); - message.append(" has died"); - - // Return - return message; -} -// Common Death Message Logic -static void Player_actuallyHurt_injection_helper(unsigned char *player, int32_t damage, bool is_local_player) { - // Store Old Health - int32_t old_health = *(int32_t *) (player + Mob_health_property_offset); - - // Call Original Method - (*(is_local_player ? LocalPlayer_actuallyHurt : Mob_actuallyHurt))(player, damage); - - // Store New Health - int32_t new_health = *(int32_t *) (player + Mob_health_property_offset); - - // Get Variables - unsigned char *minecraft = *(unsigned char **) (player + (is_local_player ? LocalPlayer_minecraft_property_offset : ServerPlayer_minecraft_property_offset)); - unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); - unsigned char *rak_net_instance_vtable = *(unsigned char **) rak_net_instance; - // Only Run On Server-Side - RakNetInstance_isServer_t RakNetInstance_isServer = *(RakNetInstance_isServer_t *) (rak_net_instance_vtable + RakNetInstance_isServer_vtable_offset); - if ((*RakNetInstance_isServer)(rak_net_instance)) { - // Check Health - if (new_health < 1 && old_health >= 1) { - // Get Death Message - std::string message = get_death_message(player); - - // Post Death Message - unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset); - (*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, message); - } - } -} -// ServerPlayer Death Message Logic -static void ServerPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) { - Player_actuallyHurt_injection_helper(player, damage, false); -} -// LocalPlayer Death Message Logic -static void LocalPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) { - Player_actuallyHurt_injection_helper(player, damage, true); -} - +// Init void _init_misc_cpp() { // Implement AppPlatform::readAssetFile So Translations Work overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); @@ -160,8 +110,4 @@ void _init_misc_cpp() { // Print Chat To Log overwrite_calls((void *) Gui_addMessage, (void *) Gui_addMessage_injection); - - // Death Messages - patch_address(ServerPlayer_actuallyHurt_vtable_addr, (void *) ServerPlayer_actuallyHurt_injection); - patch_address(LocalPlayer_actuallyHurt_vtable_addr, (void *) LocalPlayer_actuallyHurt_injection); -} \ No newline at end of file +} diff --git a/mods/src/server/server.cpp b/mods/src/server/server.cpp index 8546d3178..41e839a72 100644 --- a/mods/src/server/server.cpp +++ b/mods/src/server/server.cpp @@ -229,8 +229,8 @@ static void ban_callback(unsigned char *minecraft, std::string username, unsigne // Kill Player static void kill_callback(__attribute__((unused)) unsigned char *minecraft, __attribute__((unused)) std::string username, unsigned char *player) { unsigned char *player_vtable = *(unsigned char **) player; - Entity_die_t Entity_die = *(Entity_die_t *) (player_vtable + Entity_die_vtable_offset); - (*Entity_die)(player, NULL); + Mob_actuallyHurt_t Mob_actuallyHurt = *(Mob_actuallyHurt_t *) (player_vtable + Mob_actuallyHurt_vtable_offset); + (*Mob_actuallyHurt)(player, INT32_MAX); INFO("Killed: %s", username.c_str()); }