From 3244b87be04e3c03f08b03cbe4e0198a96061456 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Mon, 23 Nov 2020 18:03:28 -0500 Subject: [PATCH] Select Game-Mode On World Creation --- debian/client/common/usr/bin/minecraft-pi | 1 - mods/src/extra.c | 10 ----- mods/src/extra.cpp | 52 +++++++++++++++++++++++ mods/src/minecraft.h | 26 ++++++++++++ 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/debian/client/common/usr/bin/minecraft-pi b/debian/client/common/usr/bin/minecraft-pi index 0008a66..8a4c8fc 100755 --- a/debian/client/common/usr/bin/minecraft-pi +++ b/debian/client/common/usr/bin/minecraft-pi @@ -5,7 +5,6 @@ set -e # Ensure Features Are Selected MCPI_FEATURES="$(zenity --class 'Minecraft - Pi edition' --list --checklist --column 'Enabled' --column 'Feature' \ TRUE 'Touch GUI' \ - FALSE 'Survival Mode' \ TRUE 'Fix Bow & Arrow' \ TRUE 'Fix Attacking' \ TRUE 'Mob Spawning' \ diff --git a/mods/src/extra.c b/mods/src/extra.c index 119b7a5..f9e8745 100644 --- a/mods/src/extra.c +++ b/mods/src/extra.c @@ -247,16 +247,6 @@ __attribute__((constructor)) static void init() { set_is_survival(1); overwrite_calls((void *) Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection); - // Get Default Game Mode - if (!is_server) { - int default_game_mode = !extra_has_feature("Survival Mode"); - - // Set Default Game Mode - unsigned char default_game_mode_patch[4] = {default_game_mode ? 0x01 : 0x00, 0x30, 0xa0, 0xe3}; - patch((void *) 0x3d9b8, default_game_mode_patch); - patch((void *) 0x38a78, default_game_mode_patch); - } - // Disable Item Dropping Using The Cursor When Cursor Is Hidden overwrite_calls((void *) Gui_tickItemDrop, Gui_tickItemDrop_injection); // Disable Opening Inventory Using The Cursor When Cursor Is Hidden diff --git a/mods/src/extra.cpp b/mods/src/extra.cpp index b486990..b27683b 100644 --- a/mods/src/extra.cpp +++ b/mods/src/extra.cpp @@ -115,6 +115,51 @@ extern "C" { } } + // Get Minecraft From Screen + static unsigned char *get_minecraft_from_screen(unsigned char *screen) { + return *(unsigned char **) (screen + 0x14); + } + + // Redirect Create World Button To SimpleLevelChooseScreen + #define WORLD_NAME "world" + #define SIMPLE_LEVEL_CHOOSE_SCREEN_SIZE 0x68 + static void SelectWorldScreen_tick_injection(unsigned char *screen) { + bool create_world = *(bool *) (screen + 0xfc); + if (create_world) { + // Get New World Name + std::string new_name; + (*SelectWorldScreen_getUniqueLevelName)(new_name, screen, WORLD_NAME); + // Create SimpleLevelChooseScreen + unsigned char *new_screen = (unsigned char *) ::operator new(SIMPLE_LEVEL_CHOOSE_SCREEN_SIZE); + (*SimpleChooseLevelScreen)(new_screen, new_name); + // Set Screen + unsigned char *minecraft = get_minecraft_from_screen(screen); + (*Minecraft_setScreen)(minecraft, new_screen); + // Finish + *(bool *) (screen + 0xf9) = true; + } else { + (*SelectWorldScreen_tick)(screen); + } + } + static void Touch_SelectWorldScreen_tick_injection(unsigned char *screen) { + bool create_world = *(bool *) (screen + 0x154); + if (create_world) { + // Get New World Name + std::string new_name; + (*Touch_SelectWorldScreen_getUniqueLevelName)(new_name, screen, WORLD_NAME); + // Create SimpleLevelChooseScreen + unsigned char *new_screen = (unsigned char *) ::operator new(SIMPLE_LEVEL_CHOOSE_SCREEN_SIZE); + (*SimpleChooseLevelScreen)(new_screen, new_name); + // Set Screen + unsigned char *minecraft = get_minecraft_from_screen(screen); + (*Minecraft_setScreen)(minecraft, new_screen); + // Finish + *(bool *) (screen + 0x151) = true; + } else { + (*Touch_SelectWorldScreen_tick)(screen); + } + } + __attribute((constructor)) static void init() { // Implement AppPlatform::readAssetFile So Translations Work overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); @@ -134,5 +179,12 @@ extern "C" { // Tick Dynamic Textures (Animated Water) overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection); } + + // Hijack Create World Button + patch_address(SelectWorldScreen_tick_vtable_addr, (void *) SelectWorldScreen_tick_injection); + patch_address(Touch_SelectWorldScreen_tick_vtable_addr, (void *) Touch_SelectWorldScreen_tick_injection); + // Make The SimpleChooseLevelScreen Back Button Go To SelectWorldScreen Instead Of StartMenuScreen + unsigned char simple_choose_level_screen_back_button_patch[4] = {0x05, 0x10, 0xa0, 0xe3}; + patch((void *) 0x31144, simple_choose_level_screen_back_button_patch); } } diff --git a/mods/src/minecraft.h b/mods/src/minecraft.h index 67029ba..4998403 100644 --- a/mods/src/minecraft.h +++ b/mods/src/minecraft.h @@ -154,6 +154,18 @@ static Screen_updateEvents_t Screen_updateEvents = (Screen_updateEvents_t) 0x28e typedef void (*Screen_keyboardNewChar_t)(unsigned char *screen, char key); typedef void (*Screen_keyPressed_t)(unsigned char *screen, int32_t key); +typedef void (*Screen_tick_t)(unsigned char *screen); + +// SelectWorldScreen + +static Screen_tick_t SelectWorldScreen_tick = (Screen_tick_t) 0x38a2c; +static void *SelectWorldScreen_tick_vtable_addr = (void *) 0x104f78; + +// Touch::SelectWorldScreen + +static Screen_tick_t Touch_SelectWorldScreen_tick = (Screen_tick_t) 0x3d96c; +static void *Touch_SelectWorldScreen_tick_vtable_addr = (void *) 0x105780; + // ItemInstance typedef unsigned char *(*ItemInstance_t)(unsigned char *item_instance, unsigned char *item); @@ -284,6 +296,20 @@ static RakNet_SystemAddress_ToString_t RakNet_SystemAddress_ToString = (RakNet_S typedef void (*ServerSideNetworkHandler_displayGameMessage_t)(unsigned char *server_side_network_handler, std::string const& message); static ServerSideNetworkHandler_displayGameMessage_t ServerSideNetworkHandler_displayGameMessage = (ServerSideNetworkHandler_displayGameMessage_t) 0x750c4; +// SimpleChooseLevelScreen + +typedef unsigned char *(*SimpleChooseLevelScreen_t)(unsigned char *simple_choose_level_screen, std::string const& world_name); +static SimpleChooseLevelScreen_t SimpleChooseLevelScreen = (SimpleChooseLevelScreen_t) 0x31404; + +// SelectWorldScreen + +typedef std::string &(*SelectWorldScreen_getUniqueLevelName_t)(std::string &new_name, unsigned char *screen, std::string const& name); +static SelectWorldScreen_getUniqueLevelName_t SelectWorldScreen_getUniqueLevelName = (SelectWorldScreen_getUniqueLevelName_t) 0x388ec; + +// Touch::SelectWorldScreen + +static SelectWorldScreen_getUniqueLevelName_t Touch_SelectWorldScreen_getUniqueLevelName = (SelectWorldScreen_getUniqueLevelName_t) 0x3d82c; + #endif #pragma GCC diagnostic pop