Add Death Messages
This commit is contained in:
parent
4f4cdf915f
commit
b10616905d
@ -5,6 +5,11 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
// bool In C
|
||||
#ifndef __cplusplus
|
||||
typedef uint32_t bool;
|
||||
#endif
|
||||
|
||||
// Globals
|
||||
|
||||
static char **default_path = (char **) 0xe264; // /.minecraft/
|
||||
@ -98,8 +103,11 @@ static Minecraft_releaseMouse_t Minecraft_releaseMouse = (Minecraft_releaseMouse
|
||||
typedef void (*Minecraft_grabMouse_t)(unsigned char *minecraft);
|
||||
static Minecraft_grabMouse_t Minecraft_grabMouse = (Minecraft_grabMouse_t) 0x15d10;
|
||||
|
||||
typedef void (*Minecraft_leaveGame_t)(unsigned char *minecraft, bool save_remote_level);
|
||||
static Minecraft_leaveGame_t Minecraft_leaveGame = (Minecraft_leaveGame_t) 0x15ea0;
|
||||
|
||||
static uint32_t Minecraft_screen_width_property_offset = 0x20; // int32_t
|
||||
static uint32_t Minecraft_server_side_network_handler_property_offset = 0x174; // ServerSideNetworkHandler *
|
||||
static uint32_t Minecraft_network_handler_property_offset = 0x174; // NetEventCallback *
|
||||
static uint32_t Minecraft_rak_net_instance_property_offset = 0x170; // RakNetInstance *
|
||||
static uint32_t Minecraft_level_property_offset = 0x188; // Level *
|
||||
static uint32_t Minecraft_textures_property_offset = 0x164; // Textures *
|
||||
@ -110,6 +118,7 @@ static uint32_t Minecraft_hit_result_property_offset = 0xc38; // HitResult
|
||||
static uint32_t Minecraft_progress_property_offset = 0xc60; // int32_t
|
||||
static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServer *
|
||||
static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen *
|
||||
static uint32_t Minecraft_gui_property_offset = 0x198; // Gui
|
||||
|
||||
// CommandServer
|
||||
|
||||
@ -147,14 +156,31 @@ static Player_isUsingItem_t Player_isUsingItem = (Player_isUsingItem_t) 0x8f15c;
|
||||
|
||||
static uint32_t Player_username_property_offset = 0xbf4; // char *
|
||||
|
||||
// Entity
|
||||
|
||||
typedef void (*Entity_die_t)(unsigned char *entity, unsigned char *cause);
|
||||
static uint32_t Entity_die_vtable_offset = 0x130;
|
||||
|
||||
// Mob
|
||||
|
||||
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_health_property_offset = 0xec; // int32_t
|
||||
|
||||
// LocalPlayer
|
||||
|
||||
static Mob_actuallyHurt_t LocalPlayer_actuallyHurt = (Mob_actuallyHurt_t) 0x44010;
|
||||
static void *LocalPlayer_actuallyHurt_vtable_addr = (void *) 0x10639c;
|
||||
|
||||
static void *LocalPlayer_openTextEdit_vtable_addr = (void *) 0x106460;
|
||||
|
||||
static uint32_t LocalPlayer_minecraft_property_offset = 0xc90; // Minecraft *
|
||||
|
||||
// ServerPlayer
|
||||
|
||||
static void *ServerPlayer_actuallyHurt_vtable_addr = (void *) 0x109fa4;
|
||||
|
||||
static uint32_t ServerPlayer_minecraft_property_offset = 0xc8c; // Minecraft *
|
||||
static uint32_t ServerPlayer_guid_property_offset = 0xc08; // RakNetGUID
|
||||
|
||||
@ -169,9 +195,17 @@ static Gui_handleClick_t Gui_handleClick = (Gui_handleClick_t) 0x2599c;
|
||||
typedef void (*Gui_renderOnSelectItemNameText_t)(unsigned char *gui, int32_t param_1, unsigned char *font, int32_t param_2);
|
||||
static Gui_renderOnSelectItemNameText_t Gui_renderOnSelectItemNameText = (Gui_renderOnSelectItemNameText_t) 0x26aec;
|
||||
|
||||
typedef void (*Gui_renderChatMessages_t)(unsigned char *gui, int32_t param_1, uint32_t param_2, bool param_3, unsigned char *font);
|
||||
static Gui_renderChatMessages_t Gui_renderChatMessages = (Gui_renderChatMessages_t) 0x273d8;
|
||||
|
||||
static uint32_t Gui_minecraft_property_offset = 0x9f4; // Minecraft *
|
||||
static uint32_t Gui_selected_item_text_timer_property_offset = 0x9fc; // float
|
||||
|
||||
// Textures
|
||||
|
||||
typedef void (*Textures_tick_t)(unsigned char *textures, bool param_1);
|
||||
static Textures_tick_t Textures_tick = (Textures_tick_t) 0x531c4;
|
||||
|
||||
// GameMode Constructors
|
||||
|
||||
#define CREATOR_MODE_SIZE 0x18
|
||||
@ -274,6 +308,14 @@ static uint32_t RakNetInstance_peer_property_offset = 0x4;
|
||||
typedef struct RakNet_SystemAddress (*RakNet_RakPeer_GetSystemAddressFromGuid_t)(unsigned char *rak_peer, struct RakNet_RakNetGUID guid);
|
||||
static uint32_t RakNet_RakPeer_GetSystemAddressFromGuid_vtable_offset = 0xd0;
|
||||
|
||||
typedef bool (*RakNet_RakPeer_IsBanned_t)(unsigned char *rak_peer, const char *ip);
|
||||
static RakNet_RakPeer_IsBanned_t RakNet_RakPeer_IsBanned = (RakNet_RakPeer_IsBanned_t) 0xda3b4;
|
||||
|
||||
// RakNet::SystemAddress
|
||||
|
||||
typedef char *(*RakNet_SystemAddress_ToString_t)(struct RakNet_SystemAddress *system_address, bool print_delimiter, char delimiter);
|
||||
static RakNet_SystemAddress_ToString_t RakNet_SystemAddress_ToString = (RakNet_SystemAddress_ToString_t) 0xd6198;
|
||||
|
||||
// ServerSideNetworkHandler
|
||||
|
||||
typedef void (*ServerSideNetworkHandler_onDisconnect_t)(unsigned char *server_side_network_handler, unsigned char *guid);
|
||||
@ -283,13 +325,10 @@ static void *ServerSideNetworkHandler_onDisconnect_vtable_addr = (void *) 0x109b
|
||||
typedef unsigned char *(*ServerSideNetworkHandler_getPlayer_t)(unsigned char *server_side_network_handler, unsigned char *guid);
|
||||
static ServerSideNetworkHandler_getPlayer_t ServerSideNetworkHandler_getPlayer = (ServerSideNetworkHandler_getPlayer_t) 0x75464;
|
||||
|
||||
typedef void (*ServerSideNetworkHandler_handle_t)(unsigned char *server_side_network_handler, unsigned char *rak_net_guid, unsigned char *packet);
|
||||
|
||||
static void *ServerSideNetworkHandler_handle_ChatPacket_vtable_addr = (void *) 0x109c60;
|
||||
|
||||
// Entity
|
||||
|
||||
typedef void (*Entity_die_t)(unsigned char *entity, unsigned char *cause);
|
||||
static uint32_t Entity_die_vtable_offset = 0x130;
|
||||
|
||||
// Inventory
|
||||
|
||||
typedef void (*Inventory_selectSlot_t)(unsigned char *inventory, int32_t slot);
|
||||
@ -326,6 +365,11 @@ static ItemRenderer_renderGuiItemCorrect_t ItemRenderer_renderGuiItemCorrect = (
|
||||
|
||||
// Structures
|
||||
|
||||
struct AppPlatform_readAssetFile_return_value {
|
||||
char *data;
|
||||
int32_t length;
|
||||
};
|
||||
|
||||
struct ConnectedClient {
|
||||
uint32_t sock;
|
||||
std::string str;
|
||||
@ -337,10 +381,6 @@ struct ConnectedClient {
|
||||
typedef void (*AppPlatform_saveScreenshot_t)(unsigned char *app_platform, std::string const& param1, std::string const& param_2);
|
||||
static void *AppPlatform_linux_saveScreenshot_vtable_addr = (void *) 0x102160;
|
||||
|
||||
struct AppPlatform_readAssetFile_return_value {
|
||||
char *data;
|
||||
int32_t length;
|
||||
};
|
||||
typedef AppPlatform_readAssetFile_return_value (*AppPlatform_readAssetFile_t)(unsigned char *app_platform, std::string const& path);
|
||||
static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_readAssetFile_t) 0x12b10;
|
||||
|
||||
@ -349,9 +389,6 @@ static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_read
|
||||
typedef void (*Minecraft_selectLevel_t)(unsigned char *minecraft, std::string const& level_dir, std::string const& level_name, LevelSettings const& vsettings);
|
||||
static Minecraft_selectLevel_t Minecraft_selectLevel = (Minecraft_selectLevel_t) 0x16f38;
|
||||
|
||||
typedef void (*Minecraft_leaveGame_t)(unsigned char *minecraft, bool save_remote_level);
|
||||
static Minecraft_leaveGame_t Minecraft_leaveGame = (Minecraft_leaveGame_t) 0x15ea0;
|
||||
|
||||
// CommandServer
|
||||
|
||||
typedef std::string (*CommandServer_parse_t)(unsigned char *command_server, struct ConnectedClient &client, std::string const& command);
|
||||
@ -367,24 +404,6 @@ static Level_addParticle_t Level_addParticle = (Level_addParticle_t) 0xa449c;
|
||||
typedef void (*Gui_addMessage_t)(unsigned char *gui, std::string const& text);
|
||||
static Gui_addMessage_t Gui_addMessage = (Gui_addMessage_t) 0x27820;
|
||||
|
||||
typedef void (*Gui_renderChatMessages_t)(unsigned char *gui, int32_t param_1, uint32_t param_2, bool param_3, unsigned char *font);
|
||||
static Gui_renderChatMessages_t Gui_renderChatMessages = (Gui_renderChatMessages_t) 0x273d8;
|
||||
|
||||
// Textures
|
||||
|
||||
typedef void (*Textures_tick_t)(unsigned char *textures, bool param_1);
|
||||
static Textures_tick_t Textures_tick = (Textures_tick_t) 0x531c4;
|
||||
|
||||
// RakNet::RakPeer
|
||||
|
||||
typedef bool (*RakNet_RakPeer_IsBanned_t)(unsigned char *rak_peer, const char *ip);
|
||||
static RakNet_RakPeer_IsBanned_t RakNet_RakPeer_IsBanned = (RakNet_RakPeer_IsBanned_t) 0xda3b4;
|
||||
|
||||
// RakNet::SystemAddress
|
||||
|
||||
typedef char *(*RakNet_SystemAddress_ToString_t)(struct RakNet_SystemAddress *system_address, bool print_delimiter, char delimiter);
|
||||
static RakNet_SystemAddress_ToString_t RakNet_SystemAddress_ToString = (RakNet_SystemAddress_ToString_t) 0xd6198;
|
||||
|
||||
// ServerSideNetworkHandler
|
||||
|
||||
typedef void (*ServerSideNetworkHandler_displayGameMessage_t)(unsigned char *server_side_network_handler, std::string const& message);
|
||||
|
@ -49,7 +49,7 @@ static void CommandServer_parse_CommandServer_dispatchPacket_injection(unsigned
|
||||
if ((*RakNetInstance_isServer)(rak_net_instance)) {
|
||||
// Hosting Multiplayer
|
||||
char *message = *(char **) (packet + ChatPacket_message_property_offset);
|
||||
unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_server_side_network_handler_property_offset);
|
||||
unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset);
|
||||
send_message(server_side_network_handler, *default_username, message);
|
||||
} else {
|
||||
// Client
|
||||
|
@ -78,6 +78,7 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
|
||||
char *output = run_command("echo \"${CHAT_WINDOW_TCL}\" | wish -name \"Minecraft - Pi edition\"", &return_code);
|
||||
// Handle Message
|
||||
if (output != NULL) {
|
||||
// Check Return Code
|
||||
if (return_code == 0) {
|
||||
// Remove Ending Newline
|
||||
int length = strlen(output);
|
||||
@ -85,10 +86,13 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
|
||||
output[length - 1] = '\0';
|
||||
}
|
||||
length = strlen(output);
|
||||
// Don't Allow Empty Strings
|
||||
if (length > 0) {
|
||||
// Submit
|
||||
chat_queue_message(output);
|
||||
}
|
||||
// Free
|
||||
}
|
||||
// Free Output
|
||||
free(output);
|
||||
}
|
||||
// Update Counter
|
||||
|
@ -8,6 +8,38 @@
|
||||
|
||||
#define NEW_PATH "/.minecraft-pi/"
|
||||
|
||||
// Render Selected Item Text
|
||||
static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t param_1, uint32_t param_2, uint32_t param_3, unsigned char *font) {
|
||||
// Call Original Method
|
||||
(*Gui_renderChatMessages)(gui, param_1, param_2, param_3, font);
|
||||
// Calculate Selected Item Text Scale
|
||||
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset);
|
||||
int32_t screen_width = *(int32_t *) (minecraft + Minecraft_screen_width_property_offset);
|
||||
float scale = ((float) screen_width) * *InvGuiScale;
|
||||
// Render Selected Item Text
|
||||
(*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, param_1 - 0x13);
|
||||
}
|
||||
// Reset Selected Item Text Timer On Slot Select
|
||||
static uint32_t reset_selected_item_text_timer = 0;
|
||||
static void Gui_tick_injection(unsigned char *gui) {
|
||||
// Call Original Method
|
||||
(*Gui_tick)(gui);
|
||||
// Handle Reset
|
||||
float *selected_item_text_timer = (float *) (gui + Gui_selected_item_text_timer_property_offset);
|
||||
if (reset_selected_item_text_timer) {
|
||||
// Reset
|
||||
*selected_item_text_timer = 0;
|
||||
reset_selected_item_text_timer = 0;
|
||||
}
|
||||
}
|
||||
// Trigger Reset Selected Item Text Timer On Slot Select
|
||||
static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slot) {
|
||||
// Call Original Method
|
||||
(*Inventory_selectSlot)(inventory, slot);
|
||||
// Trigger Reset Selected Item Text Timer
|
||||
reset_selected_item_text_timer = 1;
|
||||
}
|
||||
|
||||
void init_misc() {
|
||||
// Store Data In ~/.minecraft-pi Instead Of ~/.minecraft
|
||||
patch_address((void *) default_path, (void *) NEW_PATH);
|
||||
@ -18,6 +50,11 @@ void init_misc() {
|
||||
patch((void *) 0x63c98, invalid_item_background_patch);
|
||||
}
|
||||
|
||||
// Fix Selected Item Text
|
||||
overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection);
|
||||
overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection);
|
||||
overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection);
|
||||
|
||||
// Init C++
|
||||
init_misc_cpp();
|
||||
}
|
@ -25,6 +25,7 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Add Item To Inventory
|
||||
static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) {
|
||||
unsigned char *item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE);
|
||||
ALLOC_CHECK(item_instance);
|
||||
@ -67,38 +68,6 @@ static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(un
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Render Selected Item Text
|
||||
static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t param_1, uint32_t param_2, bool param_3, unsigned char *font) {
|
||||
// Call Original Method
|
||||
(*Gui_renderChatMessages)(gui, param_1, param_2, param_3, font);
|
||||
// Calculate Selected Item Text Scale
|
||||
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset);
|
||||
int32_t screen_width = *(int32_t *) (minecraft + Minecraft_screen_width_property_offset);
|
||||
float scale = ((float) screen_width) * *InvGuiScale;
|
||||
// Render Selected Item Text
|
||||
(*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, param_1 - 0x13);
|
||||
}
|
||||
// Reset Selected Item Text Timer On Slot Select
|
||||
static bool reset_selected_item_text_timer = false;
|
||||
static void Gui_tick_injection(unsigned char *gui) {
|
||||
// Call Original Method
|
||||
(*Gui_tick)(gui);
|
||||
// Handle Reset
|
||||
float *selected_item_text_timer = (float *) (gui + Gui_selected_item_text_timer_property_offset);
|
||||
if (reset_selected_item_text_timer) {
|
||||
// Reset
|
||||
*selected_item_text_timer = 0;
|
||||
reset_selected_item_text_timer = false;
|
||||
}
|
||||
}
|
||||
// Trigger Reset Selected Item Text Timer On Slot Select
|
||||
static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slot) {
|
||||
// Call Original Method
|
||||
(*Inventory_selectSlot)(inventory, slot);
|
||||
// Trigger Reset Selected Item Text Timer
|
||||
reset_selected_item_text_timer = true;
|
||||
}
|
||||
|
||||
// Print Chat To Log
|
||||
static bool Gui_addMessage_recursing = false;
|
||||
static void Gui_addMessage_injection(unsigned char *gui, std::string const& text) {
|
||||
@ -120,6 +89,57 @@ static void Gui_addMessage_injection(unsigned char *gui, std::string const& text
|
||||
}
|
||||
}
|
||||
|
||||
// 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 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 (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);
|
||||
}
|
||||
|
||||
void init_misc_cpp() {
|
||||
// Implement AppPlatform::readAssetFile So Translations Work
|
||||
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
||||
@ -129,11 +149,10 @@ void init_misc_cpp() {
|
||||
overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
||||
}
|
||||
|
||||
// Fix Selected Item Text
|
||||
overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection);
|
||||
overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection);
|
||||
overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection);
|
||||
|
||||
// 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);
|
||||
}
|
@ -267,7 +267,7 @@ static void handle_server_stop(unsigned char *minecraft) {
|
||||
|
||||
// Get ServerSideNetworkHandler From Minecraft
|
||||
static unsigned char *get_server_side_network_handler(unsigned char *minecraft) {
|
||||
return *(unsigned char **) (minecraft + Minecraft_server_side_network_handler_property_offset);
|
||||
return *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset);
|
||||
}
|
||||
|
||||
// Handle Commands
|
||||
|
Loading…
Reference in New Issue
Block a user