Make "kill" Admin Command Print Death Message
minecraft-pi-reborn/pipeline/head This commit looks good Details

This commit is contained in:
TheBrokenRail 2021-06-21 21:50:26 -04:00
parent 6d79beeeb6
commit f0439e9683
10 changed files with 84 additions and 62 deletions

View File

@ -1 +1 @@
2.0.2
2.0.3

View File

@ -1,5 +1,8 @@
# Changelog
**2.0.3**
* Make "kill" Admin Command Print Death Message
**2.0.2**
* Fix Mouse Cursor Bugs

View File

@ -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

View File

@ -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()

66
mods/src/death/death.cpp Normal file
View File

@ -0,0 +1,66 @@
#include <string>
#include <libreborn/libreborn.h>
#include <libreborn/minecraft.h>
#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);
}

View File

@ -9,6 +9,7 @@ __attribute__((constructor)) static void init() {
init_game_mode();
init_input();
init_misc();
init_death();
init_camera();
init_options();
init_touch();

View File

@ -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();

View File

@ -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)

View File

@ -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);
}

View File

@ -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());
}