Some Modernization
This commit is contained in:
parent
cecd61ed72
commit
5e229fb6a8
@ -241,7 +241,7 @@ void setup_crash_report() {
|
||||
// Print Exit Code Log Line
|
||||
safe_write(STDERR_FILENO, exit_code_line.c_str(), strlen(exit_code_line.c_str()));
|
||||
// Write Exit Code Log Line
|
||||
safe_write(reborn_get_debug_fd(), exit_code_line.c_str(), strlen(exit_code_line.c_str()));
|
||||
safe_write(reborn_get_log_fd(), exit_code_line.c_str(), strlen(exit_code_line.c_str()));
|
||||
}
|
||||
|
||||
// Close Log File
|
||||
|
@ -4,7 +4,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ENV(name, ...) extern const char *name##_ENV;
|
||||
#define ENV(name, ...) extern const char *const name##_ENV;
|
||||
#include "env-list.h"
|
||||
#undef ENV
|
||||
|
||||
|
@ -1,38 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
// Set obj To NULL On asprintf() Failure
|
||||
#define safe_asprintf(obj, ...) \
|
||||
{ \
|
||||
if (asprintf(obj, __VA_ARGS__) == -1) { \
|
||||
*obj = NULL; \
|
||||
} \
|
||||
ALLOC_CHECK(*obj); \
|
||||
}
|
||||
|
||||
// Dynamic String Append Macro
|
||||
#define string_append(str, format, ...) \
|
||||
{ \
|
||||
char *old = *str; \
|
||||
safe_asprintf(str, "%s" format, *str == NULL ? "" : *str, ##__VA_ARGS__); \
|
||||
ALLOC_CHECK(*str); \
|
||||
if (old != NULL && old != *str) { \
|
||||
free(old); \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Sanitize String
|
||||
void sanitize_string(char *str, int max_length, unsigned int allow_newlines);
|
||||
void sanitize_string(char *str, int max_length, int allow_newlines);
|
||||
|
||||
// CP437
|
||||
char *to_cp437(const char *input);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <libreborn/exec.h>
|
||||
|
||||
// Define Constants
|
||||
#define ENV(name, ...) const char *name##_ENV = #name;
|
||||
#define ENV(name, ...) const char *const name##_ENV = #name;
|
||||
#include <libreborn/env-list.h>
|
||||
#undef ENV
|
||||
|
||||
|
@ -127,10 +127,19 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
|
||||
}
|
||||
}
|
||||
|
||||
// Set obj To NULL On asprintf() Failure
|
||||
#define safe_asprintf(obj, ...) \
|
||||
{ \
|
||||
if (asprintf(obj, __VA_ARGS__) == -1) { \
|
||||
*obj = NULL; \
|
||||
} \
|
||||
ALLOC_CHECK(*obj); \
|
||||
}
|
||||
|
||||
// Get Exit Status String
|
||||
void get_exit_status_string(int status, char **out) {
|
||||
void get_exit_status_string(const int status, char **out) {
|
||||
if (out != NULL) {
|
||||
*out =NULL;
|
||||
*out = NULL;
|
||||
if (WIFEXITED(status)) {
|
||||
safe_asprintf(out, ": Exit Code: %i", WEXITSTATUS(status));
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include <libreborn/string.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Sanitize String
|
||||
void sanitize_string(char *str, int max_length, unsigned int allow_newlines) {
|
||||
void sanitize_string(char *str, const int max_length, const int allow_newlines) {
|
||||
// Store Message Length
|
||||
size_t length = strlen(str);
|
||||
// Truncate Message
|
||||
|
@ -58,6 +58,7 @@ set(SRC
|
||||
src/input/toggle.cpp
|
||||
src/input/misc.cpp
|
||||
src/input/drop.cpp
|
||||
src/input/keys.cpp
|
||||
# sign
|
||||
src/sign/sign.cpp
|
||||
# atlas
|
||||
|
@ -27,4 +27,5 @@ void init_bucket();
|
||||
void init_cake();
|
||||
void init_home();
|
||||
void init_override();
|
||||
void init_screenshot();
|
||||
}
|
||||
|
@ -1,16 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
extern "C" {
|
||||
typedef void (*input_tick_function_t)(Minecraft *minecraft);
|
||||
void input_run_on_tick(input_tick_function_t function);
|
||||
|
||||
void input_set_is_right_click(int val);
|
||||
int input_back();
|
||||
void input_drop(int drop_slot);
|
||||
void input_set_is_ctrl(bool val);
|
||||
|
||||
void input_set_is_left_click(int val);
|
||||
|
||||
void input_set_mouse_grab_state(int state);
|
||||
enum {
|
||||
#define KEY(name, value) MC_KEY_##name = (value),
|
||||
#include "key-list.h"
|
||||
#undef KEY
|
||||
};
|
||||
}
|
13
mods/include/mods/input/key-list.h
Normal file
13
mods/include/mods/input/key-list.h
Normal file
@ -0,0 +1,13 @@
|
||||
// MCPI Seems To Use https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
||||
KEY(BACKSPACE, 0x8)
|
||||
KEY(DELETE, 0x2e)
|
||||
KEY(LEFT, 0x25)
|
||||
KEY(RIGHT, 0x27)
|
||||
KEY(F1, 0x70)
|
||||
KEY(F2, 0x71)
|
||||
KEY(F5, 0x74)
|
||||
KEY(F11, 0x7a)
|
||||
KEY(RETURN, 0xd)
|
||||
KEY(t, 0x54)
|
||||
KEY(q, 0x51)
|
||||
KEY(ESCAPE, 0x1b)
|
@ -23,3 +23,4 @@ void misc_run_on_tiles_setup(const std::function<void()> &func);
|
||||
void misc_run_on_items_setup(const std::function<void()> &func);
|
||||
void misc_run_on_language_setup(const std::function<void()> &func);
|
||||
void misc_run_on_game_key_press(const std::function<bool(Minecraft *, int)> &func);
|
||||
void misc_run_on_key_press(const std::function<bool(Minecraft *, int)> &func);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
struct Gui;
|
||||
|
||||
extern "C" {
|
||||
void screenshot_take(const char *home);
|
||||
void screenshot_take(Gui *gui);
|
||||
}
|
@ -3,12 +3,11 @@
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
#include <mods/screenshot/screenshot.h>
|
||||
#include <mods/home/home.h>
|
||||
#include <mods/init/init.h>
|
||||
|
||||
// Take Screenshot Using TripodCamera
|
||||
static void AppPlatform_saveScreenshot_injection(__attribute__((unused)) AppPlatform_saveScreenshot_t original, __attribute__((unused)) AppPlatform *app_platform, __attribute__((unused)) std::string *path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) {
|
||||
screenshot_take(home_get());
|
||||
screenshot_take(nullptr);
|
||||
}
|
||||
|
||||
// Enable TripodCameraRenderer
|
||||
|
@ -1,9 +1,13 @@
|
||||
#include "chat-internal.h"
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/chat/chat.h>
|
||||
#include <mods/text-input-box/TextInputScreen.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/touch/touch.h>
|
||||
#include <mods/input/input.h>
|
||||
|
||||
static std::vector<std::string> &get_history() {
|
||||
static std::vector<std::string> history = {};
|
||||
@ -143,7 +147,7 @@ static Screen *create_chat_screen() {
|
||||
// Init
|
||||
void _init_chat_ui() {
|
||||
misc_run_on_game_key_press([](Minecraft *minecraft, int key) {
|
||||
if (key == 0x54) {
|
||||
if (key == MC_KEY_t) {
|
||||
if (minecraft->isLevelGenerated() && minecraft->screen == nullptr) {
|
||||
minecraft->setScreen(create_chat_screen());
|
||||
}
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/sign/sign.h>
|
||||
#include <mods/chat/chat.h>
|
||||
#include <mods/home/home.h>
|
||||
|
||||
// Custom Title
|
||||
HOOK(SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) {
|
||||
@ -47,24 +45,16 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||
|
||||
// Handle Events
|
||||
if (ret == 1 && event != nullptr) {
|
||||
int handled = 0;
|
||||
bool handled = false;
|
||||
switch (event->type) {
|
||||
case SDL_KEYDOWN: {
|
||||
// Handle Key Presses
|
||||
if (event->key.keysym.sym == SDLK_F11) {
|
||||
media_toggle_fullscreen();
|
||||
handled = 1;
|
||||
} else if (event->key.keysym.sym == SDLK_F2) {
|
||||
screenshot_take(home_get());
|
||||
handled = 1;
|
||||
} else if (event->key.keysym.sym == SDLK_ESCAPE) {
|
||||
// Treat Escape As Back Button Press (This Fixes Issues With Signs)
|
||||
handled = input_back();
|
||||
} else if (event->key.keysym.sym == SDLK_q) {
|
||||
// Drop Item
|
||||
input_drop((event->key.keysym.mod & KMOD_CTRL) != 0);
|
||||
handled = 1;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
// Track Control Key
|
||||
bool is_ctrl = (event->key.keysym.mod & KMOD_CTRL) != 0;
|
||||
if (event->type == SDL_KEYUP) {
|
||||
is_ctrl = false;
|
||||
}
|
||||
input_set_is_ctrl(is_ctrl);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
@ -72,8 +62,6 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||
// Track Right-Click State
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) {
|
||||
input_set_is_right_click(event->button.state != SDL_RELEASED);
|
||||
} else if (event->button.button == SDL_BUTTON_LEFT) {
|
||||
input_set_is_left_click(event->button.state != SDL_RELEASED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -81,7 +69,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||
// SDL_UserEvent Is Never Used In MCPI, So It Is Repurposed For Character Events
|
||||
if (event->user.code == USER_EVENT_CHARACTER) {
|
||||
sign_key_press((char) event->user.data1);
|
||||
handled = 1;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -13,13 +13,17 @@ __attribute__((constructor)) static void init() {
|
||||
} else {
|
||||
init_multiplayer();
|
||||
}
|
||||
init_sound();
|
||||
if (!reborn_is_headless()) {
|
||||
init_sound();
|
||||
}
|
||||
init_input();
|
||||
init_sign();
|
||||
init_camera();
|
||||
init_atlas();
|
||||
init_title_screen();
|
||||
init_skin();
|
||||
if (!reborn_is_headless()) {
|
||||
init_skin();
|
||||
}
|
||||
init_fps();
|
||||
init_touch();
|
||||
init_textures();
|
||||
@ -36,4 +40,7 @@ __attribute__((constructor)) static void init() {
|
||||
if (!reborn_is_server()) {
|
||||
init_benchmark();
|
||||
}
|
||||
if (!reborn_is_headless()) {
|
||||
init_screenshot();
|
||||
}
|
||||
}
|
||||
|
@ -3,53 +3,28 @@
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
#include "input-internal.h"
|
||||
#include <mods/input/input.h>
|
||||
|
||||
// Store Left Click (0 = Not Pressed, 1 = Pressed)
|
||||
static int is_left_click = 0;
|
||||
void input_set_is_left_click(int val) {
|
||||
if ((is_left_click == 0 && val == 1) || (is_left_click != 0 && val == 0)) {
|
||||
is_left_click = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Add Attacking To MouseBuildInput
|
||||
static int32_t MouseBuildInput_tickBuild_injection(MouseBuildInput_tickBuild_t original, MouseBuildInput *mouse_build_input, Player *local_player, uint32_t *build_action_intention_return) {
|
||||
#define REMOVE_ATTACK_BAI 0xa
|
||||
#define ATTACK_BAI 0x8
|
||||
static bool MouseBuildInput_tickBuild_injection(MouseBuildInput_tickBuild_t original, MouseBuildInput *mouse_build_input, Player *local_player, uint32_t *build_action_intention_return) {
|
||||
// Call Original Method
|
||||
int32_t ret = original(mouse_build_input, local_player, build_action_intention_return);
|
||||
|
||||
// Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click
|
||||
if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) {
|
||||
// Get Target HitResult
|
||||
const bool ret = original(mouse_build_input, local_player, build_action_intention_return);
|
||||
// Convert Remove/Attack Into Attack If A Tile Is Not Selected
|
||||
if (ret && *build_action_intention_return == REMOVE_ATTACK_BAI) {
|
||||
Minecraft *minecraft = ((LocalPlayer *) local_player)->minecraft;
|
||||
HitResult *hit_result = &minecraft->hit_result;
|
||||
int32_t hit_result_type = hit_result->type;
|
||||
// Check if The Target Is An Entity Using HitResult
|
||||
if (hit_result_type == 1) {
|
||||
// Change BuildActionIntention To Attack/Place Mode (Place Will Not Happen Because The HitResult Is An Entity)
|
||||
*build_action_intention_return = 0x8;
|
||||
if (minecraft->hit_result.type != 0) {
|
||||
*build_action_intention_return = ATTACK_BAI;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Fix Holding Attack
|
||||
static bool last_player_attack_successful = false;
|
||||
static bool Player_attack_Entity_hurt_injection(Entity *entity, Entity *attacker, int32_t damage) {
|
||||
// Call Original Method
|
||||
last_player_attack_successful = entity->hurt(attacker, damage);
|
||||
return last_player_attack_successful;
|
||||
}
|
||||
static ItemInstance *Player_attack_Inventory_getSelected_injection(Inventory *inventory) {
|
||||
// Check If Attack Was Successful
|
||||
if (!last_player_attack_successful) {
|
||||
return nullptr;
|
||||
static void Minecraft_handleBuildAction_injection(Minecraft_handleBuildAction_t original, Minecraft *self, uint *bai) {
|
||||
if (*bai == ATTACK_BAI) {
|
||||
*bai = REMOVE_ATTACK_BAI;
|
||||
}
|
||||
|
||||
// Call Original Method
|
||||
return inventory->getSelected();
|
||||
original(self, bai);
|
||||
}
|
||||
|
||||
// Init
|
||||
@ -57,9 +32,6 @@ void _init_attack() {
|
||||
// Allow Attacking Mobs
|
||||
if (feature_has("Fix Attacking", server_disabled)) {
|
||||
overwrite_calls(MouseBuildInput_tickBuild, MouseBuildInput_tickBuild_injection);
|
||||
|
||||
// Fix Holding Attack
|
||||
overwrite_call((void *) 0x8fc1c, (void *) Player_attack_Entity_hurt_injection);
|
||||
overwrite_call((void *) 0x8fc24, (void *) Player_attack_Inventory_getSelected_injection);
|
||||
overwrite_calls(Minecraft_handleBuildAction, Minecraft_handleBuildAction_injection);
|
||||
}
|
||||
}
|
||||
|
@ -11,23 +11,23 @@ void input_set_is_right_click(int val) {
|
||||
is_right_click = val;
|
||||
}
|
||||
|
||||
// Enable Bow & Arrow Fix
|
||||
static int fix_bow = 0;
|
||||
|
||||
// Handle Bow & Arrow
|
||||
static void _handle_bow(Minecraft *minecraft) {
|
||||
if (fix_bow && !is_right_click) {
|
||||
static void _handle_bow(Minecraft_tickInput_t original, Minecraft *minecraft) {
|
||||
if (!is_right_click) {
|
||||
GameMode *game_mode = minecraft->game_mode;
|
||||
LocalPlayer *player = minecraft->player;
|
||||
if (player != nullptr && game_mode != nullptr && player->isUsingItem()) {
|
||||
game_mode->releaseUsingItem((Player *) player);
|
||||
}
|
||||
}
|
||||
// Call Original Method
|
||||
original(minecraft);
|
||||
}
|
||||
|
||||
// Init
|
||||
void _init_bow() {
|
||||
// Enable Bow & Arrow Fix
|
||||
fix_bow = feature_has("Fix Bow & Arrow", server_disabled);
|
||||
input_run_on_tick(_handle_bow);
|
||||
if (feature_has("Fix Bow & Arrow", server_disabled)) {
|
||||
overwrite_calls(Minecraft_tickInput, _handle_bow);
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,15 @@
|
||||
#include <mods/creative/creative.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Enable Item Dropping
|
||||
static int enable_drop = 0;
|
||||
|
||||
// Store Drop Item Presses
|
||||
static int drop_item_presses = 0;
|
||||
static bool drop_slot_pressed = false;
|
||||
void input_drop(int drop_slot) {
|
||||
if (enable_drop) {
|
||||
if (drop_slot) {
|
||||
drop_slot_pressed = true;
|
||||
} else {
|
||||
drop_item_presses++;
|
||||
}
|
||||
}
|
||||
// Track Control Key
|
||||
static bool drop_slot = false;
|
||||
void input_set_is_ctrl(const bool val) {
|
||||
drop_slot = val;
|
||||
}
|
||||
|
||||
// Handle Drop Item Presses
|
||||
static void _handle_drop(Minecraft *minecraft) {
|
||||
if ((minecraft->screen == nullptr) && (!creative_is_restricted() || !Minecraft_isCreativeMode(minecraft)) && (drop_item_presses > 0 || drop_slot_pressed)) {
|
||||
if (!creative_is_restricted() || !Minecraft_isCreativeMode(minecraft)) {
|
||||
// Get Player
|
||||
LocalPlayer *player = minecraft->player;
|
||||
if (player != nullptr) {
|
||||
@ -43,16 +33,12 @@ static void _handle_drop(Minecraft *minecraft) {
|
||||
*dropped_item = *inventory_item;
|
||||
|
||||
// Update Inventory
|
||||
if (drop_slot_pressed) {
|
||||
// Drop Slot
|
||||
|
||||
// Empty Slot
|
||||
if (drop_slot) {
|
||||
// Drop Entire Slot
|
||||
inventory_item->count = 0;
|
||||
} else {
|
||||
// Drop Item
|
||||
|
||||
// Set Item Drop Count
|
||||
int drop_count = drop_item_presses < inventory_item->count ? drop_item_presses : inventory_item->count;
|
||||
const int drop_count = 1;
|
||||
dropped_item->count = drop_count;
|
||||
inventory_item->count -= drop_count;
|
||||
}
|
||||
@ -68,13 +54,18 @@ static void _handle_drop(Minecraft *minecraft) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset
|
||||
drop_item_presses = 0;
|
||||
drop_slot_pressed = false;
|
||||
}
|
||||
|
||||
// Init
|
||||
void _init_drop() {
|
||||
enable_drop = feature_has("Bind \"Q\" Key To Item Dropping", server_disabled);
|
||||
input_run_on_tick(_handle_drop);
|
||||
if (feature_has("Bind \"Q\" Key To Item Dropping", server_disabled)) {
|
||||
misc_run_on_game_key_press([](Minecraft *mc, int key) {
|
||||
if (key == MC_KEY_q) {
|
||||
_handle_drop(mc);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,5 @@ __attribute__((visibility("internal"))) void _init_attack();
|
||||
__attribute__((visibility("internal"))) void _init_bow();
|
||||
__attribute__((visibility("internal"))) void _init_misc();
|
||||
__attribute__((visibility("internal"))) void _init_toggle();
|
||||
__attribute__((visibility("internal"))) void _init_drop();
|
||||
__attribute__((visibility("internal"))) void _init_drop();
|
||||
__attribute__((visibility("internal"))) void _init_keys();
|
@ -1,7 +1,3 @@
|
||||
#include <vector>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <media-layer/core.h>
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
@ -9,26 +5,6 @@
|
||||
#include "input-internal.h"
|
||||
#include <mods/input/input.h>
|
||||
|
||||
// Run Functions On Input Tick
|
||||
static std::vector<input_tick_function_t> &get_input_tick_functions() {
|
||||
static std::vector<input_tick_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void input_run_on_tick(input_tick_function_t function) {
|
||||
get_input_tick_functions().push_back(function);
|
||||
}
|
||||
|
||||
// Handle Input Fixes
|
||||
static void Minecraft_tickInput_injection(Minecraft_tickInput_t original, Minecraft *minecraft) {
|
||||
// Call Original Method
|
||||
original(minecraft);
|
||||
|
||||
// Run Input Tick Functions
|
||||
for (input_tick_function_t function : get_input_tick_functions()) {
|
||||
function(minecraft);
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
void init_input() {
|
||||
// Miscellaneous
|
||||
@ -43,9 +19,6 @@ void init_input() {
|
||||
// Enable Bow & Arrow Fix
|
||||
_init_bow();
|
||||
|
||||
// Loop
|
||||
overwrite_calls(Minecraft_tickInput, Minecraft_tickInput_injection);
|
||||
|
||||
// Allow Attacking Mobs
|
||||
_init_attack();
|
||||
|
||||
@ -53,4 +26,7 @@ void init_input() {
|
||||
if (feature_has("Disable Raw Mouse Motion (Not Recommended)", server_disabled)) {
|
||||
media_set_raw_mouse_motion_enabled(0);
|
||||
}
|
||||
|
||||
// Extra Key Codes
|
||||
_init_keys();
|
||||
}
|
||||
|
24
mods/src/input/keys.cpp
Normal file
24
mods/src/input/keys.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <mods/input/input.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "input-internal.h"
|
||||
|
||||
// Translator
|
||||
static int32_t sdl_key_to_minecraft_key_injection(Common_sdl_key_to_minecraft_key_t original, int32_t sdl_key) {
|
||||
switch (sdl_key) {
|
||||
#define KEY(name, value) case SDLK_##name: return MC_KEY_##name;
|
||||
#include <mods/input/key-list.h>
|
||||
#undef KEY
|
||||
default: {
|
||||
// Call Original Method
|
||||
return original(sdl_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
void _init_keys() {
|
||||
overwrite_calls(Common_sdl_key_to_minecraft_key, sdl_key_to_minecraft_key_injection);
|
||||
}
|
@ -1,25 +1,16 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "input-internal.h"
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include <mods/creative/creative.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Enable Miscellaneous Input Fixes
|
||||
static int enable_misc = 0;
|
||||
|
||||
// Store Back Button Presses
|
||||
static int back_button_presses = 0;
|
||||
int input_back() {
|
||||
if (enable_misc) {
|
||||
back_button_presses++;
|
||||
return 1; // Handled
|
||||
} else {
|
||||
return 0; // Not Handled
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Back Button Presses
|
||||
static void _handle_back(Minecraft *minecraft) {
|
||||
// If Minecraft's Level property is initialized, but Minecraft's Player property is nullptr, then Minecraft::handleBack may crash.
|
||||
@ -28,10 +19,7 @@ static void _handle_back(Minecraft *minecraft) {
|
||||
return;
|
||||
}
|
||||
// Send Event
|
||||
for (int i = 0; i < back_button_presses; i++) {
|
||||
minecraft->handleBack(0);
|
||||
}
|
||||
back_button_presses = 0;
|
||||
minecraft->handleBack(false);
|
||||
}
|
||||
|
||||
// Fix OptionsScreen Ignoring The Back Button
|
||||
@ -52,32 +40,12 @@ static bool InBedScreen_handleBackEvent_injection(InBedScreen *screen, bool do_n
|
||||
// Stop Sleeping
|
||||
LocalPlayer *player = minecraft->player;
|
||||
if (player != nullptr) {
|
||||
player->stopSleepInBed(1, 1, 1);
|
||||
player->stopSleepInBed(true, true, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set Mouse Grab State
|
||||
static int mouse_grab_state = 0;
|
||||
void input_set_mouse_grab_state(int state) {
|
||||
mouse_grab_state = state;
|
||||
}
|
||||
|
||||
// Grab/Un-Grab Mouse
|
||||
static void _handle_mouse_grab(Minecraft *minecraft) {
|
||||
if (mouse_grab_state == -1) {
|
||||
// Grab
|
||||
minecraft->grabMouse();
|
||||
} else if (mouse_grab_state == 1) {
|
||||
// Un-Grab
|
||||
minecraft->releaseMouse();
|
||||
}
|
||||
mouse_grab_state = 0;
|
||||
}
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
// Block UI Interaction When Mouse Is Locked
|
||||
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *minecraft) {
|
||||
bool is_in_game = minecraft->screen == nullptr || minecraft->screen->vtable == (Screen_vtable *) Touch_IngameBlockSelectionScreen_vtable_base;
|
||||
@ -86,7 +54,7 @@ static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *
|
||||
return creative_is_restricted() && minecraft->isCreativeMode();
|
||||
} else {
|
||||
// Disable Item Drop Ticking
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,10 +76,16 @@ void _init_misc() {
|
||||
patch_vtable(InBedScreen_handleBackEvent, InBedScreen_handleBackEvent_injection);
|
||||
// Disable Opening Inventory Using The Cursor When Cursor Is Hidden
|
||||
overwrite_calls(Gui_handleClick, Gui_handleClick_injection);
|
||||
// Proper Back Button Handling
|
||||
misc_run_on_key_press([](Minecraft *mc, const int key) {
|
||||
if (key == MC_KEY_ESCAPE) {
|
||||
_handle_back(mc);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Disable Item Dropping Using The Cursor When Cursor Is Hidden
|
||||
overwrite_call((void *) 0x27800, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection);
|
||||
|
||||
input_run_on_tick(_handle_back);
|
||||
input_run_on_tick(_handle_mouse_grab);
|
||||
}
|
||||
|
@ -9,11 +9,11 @@
|
||||
// Handle Toggle Options
|
||||
static bool _handle_toggle_options(Minecraft *minecraft, int key) {
|
||||
Options *options = &minecraft->options;
|
||||
if (key == 0x70) {
|
||||
if (key == MC_KEY_F1) {
|
||||
// Toggle Hide GUI
|
||||
options->hide_gui = options->hide_gui ^ 1;
|
||||
return true;
|
||||
} else if (key == 0x74) {
|
||||
} else if (key == MC_KEY_F5) {
|
||||
// Toggle Third Person
|
||||
options->third_person = (options->third_person + 1) % 3;
|
||||
return true;
|
||||
|
@ -89,6 +89,15 @@ void misc_run_on_game_key_press(const std::function<bool(Minecraft *, int)> &fun
|
||||
original(self, key);
|
||||
});
|
||||
}
|
||||
void misc_run_on_key_press(const std::function<bool(Minecraft *, int)> &func) {
|
||||
misc_run_on_game_key_press(func);
|
||||
overwrite_calls(Screen_keyPressed, [func](Screen_keyPressed_t original, Screen *self, int key) {
|
||||
if (func(self->minecraft, key)) {
|
||||
return;
|
||||
}
|
||||
original(self, key);
|
||||
});
|
||||
}
|
||||
|
||||
// Render Fancy Background
|
||||
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height) {
|
||||
|
@ -19,9 +19,11 @@
|
||||
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include "misc-internal.h"
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
#include "misc-internal.h"
|
||||
|
||||
// Classic HUD
|
||||
#define DEFAULT_HUD_PADDING 2
|
||||
#define NEW_HUD_PADDING 1
|
||||
@ -134,12 +136,12 @@ static void Gui_renderChatMessages_injection(Gui_renderChatMessages_t original,
|
||||
}
|
||||
|
||||
// Call Original Method
|
||||
if (!hide_chat_messages && !is_in_chat) {
|
||||
if (!hide_chat_messages && (!is_in_chat || disable_fading)) {
|
||||
original(gui, y_offset, max_messages, disable_fading, font);
|
||||
}
|
||||
|
||||
// Render Selected Item Text
|
||||
if (render_selected_item_text) {
|
||||
if (render_selected_item_text && !disable_fading) {
|
||||
// Fix GL Mode
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
// Calculate Selected Item Text Scale
|
||||
@ -361,7 +363,7 @@ int32_t misc_get_real_selected_slot(Player *player) {
|
||||
}
|
||||
|
||||
// Properly Generate Buffers
|
||||
static void anGenBuffers_injection(int32_t count, uint32_t *buffers) {
|
||||
static void anGenBuffers_injection(__attribute__((unused)) Common_anGenBuffers_t original, const int32_t count, uint32_t *buffers) {
|
||||
if (!reborn_is_headless()) {
|
||||
glGenBuffers(count, buffers);
|
||||
}
|
||||
@ -829,7 +831,7 @@ void init_misc() {
|
||||
}
|
||||
|
||||
// Properly Generate Buffers
|
||||
overwrite(Common_anGenBuffers, anGenBuffers_injection);
|
||||
overwrite_calls(Common_anGenBuffers, anGenBuffers_injection);
|
||||
|
||||
// Fix Graphics Bug When Switching To First-Person While Sneaking
|
||||
patch_vtable(PlayerRenderer_render, PlayerRenderer_render_injection);
|
||||
@ -904,7 +906,9 @@ void init_misc() {
|
||||
|
||||
// Replace Block Highlight With Outline
|
||||
if (feature_has("Replace Block Highlight With Outline", server_disabled)) {
|
||||
overwrite(LevelRenderer_renderHitSelect, LevelRenderer_renderHitOutline);
|
||||
overwrite_calls(LevelRenderer_renderHitSelect, [](__attribute__((unused)) LevelRenderer_renderHitSelect_t original, LevelRenderer *self, Player *player, HitResult *hit_result, int i, void *vp, float f) {
|
||||
self->renderHitOutline(player, hit_result, i, vp, f);
|
||||
});
|
||||
unsigned char fix_outline_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||
patch((void *) 0x4d830, fix_outline_patch);
|
||||
overwrite_call((void *) 0x4d764, (void *) LevelRenderer_render_AABB_glColor4f_injection);
|
||||
@ -968,6 +972,16 @@ void init_misc() {
|
||||
// Don't Wrap Text On '\r' Or '\t' Because THey Are Actual Characters In MCPI
|
||||
patch_address(&Strings::text_wrapping_delimiter, (void *) " \n");
|
||||
|
||||
// Fullscreen
|
||||
misc_run_on_key_press([](__attribute__((unused)) Minecraft *mc, int key) {
|
||||
if (key == MC_KEY_F11) {
|
||||
media_toggle_fullscreen();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Init Logging
|
||||
_init_misc_logging();
|
||||
_init_misc_api();
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "options-internal.h"
|
||||
|
||||
// Force Mob Spawning
|
||||
static bool LevelData_getSpawnMobs_injection(__attribute__((unused)) LevelData *level_data) {
|
||||
static bool LevelData_getSpawnMobs_injection(__attribute__((unused)) LevelData_getSpawnMobs_t original, __attribute__((unused)) LevelData *level_data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ static void Options_save_Options_addOptionToSaveOutput_injection(Options *option
|
||||
}
|
||||
|
||||
// MCPI's OptionsFile::getOptionStrings is broken, this is the version in v0.7.0
|
||||
static std::vector<std::string> OptionsFile_getOptionStrings_injection(OptionsFile *options_file) {
|
||||
static std::vector<std::string> OptionsFile_getOptionStrings_injection(__attribute__((unused)) OptionsFile_getOptionStrings_t original, OptionsFile *options_file) {
|
||||
// Get options.txt Path
|
||||
std::string path = options_file->options_txt_path;
|
||||
// Parse
|
||||
@ -145,7 +145,7 @@ static const char *get_new_options_txt_path() {
|
||||
void init_options() {
|
||||
// Force Mob Spawning
|
||||
if (feature_has("Force Mob Spawning", server_auto)) {
|
||||
overwrite(LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection);
|
||||
overwrite_calls(LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection);
|
||||
}
|
||||
|
||||
// Render Distance
|
||||
@ -191,7 +191,7 @@ void init_options() {
|
||||
// When Loading, options.txt Should Be Opened In Read Mode
|
||||
patch_address((void *) &Strings::options_txt_fopen_mode_when_loading, (void *) "r");
|
||||
// Fix OptionsFile::getOptionStrings
|
||||
overwrite(OptionsFile_getOptionStrings, OptionsFile_getOptionStrings_injection);
|
||||
overwrite_calls(OptionsFile_getOptionStrings, OptionsFile_getOptionStrings_injection);
|
||||
|
||||
// Sensitivity Loading/Saving Is Broken, Disable It
|
||||
patch((void *) 0x1931c, nop_patch);
|
||||
|
@ -11,12 +11,22 @@
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <GLES/gl.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/screenshot/screenshot.h>
|
||||
#include <mods/home/home.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/init/init.h>
|
||||
|
||||
// Ensure Screenshots Folder Exists
|
||||
static void ensure_screenshots_folder(const char *screenshots) {
|
||||
// Check Screenshots Folder
|
||||
ensure_directory(screenshots);
|
||||
static std::string get_screenshot_dir() {
|
||||
std::string dir = std::string(home_get()) + "/screenshots";
|
||||
ensure_directory(dir.c_str());
|
||||
return dir;
|
||||
}
|
||||
static std::string get_screenshot(const std::string &filename) {
|
||||
return get_screenshot_dir() + '/' + filename;
|
||||
}
|
||||
|
||||
// Take Screenshot
|
||||
@ -27,15 +37,12 @@ static int save_png(const char *filename, unsigned char *pixels, int line_size,
|
||||
// Write Image
|
||||
return !stbi_write_png(filename, width, height, 4, pixels, line_size);
|
||||
}
|
||||
void screenshot_take(const char *home) {
|
||||
void screenshot_take(Gui *gui) {
|
||||
// Check
|
||||
if (reborn_is_headless()) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
|
||||
// Get Directory
|
||||
const std::string screenshots = std::string(home) + "/screenshots";
|
||||
|
||||
// Get Timestamp
|
||||
time_t raw_time;
|
||||
time(&raw_time);
|
||||
@ -43,16 +50,18 @@ void screenshot_take(const char *home) {
|
||||
char time[512];
|
||||
strftime(time, 512, "%Y-%m-%d_%H.%M.%S", time_info);
|
||||
|
||||
// Ensure Screenshots Folder Exists
|
||||
ensure_screenshots_folder(screenshots.c_str());
|
||||
|
||||
// Prevent Overwriting Screenshots
|
||||
int num = 1;
|
||||
std::string file = screenshots + '/' + time + ".png";
|
||||
while (access(file.c_str(), F_OK) != -1) {
|
||||
file = screenshots + '/' + time + '-' + std::to_string(num) + ".png";
|
||||
int num = 0;
|
||||
std::string filename;
|
||||
do {
|
||||
filename = std::string(time);
|
||||
if (num > 0) {
|
||||
filename += '-' + std::to_string(num);
|
||||
}
|
||||
filename += ".png";
|
||||
num++;
|
||||
}
|
||||
} while (access(get_screenshot(filename).c_str(), F_OK) != -1);
|
||||
const std::string file = get_screenshot(filename);
|
||||
|
||||
// Get Image Size
|
||||
GLint viewport[4];
|
||||
@ -85,9 +94,29 @@ void screenshot_take(const char *home) {
|
||||
if (save_png(file.c_str(), pixels, line_size, width, height)) {
|
||||
WARN("Screenshot Failed: %s", file.c_str());
|
||||
} else {
|
||||
INFO("Screenshot Saved: %s", file.c_str());
|
||||
std::string msg = "Screenshot Saved: ";
|
||||
INFO("%s%s", msg.c_str(), file.c_str());
|
||||
if (gui) {
|
||||
msg += filename;
|
||||
gui->addMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Free
|
||||
free(pixels);
|
||||
}
|
||||
|
||||
// Init
|
||||
void init_screenshot() {
|
||||
// Create Directory
|
||||
get_screenshot_dir();
|
||||
// Take Screenshot On F2
|
||||
misc_run_on_key_press([](Minecraft *mc, int key) {
|
||||
if (key == MC_KEY_F2) {
|
||||
screenshot_take(&mc->gui);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/server/server.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/home/home.h>
|
||||
#include <mods/compat/compat.h>
|
||||
@ -202,23 +201,6 @@ static void list_callback(Minecraft *minecraft, const std::string &username, Pla
|
||||
INFO(" - %s (%s)", username.c_str(), get_player_ip(minecraft, player));
|
||||
}
|
||||
|
||||
// Handle Server Stop
|
||||
static void handle_server_stop(Minecraft *minecraft) {
|
||||
if (compat_check_exit_requested()) {
|
||||
INFO("Stopping Server");
|
||||
// Save And Exit
|
||||
Level *level = get_level(minecraft);
|
||||
if (level != nullptr) {
|
||||
level->saveLevelData();
|
||||
}
|
||||
minecraft->leaveGame(false);
|
||||
// Stop Game
|
||||
SDL_Event event;
|
||||
event.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
// Track TPS
|
||||
#define NANOSECONDS_IN_SECOND 1000000000ll
|
||||
static long long int get_time() {
|
||||
@ -248,112 +230,109 @@ static ServerSideNetworkHandler *get_server_side_network_handler(Minecraft *mine
|
||||
}
|
||||
|
||||
// Read STDIN Thread
|
||||
static volatile bool stdin_buffer_complete = false;
|
||||
static volatile char *stdin_buffer = nullptr;
|
||||
static pthread_t read_stdin_thread_obj;
|
||||
static volatile bool stdin_line_ready = false;
|
||||
static std::string stdin_line;
|
||||
static void *read_stdin_thread(__attribute__((unused)) void *data) {
|
||||
// Loop
|
||||
while (true) {
|
||||
int bytes_available;
|
||||
if (ioctl(fileno(stdin), FIONREAD, &bytes_available) == -1) {
|
||||
bytes_available = 0;
|
||||
}
|
||||
char buffer[bytes_available];
|
||||
bytes_available = read(fileno(stdin), (void *) buffer, bytes_available);
|
||||
for (int i = 0; i < bytes_available; i++) {
|
||||
if (!stdin_buffer_complete) {
|
||||
// Read Data
|
||||
char x = buffer[i];
|
||||
if (x == '\n') {
|
||||
if (stdin_buffer == nullptr) {
|
||||
stdin_buffer = (volatile char *) malloc(1);
|
||||
stdin_buffer[0] = '\0';
|
||||
}
|
||||
stdin_buffer_complete = true;
|
||||
} else {
|
||||
string_append((char **) &stdin_buffer, "%c", (char) x);
|
||||
}
|
||||
}
|
||||
}
|
||||
char *line = nullptr;
|
||||
size_t len = 0;
|
||||
while (getline(&line, &len, stdin) != -1) {
|
||||
stdin_line = line;
|
||||
stdin_line_ready = true;
|
||||
// Wait For Line To Be Read
|
||||
while (stdin_line_ready) {}
|
||||
}
|
||||
free(line);
|
||||
return nullptr;
|
||||
}
|
||||
__attribute__((destructor)) static void _free_stdin_buffer() {
|
||||
if (stdin_buffer != nullptr) {
|
||||
free((void *) stdin_buffer);
|
||||
stdin_buffer = nullptr;
|
||||
|
||||
// Handle Server Stop
|
||||
static void handle_server_stop(Minecraft *minecraft) {
|
||||
if (compat_check_exit_requested()) {
|
||||
INFO("Stopping Server");
|
||||
// Save And Exit
|
||||
Level *level = get_level(minecraft);
|
||||
if (level != nullptr) {
|
||||
level->saveLevelData();
|
||||
}
|
||||
minecraft->leaveGame(false);
|
||||
// Kill Reader Thread
|
||||
pthread_cancel(read_stdin_thread_obj);
|
||||
pthread_join(read_stdin_thread_obj, nullptr);
|
||||
stdin_line_ready = false;
|
||||
// Stop Game
|
||||
SDL_Event event;
|
||||
event.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Commands
|
||||
static void handle_commands(Minecraft *minecraft) {
|
||||
// Check If Level Is Generated
|
||||
if (minecraft->isLevelGenerated() && stdin_buffer_complete) {
|
||||
if (minecraft->isLevelGenerated() && stdin_line_ready) {
|
||||
// Read Line
|
||||
std::string data = std::move(stdin_line);
|
||||
data.pop_back(); // Remove Newline
|
||||
stdin_line_ready = false;
|
||||
// Command Ready; Run It
|
||||
if (stdin_buffer != nullptr) {
|
||||
ServerSideNetworkHandler *server_side_network_handler = get_server_side_network_handler(minecraft);
|
||||
if (server_side_network_handler != nullptr) {
|
||||
std::string data((char *) stdin_buffer);
|
||||
|
||||
static std::string ban_command("ban ");
|
||||
static std::string say_command("say ");
|
||||
static std::string kill_command("kill ");
|
||||
static std::string list_command("list");
|
||||
static std::string reload_command("reload");
|
||||
static std::string tps_command("tps");
|
||||
static std::string stop_command("stop");
|
||||
static std::string help_command("help");
|
||||
if (!is_whitelist() && data.rfind(ban_command, 0) == 0) {
|
||||
// IP-Ban Target Username
|
||||
std::string ban_username = data.substr(ban_command.length());
|
||||
find_players(minecraft, ban_username, ban_callback, false);
|
||||
} else if (data == reload_command) {
|
||||
INFO("Reloading %s", is_whitelist() ? "Whitelist" : "Blacklist");
|
||||
is_ip_in_blacklist(nullptr);
|
||||
} else if (data.rfind(kill_command, 0) == 0) {
|
||||
// Kill Target Username
|
||||
std::string kill_username = data.substr(kill_command.length());
|
||||
find_players(minecraft, kill_username, kill_callback, false);
|
||||
} else if (data.rfind(say_command, 0) == 0) {
|
||||
// Format Message
|
||||
std::string message = "[Server] " + data.substr(say_command.length());
|
||||
char *safe_message = to_cp437(message.c_str());
|
||||
std::string cpp_string = safe_message;
|
||||
// Post Message To Chat
|
||||
server_side_network_handler->displayGameMessage(&cpp_string);
|
||||
// Free
|
||||
free(safe_message);
|
||||
} else if (data == list_command) {
|
||||
// List Players
|
||||
INFO("All Players:");
|
||||
find_players(minecraft, "", list_callback, true);
|
||||
} else if (data == tps_command) {
|
||||
// Print TPS
|
||||
INFO("TPS: %f", tps);
|
||||
} else if (data == stop_command) {
|
||||
// Stop Server
|
||||
compat_request_exit();
|
||||
} else if (data == help_command) {
|
||||
INFO("All Commands:");
|
||||
if (!is_whitelist()) {
|
||||
INFO(" ban <Username> - IP-Ban All Players With Specifed Username");
|
||||
}
|
||||
INFO(" reload - Reload The %s", is_whitelist() ? "Whitelist" : "Blacklist");
|
||||
INFO(" kill <Username> - Kill All Players With Specifed Username");
|
||||
INFO(" say <Message> - Print Specified Message To Chat");
|
||||
INFO(" list - List All Players");
|
||||
INFO(" tps - Print TPS");
|
||||
INFO(" stop - Stop Server");
|
||||
INFO(" help - Print This Message");
|
||||
} else {
|
||||
INFO("Invalid Command: %s", data.c_str());
|
||||
ServerSideNetworkHandler *server_side_network_handler = get_server_side_network_handler(minecraft);
|
||||
if (server_side_network_handler != nullptr) {
|
||||
static std::string ban_command("ban ");
|
||||
static std::string say_command("say ");
|
||||
static std::string kill_command("kill ");
|
||||
static std::string list_command("list");
|
||||
static std::string reload_command("reload");
|
||||
static std::string tps_command("tps");
|
||||
static std::string stop_command("stop");
|
||||
static std::string help_command("help");
|
||||
if (!is_whitelist() && data.rfind(ban_command, 0) == 0) {
|
||||
// IP-Ban Target Username
|
||||
std::string ban_username = data.substr(ban_command.length());
|
||||
find_players(minecraft, ban_username, ban_callback, false);
|
||||
} else if (data == reload_command) {
|
||||
INFO("Reloading %s", is_whitelist() ? "Whitelist" : "Blacklist");
|
||||
is_ip_in_blacklist(nullptr);
|
||||
} else if (data.rfind(kill_command, 0) == 0) {
|
||||
// Kill Target Username
|
||||
std::string kill_username = data.substr(kill_command.length());
|
||||
find_players(minecraft, kill_username, kill_callback, false);
|
||||
} else if (data.rfind(say_command, 0) == 0) {
|
||||
// Format Message
|
||||
std::string message = "[Server] " + data.substr(say_command.length());
|
||||
char *safe_message = to_cp437(message.c_str());
|
||||
std::string cpp_string = safe_message;
|
||||
// Post Message To Chat
|
||||
server_side_network_handler->displayGameMessage(&cpp_string);
|
||||
// Free
|
||||
free(safe_message);
|
||||
} else if (data == list_command) {
|
||||
// List Players
|
||||
INFO("All Players:");
|
||||
find_players(minecraft, "", list_callback, true);
|
||||
} else if (data == tps_command) {
|
||||
// Print TPS
|
||||
INFO("TPS: %f", tps);
|
||||
} else if (data == stop_command) {
|
||||
// Stop Server
|
||||
compat_request_exit();
|
||||
} else if (data == help_command) {
|
||||
INFO("All Commands:");
|
||||
if (!is_whitelist()) {
|
||||
INFO(" ban <Username> - IP-Ban All Players With Specifed Username");
|
||||
}
|
||||
INFO(" reload - Reload The %s", is_whitelist() ? "Whitelist" : "Blacklist");
|
||||
INFO(" kill <Username> - Kill All Players With Specifed Username");
|
||||
INFO(" say <Message> - Print Specified Message To Chat");
|
||||
INFO(" list - List All Players");
|
||||
INFO(" tps - Print TPS");
|
||||
INFO(" stop - Stop Server");
|
||||
INFO(" help - Print This Message");
|
||||
} else {
|
||||
INFO("Invalid Command: %s", data.c_str());
|
||||
}
|
||||
|
||||
// Free
|
||||
free((void *) stdin_buffer);
|
||||
stdin_buffer = nullptr;
|
||||
}
|
||||
stdin_buffer_complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,7 +556,6 @@ static void server_init() {
|
||||
misc_run_on_tick(Minecraft_tick_injection);
|
||||
|
||||
// Start Reading STDIN
|
||||
pthread_t read_stdin_thread_obj;
|
||||
pthread_create(&read_stdin_thread_obj, nullptr, read_stdin_thread, nullptr);
|
||||
}
|
||||
|
||||
|
@ -1,34 +1,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/sign/sign.h>
|
||||
|
||||
// Handle Backspace
|
||||
static int32_t sdl_key_to_minecraft_key_injection(Common_sdl_key_to_minecraft_key_t original, int32_t sdl_key) {
|
||||
if (sdl_key == SDLK_BACKSPACE) {
|
||||
return 0x8;
|
||||
} else if (sdl_key == SDLK_DELETE) {
|
||||
return 0x2e;
|
||||
} else if (sdl_key == SDLK_LEFT) {
|
||||
return 0x25;
|
||||
} else if (sdl_key == SDLK_RIGHT) {
|
||||
return 0x27;
|
||||
} else if (sdl_key == SDLK_F1) {
|
||||
return 0x70;
|
||||
} else if (sdl_key == SDLK_F5) {
|
||||
return 0x74;
|
||||
} else {
|
||||
// Call Original Method
|
||||
return original(sdl_key);
|
||||
}
|
||||
}
|
||||
|
||||
// Open Sign Screen
|
||||
static void LocalPlayer_openTextEdit_injection(LocalPlayer *local_player, TileEntity *sign) {
|
||||
if (sign->type == 4) {
|
||||
@ -41,7 +19,7 @@ static void LocalPlayer_openTextEdit_injection(LocalPlayer *local_player, TileEn
|
||||
}
|
||||
|
||||
// Store Text Input
|
||||
void sign_key_press(char key) {
|
||||
void sign_key_press(const char key) {
|
||||
Keyboard::_inputText.push_back(key);
|
||||
}
|
||||
|
||||
@ -51,7 +29,4 @@ void init_sign() {
|
||||
// Fix Signs
|
||||
patch_vtable(LocalPlayer_openTextEdit, LocalPlayer_openTextEdit_injection);
|
||||
}
|
||||
|
||||
// Handle Backspace
|
||||
overwrite_calls(Common_sdl_key_to_minecraft_key, sdl_key_to_minecraft_key_injection);
|
||||
}
|
||||
|
@ -79,10 +79,6 @@ static int32_t Textures_loadAndBindTexture_injection(Textures *textures, __attri
|
||||
|
||||
// Init
|
||||
void init_skin() {
|
||||
// Not Needed On Headless Mode
|
||||
if (reborn_is_headless()) {
|
||||
return;
|
||||
}
|
||||
// Check Feature Flag
|
||||
if (feature_has("Load Custom Skins", server_disabled)) {
|
||||
// LocalPlayer
|
||||
|
@ -69,15 +69,15 @@ static void play(std::string name, float x, float y, float z, float volume, floa
|
||||
media_audio_play(source.c_str(), resolved_name.c_str(), x, y, z, pitch, volume, is_ui);
|
||||
}
|
||||
}
|
||||
static void SoundEngine_playUI_injection(__attribute__((unused)) SoundEngine *sound_engine, std::string *name, float volume, float pitch) {
|
||||
static void SoundEngine_playUI_injection(__attribute__((unused)) SoundEngine_playUI_t original, __attribute__((unused)) SoundEngine *sound_engine, std::string *name, float volume, float pitch) {
|
||||
play(*name, 0, 0, 0, volume, pitch, true);
|
||||
}
|
||||
static void SoundEngine_play_injection(__attribute__((unused)) SoundEngine *sound_engine, std::string *name, float x, float y, float z, float volume, float pitch) {
|
||||
static void SoundEngine_play_injection(__attribute__((unused)) SoundEngine_play_t original, __attribute__((unused)) SoundEngine *sound_engine, std::string *name, float x, float y, float z, float volume, float pitch) {
|
||||
play(*name, x, y, z, volume, pitch, false);
|
||||
}
|
||||
|
||||
// Refresh Data
|
||||
static void SoundEngine_update_injection(SoundEngine *sound_engine, Mob *listener_mob, __attribute__((unused)) float listener_angle) {
|
||||
static void SoundEngine_update_injection(__attribute__((unused)) SoundEngine_update_t original, SoundEngine *sound_engine, Mob *listener_mob, __attribute__((unused)) float listener_angle) {
|
||||
// Variables
|
||||
static float volume = 0;
|
||||
static float x = 0;
|
||||
@ -117,15 +117,11 @@ static void SoundEngine_init_injection(SoundEngine_init_t original, SoundEngine
|
||||
|
||||
// Init
|
||||
void init_sound() {
|
||||
// Not Needed On Headless Mode
|
||||
if (reborn_is_headless()) {
|
||||
return;
|
||||
}
|
||||
// Implement Sound Engine
|
||||
if (feature_has("Implement Sound Engine", server_disabled)) {
|
||||
overwrite(SoundEngine_playUI, SoundEngine_playUI_injection);
|
||||
overwrite(SoundEngine_play, SoundEngine_play_injection);
|
||||
overwrite(SoundEngine_update, SoundEngine_update_injection);
|
||||
overwrite_calls(SoundEngine_playUI, SoundEngine_playUI_injection);
|
||||
overwrite_calls(SoundEngine_play, SoundEngine_play_injection);
|
||||
overwrite_calls(SoundEngine_update, SoundEngine_update_injection);
|
||||
overwrite_calls(SoundEngine_init, SoundEngine_init_injection);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include <mods/text-input-box/TextInputBox.h>
|
||||
#include <mods/input/input.h>
|
||||
|
||||
TextInputBox *TextInputBox::create(const std::string &placeholder, const std::string &text) {
|
||||
// Construct
|
||||
@ -49,7 +50,7 @@ void TextInputBox::keyPressed(int key) {
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 0x8: {
|
||||
case MC_KEY_BACKSPACE: {
|
||||
// Backspace
|
||||
if (m_text.empty()) {
|
||||
return;
|
||||
@ -65,7 +66,7 @@ void TextInputBox::keyPressed(int key) {
|
||||
recalculateScroll();
|
||||
break;
|
||||
}
|
||||
case 0x2e: {
|
||||
case MC_KEY_DELETE: {
|
||||
// Delete
|
||||
if (m_text.empty()) {
|
||||
return;
|
||||
@ -79,7 +80,7 @@ void TextInputBox::keyPressed(int key) {
|
||||
m_text.erase(m_text.begin() + m_insertHead, m_text.begin() + m_insertHead + 1);
|
||||
break;
|
||||
}
|
||||
case 0x25: {
|
||||
case MC_KEY_LEFT: {
|
||||
// Left
|
||||
m_insertHead--;
|
||||
if (m_insertHead < 0) {
|
||||
@ -88,7 +89,7 @@ void TextInputBox::keyPressed(int key) {
|
||||
recalculateScroll();
|
||||
break;
|
||||
}
|
||||
case 0x27: {
|
||||
case MC_KEY_RIGHT: {
|
||||
// Right
|
||||
m_insertHead++;
|
||||
if (!m_text.empty()) {
|
||||
@ -101,7 +102,7 @@ void TextInputBox::keyPressed(int key) {
|
||||
recalculateScroll();
|
||||
break;
|
||||
}
|
||||
case 0x0d: {
|
||||
case MC_KEY_RETURN: {
|
||||
// Enter
|
||||
m_bFocused = false;
|
||||
break;
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
// Enable Touch GUI
|
||||
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) Minecraft *minecraft) {
|
||||
return 1;
|
||||
static bool Minecraft_isTouchscreen_injection(__attribute__((unused)) Minecraft_isTouchscreen_t original, __attribute__((unused)) Minecraft *minecraft) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IngameBlockSelectionScreen Memory Allocation Override
|
||||
@ -17,7 +17,7 @@ static unsigned char *operator_new_IngameBlockSelectionScreen_injection(__attrib
|
||||
}
|
||||
|
||||
// Improved Button Hover Behavior
|
||||
static int32_t Button_hovered_injection(__attribute__((unused)) Button *button, __attribute__((unused)) Minecraft *minecraft, __attribute__((unused)) int32_t click_x, __attribute__((unused)) int32_t click_y) {
|
||||
static int32_t Button_hovered_injection(__attribute__((unused)) Button_hovered_t original, __attribute__((unused)) Button *button, __attribute__((unused)) Minecraft *minecraft, __attribute__((unused)) int32_t click_x, __attribute__((unused)) int32_t click_y) {
|
||||
// Get Mouse Position
|
||||
int32_t x = Mouse::getX() * Gui::InvGuiScale;
|
||||
int32_t y = Mouse::getY() * Gui::InvGuiScale;
|
||||
@ -33,7 +33,7 @@ static int32_t Button_hovered_injection(__attribute__((unused)) Button *button,
|
||||
}
|
||||
static void LargeImageButton_render_GuiComponent_drawCenteredString_injection(GuiComponent *component, Font *font, std::string *text, int32_t x, int32_t y, int32_t color) {
|
||||
// Change Color On Hover
|
||||
if (color == 0xe0e0e0 && Button_hovered_injection((Button *) component, nullptr, 0, 0)) {
|
||||
if (color == 0xe0e0e0 && Button_hovered_injection(nullptr, (Button *) component, nullptr, 0, 0)) {
|
||||
color = 0xffffa0;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ void init_touch() {
|
||||
int touch_buttons = touch_gui;
|
||||
if (touch_gui) {
|
||||
// Main UI
|
||||
overwrite(Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection);
|
||||
overwrite_calls(Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection);
|
||||
|
||||
// Force Correct Toolbar Size
|
||||
unsigned char toolbar_patch[4] = {0x01, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1"
|
||||
@ -97,7 +97,7 @@ void init_touch() {
|
||||
|
||||
// Improved Button Hover Behavior
|
||||
if (touch_buttons && feature_has("Improved Button Hover Behavior", server_disabled)) {
|
||||
overwrite(Button_hovered, Button_hovered_injection);
|
||||
overwrite_calls(Button_hovered, Button_hovered_injection);
|
||||
overwrite_call((void *) 0x1ebd4, (void *) LargeImageButton_render_GuiComponent_drawCenteredString_injection);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ const char *version_get() {
|
||||
}
|
||||
|
||||
// Injection For Touch GUI Version
|
||||
static std::string Common_getGameVersionString_injection(__attribute__((unused)) std::string *version_suffix) {
|
||||
static std::string Common_getGameVersionString_injection(__attribute__((unused)) Common_getGameVersionString_t original, __attribute__((unused)) std::string *version_suffix) {
|
||||
// Set Version
|
||||
return version_get();
|
||||
}
|
||||
@ -24,7 +24,7 @@ static std::string Common_getGameVersionString_injection(__attribute__((unused))
|
||||
// Init
|
||||
void init_version() {
|
||||
// Touch GUI
|
||||
overwrite(Common_getGameVersionString, Common_getGameVersionString_injection);
|
||||
overwrite_calls(Common_getGameVersionString, Common_getGameVersionString_injection);
|
||||
// Normal GUI
|
||||
patch_address((void *) &Strings::minecraft_pi_version, (void *) version_get());
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
vtable 0x102540;
|
||||
|
||||
virtual-method int tickBuild(Player *player, uint *build_action_intention_return) = 0xc;
|
||||
virtual-method bool tickBuild(Player *player, uint *build_action_intention_return) = 0xc;
|
||||
|
Loading…
Reference in New Issue
Block a user