minecraft-pi-reborn/mods/src/game-mode/game-mode.c

79 lines
2.9 KiB
C
Raw Normal View History

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
static void set_is_survival(int new_is_survival) {
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
2021-03-05 00:27:24 +00:00
unsigned char inventory_patch[4] = {new_is_survival ? 0x00 : 0x01, 0x30, 0xa0, 0xe3}; // "mov r3, #0x0" or "mov r3, #0x1"
2021-12-01 02:25:04 +00:00
patch((void *) 0x178c0, inventory_patch);
2020-12-02 23:18:49 +00:00
// Use Correct Size For GameMode Object
2021-03-05 00:27:24 +00:00
unsigned char size_patch[4] = {new_is_survival ? SURVIVAL_MODE_SIZE : CREATOR_MODE_SIZE, 0x00, 0xa0, 0xe3}; // "mov r0, #SURVIVAL_MODE_SIZE" or "mov r0, #CREATOR_MODE_SIZE"
2021-12-01 02:25:04 +00:00
patch((void *) 0x178a8, size_patch);
2020-12-02 23:18:49 +00:00
2020-12-08 21:32:12 +00:00
// Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor
2021-12-01 02:25:04 +00:00
overwrite_call((void *) 0x178b8, new_is_survival ? SurvivalMode : CreatorMode);
2020-12-02 23:18:49 +00:00
is_survival = new_is_survival;
}
}
// Handle Gamemode Switching
static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t new_game_mode) {
set_is_survival(!new_game_mode);
// Call Original Method
(*Minecraft_setIsCreativeMode)(this, new_game_mode);
}
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
static unsigned char *Minecraft_getCreator_injection(unsigned char *minecraft) {
if (is_survival) {
// SurvivalMode, Return NULL
return NULL;
} else {
// CreatorMode, Call Original Method
return (*Minecraft_getCreator)(minecraft);
}
}
2021-07-04 23:02:45 +00:00
// Init
2020-12-02 23:18:49 +00:00
void init_game_mode() {
// Dynamic Game Mode Switching
2022-04-10 00:01:16 +00:00
if (feature_has("Implement Game-Mode Switching", server_enabled)) {
2021-07-04 23:02:45 +00:00
set_is_survival(1);
2021-07-05 01:23:12 +00:00
overwrite_calls((void *) Minecraft_setIsCreativeMode, (void *) 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)
2021-12-01 02:25:04 +00:00
overwrite_call((void *) 0x17950, (void *) ServerLevel);
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-12-01 02:25:04 +00:00
patch_address((void *) 0x17a38, (void *) level_size);
2020-12-02 23:18:49 +00:00
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
overwrite_calls((void *) Minecraft_getCreator, (void *) Minecraft_getCreator_injection);
2022-04-28 03:38:30 +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
}
2022-09-23 21:08:26 +00:00
// Allow Joining Survival Mode Servers
if (feature_has("Allow Joining Survival Mode Servers", server_enabled)) {
2021-12-01 02:25:04 +00:00
unsigned char server_patch[4] = {0x16, 0x00, 0x00, 0xea}; // "b 0x8e998"
patch((void *) 0x8e938, server_patch);
}
2021-06-28 21:00:29 +00:00
}