Add Survival Mode
This commit is contained in:
parent
10fd60e6db
commit
e1ddc78d31
@ -10,16 +10,18 @@ RUN apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf b
|
||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so
|
||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1 /usr/lib/libEGL.so
|
||||
|
||||
ADD . /app
|
||||
ADD ./build /app/build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN ./build/download-minecraft-pi.sh
|
||||
|
||||
RUN ./build/build-mods.sh
|
||||
|
||||
RUN ./build/build-libpng12.sh
|
||||
|
||||
ADD . /app
|
||||
|
||||
RUN ./build/build-mods.sh
|
||||
|
||||
WORKDIR ./minecraft-pi
|
||||
|
||||
ENTRYPOINT ./launcher
|
||||
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -13,7 +13,7 @@ pipeline {
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh './scripts/build.sh'
|
||||
sh 'DOCKER_BUILD_OPTIONS="--no-cache" ./scripts/build.sh'
|
||||
}
|
||||
}
|
||||
stage('Publish') {
|
||||
|
@ -27,7 +27,8 @@ extern "C" {
|
||||
\
|
||||
__attribute__((__used__)) return_type name args
|
||||
|
||||
void overwrite(void *start, void *target);
|
||||
void *overwrite(void *start, void *target);
|
||||
void revert_overwrite(void *start, void *original);
|
||||
void patch(void *start, unsigned char patch[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -6,9 +6,11 @@
|
||||
|
||||
#include <libcore/libcore.h>
|
||||
|
||||
#define PREPARE_PATCH(start) \
|
||||
#define PATCH_PRINTF(print, start, str) if (print) fprintf(stderr, "Patching (0x%04x) - "str": 0x%02x 0x%02x 0x%02x 0x%02x\n", (uint32_t) start, data[0], data[1], data[2], data[3]);
|
||||
|
||||
#define PREPARE_PATCH(print, count) \
|
||||
size_t page_size = sysconf(_SC_PAGESIZE); \
|
||||
uintptr_t end = ((uintptr_t) start) + 1; \
|
||||
uintptr_t end = ((uintptr_t) start) + (4 * count); \
|
||||
uintptr_t page_start = ((uintptr_t) start) & -page_size; \
|
||||
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_WRITE); \
|
||||
\
|
||||
@ -17,15 +19,22 @@
|
||||
if (thumb) { \
|
||||
data--; \
|
||||
} \
|
||||
fprintf(stderr, "Patching - original: %i %i %i %i %i\n", data[0], data[1], data[2], data[3], data[4]);
|
||||
PATCH_PRINTF(print, start, "original");
|
||||
|
||||
#define END_PATCH() \
|
||||
fprintf(stderr, "Patching - result: %i %i %i %i %i\n", data[0], data[1], data[2], data[3], data[4]); \
|
||||
#define END_PATCH(print) \
|
||||
PATCH_PRINTF(print, start, "result"); \
|
||||
\
|
||||
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_EXEC);
|
||||
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_EXEC); \
|
||||
__clear_cache(start, (void *) end);
|
||||
|
||||
#define ORIGINAL_SIZE 4 + sizeof (int)
|
||||
|
||||
void *overwrite(void *start, void *target) {
|
||||
PREPARE_PATCH(1, 2);
|
||||
|
||||
void *original = malloc(ORIGINAL_SIZE);
|
||||
memcpy(original, start, ORIGINAL_SIZE);
|
||||
|
||||
void overwrite(void *start, void *target) {
|
||||
PREPARE_PATCH(start);
|
||||
if (thumb) {
|
||||
unsigned char patch[4] = {0xdf, 0xf8, 0x00, 0xf0};
|
||||
memcpy(data, patch, 4);
|
||||
@ -34,11 +43,26 @@ void overwrite(void *start, void *target) {
|
||||
memcpy(data, patch, 4);
|
||||
}
|
||||
memcpy(&data[4], &target, sizeof (int));
|
||||
END_PATCH();
|
||||
|
||||
END_PATCH(1);
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
void revert_overwrite(void *start, void *original) {
|
||||
PREPARE_PATCH(0, 2);
|
||||
|
||||
void *temp = malloc(ORIGINAL_SIZE);
|
||||
memcpy(temp, data, ORIGINAL_SIZE);
|
||||
memcpy(data, original, ORIGINAL_SIZE);
|
||||
memcpy(original, temp, ORIGINAL_SIZE);
|
||||
free(temp);
|
||||
|
||||
END_PATCH(0);
|
||||
}
|
||||
|
||||
void patch(void *start, unsigned char patch[]) {
|
||||
PREPARE_PATCH(start);
|
||||
PREPARE_PATCH(1, 1);
|
||||
memcpy(data, patch, 4);
|
||||
END_PATCH();
|
||||
END_PATCH(1);
|
||||
}
|
||||
|
2
debian/DEBIAN/control
vendored
2
debian/DEBIAN/control
vendored
@ -4,4 +4,4 @@ Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: amd64
|
||||
Depends: docker.io, docker-compose, virgl-server
|
||||
Depends: docker.io, docker-compose, virgl-server, zenity
|
||||
|
2
debian/usr/bin/minecraft-pi
vendored
2
debian/usr/bin/minecraft-pi
vendored
@ -2,6 +2,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
export FEATURES="$(zenity --class minecraft-pi --list --checklist --column 'Enabled' --column 'Feature' FALSE 'Touch GUI' FALSE 'Survival Mode' FALSE 'Fix Bow & Arrow' FALSE 'Fix Attacking' FALSE 'Mob Spawning')"
|
||||
|
||||
virgl_test_server &
|
||||
PID="$!"
|
||||
|
||||
|
@ -9,3 +9,4 @@ services:
|
||||
- '~/.minecraft-pi:/root/.minecraft'
|
||||
environment:
|
||||
- 'DISPLAY=unix${DISPLAY}'
|
||||
- 'FEATURES=${FEATURES}'
|
||||
|
@ -12,8 +12,8 @@ target_link_libraries(compat core SDL EGL GLESv1_CM GLESv2 X11 dl)
|
||||
# Force GLESv1 Link
|
||||
target_link_options(compat PRIVATE "-Wl,--no-as-needed")
|
||||
|
||||
add_library(touch SHARED src/touch.c)
|
||||
target_link_libraries(touch core dl)
|
||||
add_library(extra SHARED src/extra.c)
|
||||
target_link_libraries(extra core dl)
|
||||
|
||||
add_library(readdir SHARED src/readdir.c)
|
||||
target_link_libraries(readdir core)
|
||||
|
@ -144,7 +144,6 @@ HOOK(eglSwapBuffers, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __
|
||||
}
|
||||
|
||||
static void resize(int width, int height, int fullscreen) {
|
||||
fprintf(stderr, "W: %i H: %i FS: %i\n", width, height, fullscreen);
|
||||
Uint32 flags = fullscreen ? FULLSCREEN_VIDEO_FLAGS : WINDOW_VIDEO_FLAGS;
|
||||
|
||||
ensure_SDL_SetVideoMode();
|
||||
|
104
mods/src/extra.c
Normal file
104
mods/src/extra.c
Normal file
@ -0,0 +1,104 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libcore/libcore.h>
|
||||
|
||||
static int32_t get_game_type(__attribute__((unused)) int32_t level_data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t can_spawn_mobs(__attribute__((unused)) int32_t obj) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include <SDL/SDL_mouse.h>
|
||||
|
||||
typedef void (*releaseUsingItem_t)(unsigned char *t, unsigned char *player);
|
||||
static releaseUsingItem_t survival_releaseUsingItem = (releaseUsingItem_t) 0x1a598;
|
||||
static releaseUsingItem_t creative_releaseUsingItem = (releaseUsingItem_t) 0x1b1a0;
|
||||
|
||||
typedef void (*handle_input_t)(unsigned char *, unsigned char *, unsigned char *, unsigned char *);
|
||||
static handle_input_t handle_input = (handle_input_t) 0x15ffc;
|
||||
static void *handle_input_original = NULL;
|
||||
|
||||
static int is_survival = 0;
|
||||
|
||||
static void handle_input_injection(unsigned char *param_1, unsigned char *param_2, unsigned char *param_3, unsigned char *param_4) {
|
||||
// Call Original Method
|
||||
revert_overwrite((void *) handle_input, handle_input_original);
|
||||
(*handle_input)(param_1, param_2, param_3, param_4);
|
||||
revert_overwrite((void *) handle_input, handle_input_original);
|
||||
|
||||
// GameMode Is Offset From param_1 By 0x160
|
||||
// Player Is Offset From param_1 By 0x18c
|
||||
int using_item = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT);
|
||||
if (!using_item) {
|
||||
unsigned char *game_mode = *(unsigned char **) (param_1 + 0x160);
|
||||
unsigned char *player = *(unsigned char **) (param_1 + 0x18c);
|
||||
if (player != NULL && game_mode != NULL) {
|
||||
(*(is_survival ? survival_releaseUsingItem : creative_releaseUsingItem))(game_mode, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int has_feature(const char *name) {
|
||||
char *env = getenv("FEATURES");
|
||||
char *features = strdup(env != NULL ? env : "");
|
||||
char *tok = strtok(features, "|");
|
||||
int ret = 0;
|
||||
while (tok != NULL) {
|
||||
if (strcmp(tok, name) == 0) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
tok = strtok(NULL, "|");
|
||||
}
|
||||
free(features);
|
||||
fprintf(stderr, "Feature: %s: %s\n", name, ret ? "Enabled" : "Disabled");
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void init() {
|
||||
if (has_feature("Touch GUI")) {
|
||||
// Use Touch UI
|
||||
unsigned char patch_data[4] = {0x01, 0x00, 0x50, 0xe3};
|
||||
patch((void *) 0x292fc, patch_data);
|
||||
}
|
||||
|
||||
is_survival = has_feature("Survival Mode");
|
||||
if (is_survival) {
|
||||
// Survival Mode Inventpry UI
|
||||
unsigned char patch_data_2[4] = {0x00, 0x30, 0xa0, 0xe3};
|
||||
patch((void *) 0x16efc, patch_data_2);
|
||||
|
||||
// Replace Creative Mode VTable With Survival Mode VTable
|
||||
patch((void *) 0x1a0d8, (unsigned char *) 0x1b804);
|
||||
|
||||
// Use Correct Size For Survival Mode Object
|
||||
unsigned char patch_data_3[4] = {0x24, 0x00, 0xa0, 0xe3};
|
||||
patch((void *) 0x1a054, patch_data_3);
|
||||
|
||||
// Force GameType To 0 (Required For Day-Night Cycle)
|
||||
overwrite((void *) 0xbabdc, get_game_type);
|
||||
}
|
||||
|
||||
if (has_feature("Fix Bow & Arrow")) {
|
||||
// Fix Bow
|
||||
handle_input_original = overwrite((void *) handle_input, handle_input_injection);
|
||||
}
|
||||
|
||||
if (has_feature("Fix Attacking")) {
|
||||
// Allow Attacking Mobs
|
||||
unsigned char patch_data_5[4] = {0x00, 0xf0, 0x20, 0xe3};
|
||||
patch((void *) 0x162d4, patch_data_5);
|
||||
}
|
||||
|
||||
if (has_feature("Mob Spawning")) {
|
||||
// Enable Mob Spawning
|
||||
overwrite((void *) 0xbabec, can_spawn_mobs);
|
||||
|
||||
// Replace CreatorLevel With Level
|
||||
unsigned char patch_data_4[4] = {0x96, 0x3d, 0x02, 0xeb};
|
||||
patch((void *) 0x16f84, patch_data_4);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#include <libcore/libcore.h>
|
||||
|
||||
__attribute__((constructor)) static void init() {
|
||||
unsigned char patch_data[4] = {0x01, 0x00, 0x50, 0xe3};
|
||||
patch((void *) 0x292fc, patch_data);
|
||||
}
|
@ -2,4 +2,4 @@
|
||||
|
||||
set -e
|
||||
|
||||
docker build --no-cache --tag thebrokenrail/minecraft-pi:latest .
|
||||
docker build ${DOCKER_BUILD_OPTIONS} --tag thebrokenrail/minecraft-pi:latest .
|
||||
|
Loading…
Reference in New Issue
Block a user