2022-06-25 21:30:08 +00:00
|
|
|
#include "game-mode-internal.h"
|
|
|
|
#include <mods/init/init.h>
|
|
|
|
#include <mods/feature/feature.h>
|
2020-12-02 23:18:49 +00:00
|
|
|
|
2021-07-04 23:02:45 +00:00
|
|
|
#include <libreborn/libreborn.h>
|
2021-09-12 03:18:12 +00:00
|
|
|
#include <symbols/minecraft.h>
|
2020-12-02 23:18:49 +00:00
|
|
|
|
|
|
|
static int is_survival = -1;
|
|
|
|
|
|
|
|
// Patch Game Mode
|
2024-04-02 23:22:01 +00:00
|
|
|
static void set_is_survival(bool new_is_survival) {
|
2020-12-02 23:18:49 +00:00
|
|
|
if (is_survival != new_is_survival) {
|
2022-07-09 02:40:56 +00:00
|
|
|
DEBUG("Setting Game Mode: %s", new_is_survival ? "Survival" : "Creative");
|
2020-12-02 23:18:49 +00:00
|
|
|
|
|
|
|
// Correct Inventpry UI
|
2024-04-02 23:22:01 +00:00
|
|
|
unsigned char inventory_patch[4] = {(unsigned char) (new_is_survival ? 0x00 : 0x01), 0x30, 0xa0, 0xe3}; // "mov r3, #0x0" or "mov r3, #0x1"
|
2020-12-02 23:18:49 +00:00
|
|
|
patch((void *) 0x16efc, inventory_patch);
|
|
|
|
|
|
|
|
// Use Correct Size For GameMode Object
|
2024-04-02 23:22:01 +00:00
|
|
|
unsigned char size_patch[4] = {(unsigned char) (new_is_survival ? SURVIVAL_MODE_SIZE : CREATOR_MODE_SIZE), 0x00, 0xa0, 0xe3}; // "mov r0, #SURVIVAL_MODE_SIZE" or "mov r0, #CREATOR_MODE_SIZE"
|
2020-12-02 23:18:49 +00:00
|
|
|
patch((void *) 0x16ee4, size_patch);
|
|
|
|
|
2020-12-08 21:32:12 +00:00
|
|
|
// Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor
|
2024-01-06 11:30:23 +00:00
|
|
|
overwrite_call((void *) 0x16ef4, new_is_survival ? (void *) SurvivalMode_constructor : (void *) CreatorMode_constructor);
|
2020-12-02 23:18:49 +00:00
|
|
|
|
|
|
|
is_survival = new_is_survival;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle Gamemode Switching
|
2024-04-03 07:19:12 +00:00
|
|
|
static void Minecraft_setIsCreativeMode_injection(Minecraft_setIsCreativeMode_t original, Minecraft *self, int32_t new_game_mode) {
|
2020-12-02 23:18:49 +00:00
|
|
|
set_is_survival(!new_game_mode);
|
|
|
|
|
|
|
|
// Call Original Method
|
2024-04-03 07:19:12 +00:00
|
|
|
original(self, new_game_mode);
|
2020-12-02 23:18:49 +00:00
|
|
|
}
|
|
|
|
|
2021-09-16 20:39:24 +00:00
|
|
|
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
|
2024-04-03 07:19:12 +00:00
|
|
|
static unsigned char *Minecraft_getCreator_injection(Minecraft_getCreator_t original, Minecraft *minecraft) {
|
2021-09-16 20:39:24 +00:00
|
|
|
if (is_survival) {
|
2024-04-02 23:22:01 +00:00
|
|
|
// SurvivalMode, Return nullptr
|
|
|
|
return nullptr;
|
2021-09-16 20:39:24 +00:00
|
|
|
} else {
|
|
|
|
// CreatorMode, Call Original Method
|
2024-04-03 07:19:12 +00:00
|
|
|
return original(minecraft);
|
2021-09-16 20:39:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-04 23:02:45 +00:00
|
|
|
// Init
|
2020-12-02 23:18:49 +00:00
|
|
|
void init_game_mode() {
|
2021-08-23 22:33:18 +00:00
|
|
|
// Dynamic Game Mode Switching
|
2022-04-10 00:01:16 +00:00
|
|
|
if (feature_has("Implement Game-Mode Switching", server_enabled)) {
|
2024-04-02 23:22:01 +00:00
|
|
|
set_is_survival(true);
|
2024-04-03 07:19:12 +00:00
|
|
|
overwrite_calls(Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection);
|
2020-12-02 23:18:49 +00:00
|
|
|
|
2021-07-04 23:02:45 +00:00
|
|
|
// Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning)
|
2024-01-06 11:30:23 +00:00
|
|
|
overwrite_call((void *) 0x16f84, (void *) ServerLevel_constructor);
|
2020-12-02 23:18:49 +00:00
|
|
|
|
2021-07-04 23:02:45 +00:00
|
|
|
// Allocate Correct Size For ServerLevel
|
|
|
|
uint32_t level_size = SERVER_LEVEL_SIZE;
|
2021-08-24 21:21:38 +00:00
|
|
|
patch_address((void *) 0x17004, (void *) level_size);
|
2020-12-02 23:18:49 +00:00
|
|
|
|
2021-09-16 20:39:24 +00:00
|
|
|
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
|
2024-04-03 07:19:12 +00:00
|
|
|
overwrite_calls(Minecraft_getCreator, Minecraft_getCreator_injection);
|
2022-04-28 03:38:30 +00:00
|
|
|
}
|
2021-09-16 20:39:24 +00:00
|
|
|
|
2022-04-28 03:38:30 +00:00
|
|
|
// Create World Dialog
|
|
|
|
if (feature_has("Implement Create World Dialog", server_disabled)) {
|
|
|
|
// Init UI
|
|
|
|
_init_game_mode_ui();
|
2021-07-04 23:02:45 +00:00
|
|
|
}
|
2021-08-23 22:33:18 +00:00
|
|
|
|
2022-09-23 21:08:26 +00:00
|
|
|
// Allow Joining Survival Mode Servers
|
|
|
|
if (feature_has("Allow Joining Survival Mode Servers", server_enabled)) {
|
2021-08-23 22:33:18 +00:00
|
|
|
unsigned char server_patch[4] = {0x0f, 0x00, 0x00, 0xea}; // "b 0x6dcb4"
|
|
|
|
patch((void *) 0x6dc70, server_patch);
|
|
|
|
}
|
2021-06-28 21:00:29 +00:00
|
|
|
}
|