Add Death Messages

This commit is contained in:
TheBrokenRail 2021-02-17 11:31:01 -05:00
parent 4f4cdf915f
commit b10616905d
6 changed files with 152 additions and 73 deletions

View File

@ -5,6 +5,11 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-variable"
// bool In C
#ifndef __cplusplus
typedef uint32_t bool;
#endif
// Globals // Globals
static char **default_path = (char **) 0xe264; // /.minecraft/ 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); typedef void (*Minecraft_grabMouse_t)(unsigned char *minecraft);
static Minecraft_grabMouse_t Minecraft_grabMouse = (Minecraft_grabMouse_t) 0x15d10; 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_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_rak_net_instance_property_offset = 0x170; // RakNetInstance *
static uint32_t Minecraft_level_property_offset = 0x188; // Level * static uint32_t Minecraft_level_property_offset = 0x188; // Level *
static uint32_t Minecraft_textures_property_offset = 0x164; // Textures * 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_progress_property_offset = 0xc60; // int32_t
static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServer * static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServer *
static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen * static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen *
static uint32_t Minecraft_gui_property_offset = 0x198; // Gui
// CommandServer // CommandServer
@ -147,14 +156,31 @@ static Player_isUsingItem_t Player_isUsingItem = (Player_isUsingItem_t) 0x8f15c;
static uint32_t Player_username_property_offset = 0xbf4; // char * 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 // 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 void *LocalPlayer_openTextEdit_vtable_addr = (void *) 0x106460;
static uint32_t LocalPlayer_minecraft_property_offset = 0xc90; // Minecraft * static uint32_t LocalPlayer_minecraft_property_offset = 0xc90; // Minecraft *
// ServerPlayer // ServerPlayer
static void *ServerPlayer_actuallyHurt_vtable_addr = (void *) 0x109fa4;
static uint32_t ServerPlayer_minecraft_property_offset = 0xc8c; // Minecraft * static uint32_t ServerPlayer_minecraft_property_offset = 0xc8c; // Minecraft *
static uint32_t ServerPlayer_guid_property_offset = 0xc08; // RakNetGUID 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); 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; 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_minecraft_property_offset = 0x9f4; // Minecraft *
static uint32_t Gui_selected_item_text_timer_property_offset = 0x9fc; // float 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 // GameMode Constructors
#define CREATOR_MODE_SIZE 0x18 #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); 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; 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 // ServerSideNetworkHandler
typedef void (*ServerSideNetworkHandler_onDisconnect_t)(unsigned char *server_side_network_handler, unsigned char *guid); 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); 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; 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; 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 // Inventory
typedef void (*Inventory_selectSlot_t)(unsigned char *inventory, int32_t slot); typedef void (*Inventory_selectSlot_t)(unsigned char *inventory, int32_t slot);
@ -326,6 +365,11 @@ static ItemRenderer_renderGuiItemCorrect_t ItemRenderer_renderGuiItemCorrect = (
// Structures // Structures
struct AppPlatform_readAssetFile_return_value {
char *data;
int32_t length;
};
struct ConnectedClient { struct ConnectedClient {
uint32_t sock; uint32_t sock;
std::string str; 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); 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; 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); 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; 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); 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; 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 // CommandServer
typedef std::string (*CommandServer_parse_t)(unsigned char *command_server, struct ConnectedClient &client, std::string const& command); 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); typedef void (*Gui_addMessage_t)(unsigned char *gui, std::string const& text);
static Gui_addMessage_t Gui_addMessage = (Gui_addMessage_t) 0x27820; 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 // ServerSideNetworkHandler
typedef void (*ServerSideNetworkHandler_displayGameMessage_t)(unsigned char *server_side_network_handler, std::string const& message); typedef void (*ServerSideNetworkHandler_displayGameMessage_t)(unsigned char *server_side_network_handler, std::string const& message);

View File

@ -49,7 +49,7 @@ static void CommandServer_parse_CommandServer_dispatchPacket_injection(unsigned
if ((*RakNetInstance_isServer)(rak_net_instance)) { if ((*RakNetInstance_isServer)(rak_net_instance)) {
// Hosting Multiplayer // Hosting Multiplayer
char *message = *(char **) (packet + ChatPacket_message_property_offset); 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); send_message(server_side_network_handler, *default_username, message);
} else { } else {
// Client // Client

View File

@ -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); char *output = run_command("echo \"${CHAT_WINDOW_TCL}\" | wish -name \"Minecraft - Pi edition\"", &return_code);
// Handle Message // Handle Message
if (output != NULL) { if (output != NULL) {
// Check Return Code
if (return_code == 0) { if (return_code == 0) {
// Remove Ending Newline // Remove Ending Newline
int length = strlen(output); int length = strlen(output);
@ -85,10 +86,13 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
output[length - 1] = '\0'; output[length - 1] = '\0';
} }
length = strlen(output); length = strlen(output);
// Submit // Don't Allow Empty Strings
chat_queue_message(output); if (length > 0) {
// Submit
chat_queue_message(output);
}
} }
// Free // Free Output
free(output); free(output);
} }
// Update Counter // Update Counter

View File

@ -8,6 +8,38 @@
#define NEW_PATH "/.minecraft-pi/" #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() { void init_misc() {
// Store Data In ~/.minecraft-pi Instead Of ~/.minecraft // Store Data In ~/.minecraft-pi Instead Of ~/.minecraft
patch_address((void *) default_path, (void *) NEW_PATH); patch_address((void *) default_path, (void *) NEW_PATH);
@ -18,6 +50,11 @@ void init_misc() {
patch((void *) 0x63c98, invalid_item_background_patch); 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 C++
init_misc_cpp(); init_misc_cpp();
} }

View File

@ -25,6 +25,7 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio
return ret; return ret;
} }
// Add Item To Inventory
static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) { 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); unsigned char *item_instance = (unsigned char *) ::operator new(ITEM_INSTANCE_SIZE);
ALLOC_CHECK(item_instance); ALLOC_CHECK(item_instance);
@ -67,38 +68,6 @@ static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(un
return ret; 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 // Print Chat To Log
static bool Gui_addMessage_recursing = false; static bool Gui_addMessage_recursing = false;
static void Gui_addMessage_injection(unsigned char *gui, std::string const& text) { 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() { void init_misc_cpp() {
// Implement AppPlatform::readAssetFile So Translations Work // Implement AppPlatform::readAssetFile So Translations Work
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); 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); 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 // Print Chat To Log
overwrite_calls((void *) Gui_addMessage, (void *) Gui_addMessage_injection); 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

@ -267,7 +267,7 @@ static void handle_server_stop(unsigned char *minecraft) {
// Get ServerSideNetworkHandler From Minecraft // Get ServerSideNetworkHandler From Minecraft
static unsigned char *get_server_side_network_handler(unsigned char *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 // Handle Commands