2.2.8
This commit is contained in:
parent
a79a601c59
commit
472f5d67a5
@ -1,5 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
**2.2.8**
|
||||||
|
* Add "Hide Chat Messages" Optional Feature Flag
|
||||||
|
* Add "Remove Creative Restrictions" Optional Feature Flag
|
||||||
|
* Improve GLFW->SDL Mouse Motion Event Conversion
|
||||||
|
* Performance Optimizations
|
||||||
|
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
|
||||||
|
* Simple Benchmark Mode
|
||||||
|
* Fix Typo When Audio Source File Doesn't Exist
|
||||||
|
* Improve Build System
|
||||||
|
|
||||||
**2.2.7**
|
**2.2.7**
|
||||||
* Fix Crash When OpenAL Is Unavailable
|
* Fix Crash When OpenAL Is Unavailable
|
||||||
* Fix Command Input In Server
|
* Fix Command Input In Server
|
||||||
|
@ -9,3 +9,8 @@ FALSE This Flag Is Off By Default
|
|||||||
|
|
||||||
## ``--only-generate`` (Server Mode Only)
|
## ``--only-generate`` (Server Mode Only)
|
||||||
If you run MCPI-Reborn with ``--only-generate``, it will immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
|
If you run MCPI-Reborn with ``--only-generate``, it will immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
|
||||||
|
|
||||||
|
## ``--benchmark`` (Client Mode Only)
|
||||||
|
If you run MCPI-Reborn with ``--benchmark``, it will enter a simple benchmark mode. This means automatically loading a newly generated world, then rotating the camera for a period of time. When it has finished, it will then exit and print the average FPS while the world was loaded. In this mode, all user input is blocked. However you can still modify rendering settings by changing feature flags.
|
||||||
|
|
||||||
|
The world used will always be re-created on start and uses a hard-coded seed.
|
||||||
|
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -8,6 +8,7 @@ TRUE Display Nametags By Default
|
|||||||
TRUE Fix Sign Placement
|
TRUE Fix Sign Placement
|
||||||
TRUE Show Block Outlines
|
TRUE Show Block Outlines
|
||||||
FALSE Expand Creative Inventory
|
FALSE Expand Creative Inventory
|
||||||
|
FALSE Remove Creative Restrictions
|
||||||
FALSE Peaceful Mode
|
FALSE Peaceful Mode
|
||||||
TRUE Animated Water
|
TRUE Animated Water
|
||||||
TRUE Remove Invalid Item Background
|
TRUE Remove Invalid Item Background
|
||||||
@ -16,6 +17,7 @@ TRUE Smooth Lighting
|
|||||||
FALSE 3D Anaglyph
|
FALSE 3D Anaglyph
|
||||||
TRUE Fix Camera Rendering
|
TRUE Fix Camera Rendering
|
||||||
TRUE Implement Chat
|
TRUE Implement Chat
|
||||||
|
FALSE Hide Chat Messages
|
||||||
TRUE Implement Death Messages
|
TRUE Implement Death Messages
|
||||||
TRUE Implement Game-Mode Switching
|
TRUE Implement Game-Mode Switching
|
||||||
TRUE Allow Joining Survival Servers
|
TRUE Allow Joining Survival Servers
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <media-layer/internal.h>
|
#include <media-layer/internal.h>
|
||||||
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
// SDL Is Replaced With GLFW
|
// SDL Is Replaced With GLFW
|
||||||
|
|
||||||
@ -41,3 +42,7 @@ int SDL_PushEvent(SDL_Event *event) {
|
|||||||
pthread_mutex_unlock(&queue_mutex);
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void media_ensure_loaded() {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
@ -16,6 +16,14 @@
|
|||||||
#include "audio/engine.h"
|
#include "audio/engine.h"
|
||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
|
// Allow Disabling Interaction
|
||||||
|
static void update_cursor();
|
||||||
|
static int is_interactable = 1;
|
||||||
|
void media_set_interactable(int toggle) {
|
||||||
|
is_interactable = toggle;
|
||||||
|
update_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
// GLFW Code Not Needed In Headless Mode
|
// GLFW Code Not Needed In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
@ -139,6 +147,7 @@ static SDLMod glfw_modifier_to_sdl_modifier(int mods) {
|
|||||||
|
|
||||||
// Pass Key Presses To SDL
|
// Pass Key Presses To SDL
|
||||||
static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int scancode, int action, __attribute__((unused)) int mods) {
|
static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int scancode, int action, __attribute__((unused)) int mods) {
|
||||||
|
if (is_interactable) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
int up = action == GLFW_RELEASE;
|
int up = action == GLFW_RELEASE;
|
||||||
event.type = up ? SDL_KEYUP : SDL_KEYDOWN;
|
event.type = up ? SDL_KEYUP : SDL_KEYDOWN;
|
||||||
@ -151,32 +160,40 @@ static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int sc
|
|||||||
character_event((char) '\b');
|
character_event((char) '\b');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pass Text To Minecraft
|
// Pass Text To Minecraft
|
||||||
static void glfw_char(__attribute__((unused)) GLFWwindow *window, unsigned int codepoint) {
|
static void glfw_char(__attribute__((unused)) GLFWwindow *window, unsigned int codepoint) {
|
||||||
|
if (is_interactable) {
|
||||||
character_event((char) codepoint);
|
character_event((char) codepoint);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last Mouse Location
|
||||||
static double last_mouse_x = 0;
|
static double last_mouse_x = 0;
|
||||||
static double last_mouse_y = 0;
|
static double last_mouse_y = 0;
|
||||||
static int ignore_relative_mouse = 1;
|
// Ignore Relative Cursor Motion
|
||||||
|
static int ignore_relative_motion = 0;
|
||||||
|
|
||||||
// Pass Mouse Movement To SDL
|
// Pass Mouse Movement To SDL
|
||||||
static void glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) {
|
static void glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) {
|
||||||
|
if (is_interactable) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = SDL_MOUSEMOTION;
|
event.type = SDL_MOUSEMOTION;
|
||||||
event.motion.x = xpos;
|
event.motion.x = xpos;
|
||||||
event.motion.y = ypos;
|
event.motion.y = ypos;
|
||||||
event.motion.xrel = !ignore_relative_mouse ? (xpos - last_mouse_x) : 0;
|
event.motion.xrel = !ignore_relative_motion ? (xpos - last_mouse_x) : 0;
|
||||||
event.motion.yrel = !ignore_relative_mouse ? (ypos - last_mouse_y) : 0;
|
event.motion.yrel = !ignore_relative_motion ? (ypos - last_mouse_y) : 0;
|
||||||
ignore_relative_mouse = 0;
|
SDL_PushEvent(&event);
|
||||||
|
}
|
||||||
|
ignore_relative_motion = 0;
|
||||||
last_mouse_x = xpos;
|
last_mouse_x = xpos;
|
||||||
last_mouse_y = ypos;
|
last_mouse_y = ypos;
|
||||||
SDL_PushEvent(&event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create And Push SDL Mouse Click Event
|
// Create And Push SDL Mouse Click Event
|
||||||
static void click_event(int button, int up) {
|
static void click_event(int button, int up) {
|
||||||
|
if (is_interactable) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = up ? SDL_MOUSEBUTTONUP : SDL_MOUSEBUTTONDOWN;
|
event.type = up ? SDL_MOUSEBUTTONUP : SDL_MOUSEBUTTONDOWN;
|
||||||
event.button.x = last_mouse_x;
|
event.button.x = last_mouse_x;
|
||||||
@ -185,17 +202,20 @@ static void click_event(int button, int up) {
|
|||||||
event.button.button = button;
|
event.button.button = button;
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pass Mouse Click To SDL
|
// Pass Mouse Click To SDL
|
||||||
static void glfw_click(__attribute__((unused)) GLFWwindow *window, int button, int action, __attribute__((unused)) int mods) {
|
static void glfw_click(__attribute__((unused)) GLFWwindow *window, int button, int action, __attribute__((unused)) int mods) {
|
||||||
|
if (is_interactable) {
|
||||||
int up = action == GLFW_RELEASE;
|
int up = action == GLFW_RELEASE;
|
||||||
int sdl_button = button == GLFW_MOUSE_BUTTON_RIGHT ? SDL_BUTTON_RIGHT : (button == GLFW_MOUSE_BUTTON_LEFT ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE);
|
int sdl_button = button == GLFW_MOUSE_BUTTON_RIGHT ? SDL_BUTTON_RIGHT : (button == GLFW_MOUSE_BUTTON_LEFT ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE);
|
||||||
click_event(sdl_button, up);
|
click_event(sdl_button, up);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pass Mouse Scroll To SDL
|
// Pass Mouse Scroll To SDL
|
||||||
static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute__((unused)) double xoffset, double yoffset) {
|
static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute__((unused)) double xoffset, double yoffset) {
|
||||||
if (yoffset != 0) {
|
if (is_interactable && yoffset != 0) {
|
||||||
int sdl_button = yoffset > 0 ? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
|
int sdl_button = yoffset > 0 ? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
|
||||||
click_event(sdl_button, 0);
|
click_event(sdl_button, 0);
|
||||||
click_event(sdl_button, 1);
|
click_event(sdl_button, 1);
|
||||||
@ -207,6 +227,17 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
|
|||||||
// Track Media Layer State
|
// Track Media Layer State
|
||||||
static int is_running = 0;
|
static int is_running = 0;
|
||||||
|
|
||||||
|
// Disable V-Sync
|
||||||
|
static int disable_vsync = 0;
|
||||||
|
void media_disable_vsync() {
|
||||||
|
disable_vsync = 1;
|
||||||
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
if (is_running) {
|
||||||
|
glfwSwapInterval(0);
|
||||||
|
}
|
||||||
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
}
|
||||||
|
|
||||||
// Init Media Layer
|
// Init Media Layer
|
||||||
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
|
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
|
||||||
// Don't Enable GLFW In Headless Mode
|
// Don't Enable GLFW In Headless Mode
|
||||||
@ -250,6 +281,12 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
|||||||
|
|
||||||
// Set State
|
// Set State
|
||||||
is_running = 1;
|
is_running = 1;
|
||||||
|
|
||||||
|
// Update State
|
||||||
|
update_cursor();
|
||||||
|
if (disable_vsync) {
|
||||||
|
media_disable_vsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_swap_buffers() {
|
void media_swap_buffers() {
|
||||||
@ -341,15 +378,20 @@ static int cursor_grabbed = 0;
|
|||||||
static int cursor_visible = 1;
|
static int cursor_visible = 1;
|
||||||
|
|
||||||
// Update GLFW Cursor State (Client Only)
|
// Update GLFW Cursor State (Client Only)
|
||||||
|
static void update_cursor() {
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
static void update_glfw_cursor() {
|
if (is_running) {
|
||||||
|
// Get New State
|
||||||
|
int new_cursor_visible = is_interactable ? cursor_visible : 1;
|
||||||
|
int new_cursor_grabbed = is_interactable ? cursor_grabbed : 0;
|
||||||
|
|
||||||
// Store Old Mode
|
// Store Old Mode
|
||||||
int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
|
int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
|
||||||
|
|
||||||
// Handle Cursor Visibility
|
// Handle Cursor Visibility
|
||||||
int new_mode;
|
int new_mode;
|
||||||
if (!cursor_visible) {
|
if (!new_cursor_visible) {
|
||||||
if (cursor_grabbed) {
|
if (new_cursor_grabbed) {
|
||||||
new_mode = GLFW_CURSOR_DISABLED;
|
new_mode = GLFW_CURSOR_DISABLED;
|
||||||
} else {
|
} else {
|
||||||
new_mode = GLFW_CURSOR_HIDDEN;
|
new_mode = GLFW_CURSOR_HIDDEN;
|
||||||
@ -358,6 +400,11 @@ static void update_glfw_cursor() {
|
|||||||
new_mode = GLFW_CURSOR_NORMAL;
|
new_mode = GLFW_CURSOR_NORMAL;
|
||||||
}
|
}
|
||||||
if (new_mode != old_mode) {
|
if (new_mode != old_mode) {
|
||||||
|
// Ignore Relative Cursor Motion When Locking
|
||||||
|
if (new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) {
|
||||||
|
ignore_relative_motion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Set New Mode
|
// Set New Mode
|
||||||
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
|
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
|
||||||
|
|
||||||
@ -365,13 +412,19 @@ static void update_glfw_cursor() {
|
|||||||
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
|
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
|
||||||
// Use Raw Mouse Motion
|
// Use Raw Mouse Motion
|
||||||
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
|
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset Last Mouse Position
|
// Reset Mouse Position When Unlocking
|
||||||
ignore_relative_mouse = 1;
|
if (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED) {
|
||||||
|
double cursor_x;
|
||||||
|
double cursor_y;
|
||||||
|
glfwGetCursorPos(glfw_window, &cursor_x, &cursor_y);
|
||||||
|
glfw_motion(glfw_window, cursor_x, cursor_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
}
|
||||||
|
|
||||||
// Fix SDL Cursor Visibility/Grabbing
|
// Fix SDL Cursor Visibility/Grabbing
|
||||||
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
|
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
|
||||||
@ -386,9 +439,7 @@ SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
|
|||||||
cursor_grabbed = 0;
|
cursor_grabbed = 0;
|
||||||
}
|
}
|
||||||
// Update Cursor GLFW State (Client Only)
|
// Update Cursor GLFW State (Client Only)
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
update_cursor();
|
||||||
update_glfw_cursor();
|
|
||||||
#endif
|
|
||||||
// Return
|
// Return
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
@ -406,9 +457,7 @@ int SDL_ShowCursor(int toggle) {
|
|||||||
cursor_visible = 0;
|
cursor_visible = 0;
|
||||||
}
|
}
|
||||||
// Update Cursor GLFW State (Client Only)
|
// Update Cursor GLFW State (Client Only)
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
update_cursor();
|
||||||
update_glfw_cursor();
|
|
||||||
#endif
|
|
||||||
// Return
|
// Return
|
||||||
return toggle;
|
return toggle;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ extern "C" {
|
|||||||
#define GL_DEPTH_TEST 0xb71
|
#define GL_DEPTH_TEST 0xb71
|
||||||
#define GL_PACK_ALIGNMENT 0xd05
|
#define GL_PACK_ALIGNMENT 0xd05
|
||||||
#define GL_UNPACK_ALIGNMENT 0xcf5
|
#define GL_UNPACK_ALIGNMENT 0xcf5
|
||||||
|
#define GL_SRC_ALPHA 0x302
|
||||||
|
#define GL_ONE_MINUS_SRC_ALPHA 0x303
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -8,11 +8,15 @@ extern "C" {
|
|||||||
#define DEFAULT_WIDTH 840
|
#define DEFAULT_WIDTH 840
|
||||||
#define DEFAULT_HEIGHT 480
|
#define DEFAULT_HEIGHT 480
|
||||||
|
|
||||||
|
void media_ensure_loaded();
|
||||||
|
|
||||||
void media_take_screenshot(char *home);
|
void media_take_screenshot(char *home);
|
||||||
void media_toggle_fullscreen();
|
void media_toggle_fullscreen();
|
||||||
void media_swap_buffers();
|
void media_swap_buffers();
|
||||||
void media_cleanup();
|
void media_cleanup();
|
||||||
void media_get_framebuffer_size(int *width, int *height);
|
void media_get_framebuffer_size(int *width, int *height);
|
||||||
|
void media_set_interactable(int is_interactable);
|
||||||
|
void media_disable_vsync();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -307,3 +307,32 @@ CALL(60, media_audio_play, void, (const char *source, const char *name, float x,
|
|||||||
free(name);
|
free(name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CALL(62, media_set_interactable, void, (int is_interactable)) {
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Lock Proxy
|
||||||
|
start_proxy_call();
|
||||||
|
|
||||||
|
// Arguments
|
||||||
|
write_int(is_interactable);
|
||||||
|
|
||||||
|
// Release Proxy
|
||||||
|
end_proxy_call();
|
||||||
|
#else
|
||||||
|
int is_interactable = read_int();
|
||||||
|
// Run
|
||||||
|
media_set_interactable(is_interactable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(63, media_disable_vsync, void, ()) {
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Lock Proxy
|
||||||
|
start_proxy_call();
|
||||||
|
// Release Proxy
|
||||||
|
end_proxy_call();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
media_disable_vsync();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
|
|
||||||
// Track Client State
|
// Track Client State
|
||||||
@ -85,43 +87,20 @@ static void start_media_layer_proxy_client(int read, int write) {
|
|||||||
update_client_state(1, 0);
|
update_client_state(1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximize Pipe Buffer Size
|
|
||||||
static void maximize_pipe_fd_size(int fd) {
|
|
||||||
// Read Maximum Pipe Size
|
|
||||||
std::ifstream max_size_file("/proc/sys/fs/pipe-max-size");
|
|
||||||
if (!max_size_file.good()) {
|
|
||||||
PROXY_ERR("%s", "Unable To Open Maximum Pipe Size File");
|
|
||||||
}
|
|
||||||
// Read One Line
|
|
||||||
int max_size;
|
|
||||||
std::string line;
|
|
||||||
if (std::getline(max_size_file, line) && line.size() > 0) {
|
|
||||||
max_size = std::stoi(line);
|
|
||||||
} else {
|
|
||||||
PROXY_ERR("%s", "Unable To Read Maximum Pipe Size File");
|
|
||||||
}
|
|
||||||
// Set Maximum Pipe Size
|
|
||||||
errno = 0;
|
|
||||||
if (fcntl(fd, F_SETPIPE_SZ, max_size) < max_size) {
|
|
||||||
PROXY_ERR("Unable To Set Maximum Pipe Size: %s", errno != 0 ? strerror(errno) : "Unknown Error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void maximize_pipe_size(int pipe[2]) {
|
|
||||||
maximize_pipe_fd_size(pipe[0]);
|
|
||||||
maximize_pipe_fd_size(pipe[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Server
|
// Start Server
|
||||||
__attribute__((constructor)) static void init_media_layer_proxy_server() {
|
static int loaded = 0;
|
||||||
|
__attribute__((constructor)) void media_ensure_loaded() {
|
||||||
|
if (!loaded) {
|
||||||
|
loaded = 1;
|
||||||
|
|
||||||
|
// Log
|
||||||
PROXY_INFO("%s", "Starting...");
|
PROXY_INFO("%s", "Starting...");
|
||||||
|
|
||||||
// Create Connection
|
// Create Connection
|
||||||
int server_to_client_pipe[2];
|
int server_to_client_pipe[2];
|
||||||
safe_pipe2(server_to_client_pipe, 0);
|
safe_pipe2(server_to_client_pipe, 0);
|
||||||
maximize_pipe_size(server_to_client_pipe);
|
|
||||||
int client_to_server_pipe[2];
|
int client_to_server_pipe[2];
|
||||||
safe_pipe2(client_to_server_pipe, 0);
|
safe_pipe2(client_to_server_pipe, 0);
|
||||||
maximize_pipe_size(client_to_server_pipe);
|
|
||||||
// Set Connection
|
// Set Connection
|
||||||
set_connection(client_to_server_pipe[0], server_to_client_pipe[1]);
|
set_connection(client_to_server_pipe[0], server_to_client_pipe[1]);
|
||||||
|
|
||||||
@ -138,6 +117,7 @@ __attribute__((constructor)) static void init_media_layer_proxy_server() {
|
|||||||
// Free
|
// Free
|
||||||
free(str);
|
free(str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Assign Unique ID To Function
|
// Assign Unique ID To Function
|
||||||
static std::unordered_map<std::string, unsigned char> &get_unique_ids() {
|
static std::unordered_map<std::string, unsigned char> &get_unique_ids() {
|
||||||
|
@ -23,7 +23,7 @@ target_link_libraries(chat reborn symbols feature pthread)
|
|||||||
|
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp)
|
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp)
|
||||||
target_link_libraries(server reborn symbols feature home compat version dl media-layer-core pthread)
|
target_link_libraries(server reborn symbols feature home misc compat dl media-layer-core pthread)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(compat input sign chat home dl)
|
target_link_libraries(compat input sign chat home dl)
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ else()
|
|||||||
target_link_libraries(camera reborn symbols media-layer-core feature home)
|
target_link_libraries(camera reborn symbols media-layer-core feature home)
|
||||||
|
|
||||||
add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp)
|
add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp)
|
||||||
target_link_libraries(input reborn symbols feature media-layer-core)
|
target_link_libraries(input reborn symbols creative feature media-layer-core)
|
||||||
|
|
||||||
add_library(sign SHARED src/sign/sign.cpp)
|
add_library(sign SHARED src/sign/sign.cpp)
|
||||||
target_link_libraries(sign reborn symbols feature input)
|
target_link_libraries(sign reborn symbols feature input)
|
||||||
@ -58,6 +58,11 @@ else()
|
|||||||
|
|
||||||
add_library(atlas SHARED src/atlas/atlas.cpp)
|
add_library(atlas SHARED src/atlas/atlas.cpp)
|
||||||
target_link_libraries(atlas reborn symbols feature GLESv1_CM)
|
target_link_libraries(atlas reborn symbols feature GLESv1_CM)
|
||||||
|
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
add_library(benchmark SHARED src/benchmark/benchmark.cpp)
|
||||||
|
target_link_libraries(benchmark reborn symbols compat misc media-layer-core)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp)
|
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp)
|
||||||
@ -66,8 +71,8 @@ target_link_libraries(game-mode reborn symbols feature)
|
|||||||
add_library(death SHARED src/death/death.cpp)
|
add_library(death SHARED src/death/death.cpp)
|
||||||
target_link_libraries(death reborn symbols feature)
|
target_link_libraries(death reborn symbols feature)
|
||||||
|
|
||||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp)
|
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp)
|
||||||
target_link_libraries(misc reborn symbols feature)
|
target_link_libraries(misc reborn symbols feature GLESv1_CM)
|
||||||
|
|
||||||
add_library(options SHARED src/options/options.c)
|
add_library(options SHARED src/options/options.c)
|
||||||
target_link_libraries(options reborn symbols feature)
|
target_link_libraries(options reborn symbols feature)
|
||||||
@ -79,11 +84,14 @@ add_library(test SHARED src/test/test.c)
|
|||||||
target_link_libraries(test reborn home)
|
target_link_libraries(test reborn home)
|
||||||
|
|
||||||
add_library(init SHARED src/init/init.c)
|
add_library(init SHARED src/init/init.c)
|
||||||
target_link_libraries(init compat game-mode misc death options chat home version test)
|
target_link_libraries(init compat game-mode misc death options chat home version test media-layer-core)
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
target_link_libraries(init server)
|
target_link_libraries(init server)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(init multiplayer sound camera input sign creative touch textures atlas)
|
target_link_libraries(init multiplayer sound camera input sign creative touch textures atlas)
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
target_link_libraries(init benchmark)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
## Install Mods
|
## Install Mods
|
||||||
@ -92,4 +100,7 @@ if(MCPI_SERVER_MODE)
|
|||||||
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
else()
|
else()
|
||||||
install(TARGETS multiplayer sound override camera input sign creative touch textures atlas DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS multiplayer sound override camera input sign creative touch textures atlas DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
install(TARGETS benchmark DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
2
mods/src/benchmark/README.md
Normal file
2
mods/src/benchmark/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# ``benchmark`` Mod
|
||||||
|
This mod contain a simple game benchmark.
|
147
mods/src/benchmark/benchmark.cpp
Normal file
147
mods/src/benchmark/benchmark.cpp
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
|
#include <media-layer/core.h>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
#include "../init/init.h"
|
||||||
|
#include "../compat/compat.h"
|
||||||
|
#include "../misc/misc.h"
|
||||||
|
|
||||||
|
// --benchmark: Activate Benchmark
|
||||||
|
static bool active = false;
|
||||||
|
__attribute__((constructor)) static void _init_active(int argc, char *argv[]) {
|
||||||
|
// Iterate Arguments
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
// Check Argument
|
||||||
|
if (strcmp(argv[i], "--benchmark") == 0) {
|
||||||
|
// Enabled
|
||||||
|
active = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define NANOSECONDS_IN_SECOND 1000000000ll
|
||||||
|
|
||||||
|
// Config
|
||||||
|
#define BENCHMARK_GAME_MODE 1 // Creative Mode
|
||||||
|
#define BENCHMARK_SEED 2048 // Random Number
|
||||||
|
#define BENCHMARK_WORLD_NAME "_Benchmark" // Random Number
|
||||||
|
#define BENCHMARK_LENGTH (180ll * NANOSECONDS_IN_SECOND) // 3 Minutes
|
||||||
|
#define BENCHMARK_ROTATION_INTERVAL ((long long int) (0.02f * NANOSECONDS_IN_SECOND))
|
||||||
|
#define BENCHMARK_ROTATION_AMOUNT 10
|
||||||
|
|
||||||
|
// Create/Start World
|
||||||
|
static void start_world(unsigned char *minecraft) {
|
||||||
|
// Log
|
||||||
|
INFO("%s", "Loading Benchmark");
|
||||||
|
|
||||||
|
// Specify Level Settings
|
||||||
|
LevelSettings settings;
|
||||||
|
settings.game_type = BENCHMARK_GAME_MODE;
|
||||||
|
settings.seed = BENCHMARK_SEED;
|
||||||
|
|
||||||
|
// Delete World If It Already Exists
|
||||||
|
unsigned char *level_source = (*Minecraft_getLevelSource)(minecraft);
|
||||||
|
unsigned char *level_source_vtable = *(unsigned char **) level_source;
|
||||||
|
ExternalFileLevelStorageSource_deleteLevel_t ExternalFileLevelStorageSource_deleteLevel = *(ExternalFileLevelStorageSource_deleteLevel_t *) (level_source_vtable + ExternalFileLevelStorageSource_deleteLevel_vtable_offset);
|
||||||
|
(*ExternalFileLevelStorageSource_deleteLevel)(level_source, BENCHMARK_WORLD_NAME);
|
||||||
|
|
||||||
|
// Select Level
|
||||||
|
(*Minecraft_selectLevel)(minecraft, BENCHMARK_WORLD_NAME, BENCHMARK_WORLD_NAME, settings);
|
||||||
|
|
||||||
|
// Open ProgressScreen
|
||||||
|
void *screen = ::operator new(PROGRESS_SCREEN_SIZE);
|
||||||
|
ALLOC_CHECK(screen);
|
||||||
|
screen = (*ProgressScreen)((unsigned char *) screen);
|
||||||
|
(*Minecraft_setScreen)(minecraft, (unsigned char *) screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track Frames
|
||||||
|
static unsigned long long int frames = 0;
|
||||||
|
HOOK(media_swap_buffers, void, ()) {
|
||||||
|
ensure_media_swap_buffers();
|
||||||
|
(*real_media_swap_buffers)();
|
||||||
|
frames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Time
|
||||||
|
static long long int get_time() {
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
long long int a = (long long int) ts.tv_nsec;
|
||||||
|
long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store Time When World Loaded
|
||||||
|
static int world_loaded = 0;
|
||||||
|
static long long int world_loaded_time;
|
||||||
|
static unsigned long long int world_loaded_frames;
|
||||||
|
|
||||||
|
// Runs Every Tick
|
||||||
|
static bool loaded = false;
|
||||||
|
static bool exit_requested = false;
|
||||||
|
static void Minecraft_update_injection(unsigned char *minecraft) {
|
||||||
|
// Create/Start World
|
||||||
|
if (!loaded) {
|
||||||
|
start_world(minecraft);
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect World Loaded
|
||||||
|
if (!world_loaded && (*Minecraft_isLevelGenerated)(minecraft)) {
|
||||||
|
world_loaded = 1;
|
||||||
|
world_loaded_time = get_time();
|
||||||
|
world_loaded_frames = frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run Benchmark
|
||||||
|
if (!exit_requested && world_loaded) {
|
||||||
|
// Get Time
|
||||||
|
long long int current_time = get_time() - world_loaded_time;
|
||||||
|
unsigned long long int current_frames = frames - world_loaded_frames;
|
||||||
|
|
||||||
|
// Rotate Player
|
||||||
|
static long long int rotate_point = BENCHMARK_ROTATION_INTERVAL;
|
||||||
|
if (current_time >= rotate_point) {
|
||||||
|
SDL_Event event;
|
||||||
|
event.type = SDL_MOUSEMOTION;
|
||||||
|
event.motion.x = 0;
|
||||||
|
event.motion.y = 0;
|
||||||
|
event.motion.xrel = BENCHMARK_ROTATION_AMOUNT;
|
||||||
|
event.motion.yrel = 0;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
// Reset Rotation Timer
|
||||||
|
rotate_point += BENCHMARK_ROTATION_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If Benchmark Is Over
|
||||||
|
if (current_time >= BENCHMARK_LENGTH) {
|
||||||
|
// Request Exit
|
||||||
|
compat_request_exit();
|
||||||
|
// Disable Special Behavior After Requesting Exit
|
||||||
|
exit_requested = true;
|
||||||
|
|
||||||
|
// Calculate FPS
|
||||||
|
static double frames_per_nanosecond = ((double) current_frames) / ((double) current_time);
|
||||||
|
static double frames_per_second = frames_per_nanosecond * NANOSECONDS_IN_SECOND;
|
||||||
|
INFO("Benchmark Completed After %llu Frames In %lld Nanoseconds, Average FPS: %f", current_frames, current_time, frames_per_second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init Benchmark
|
||||||
|
void init_benchmark() {
|
||||||
|
if (active) {
|
||||||
|
misc_run_on_update(Minecraft_update_injection);
|
||||||
|
// Disable Interaction
|
||||||
|
media_set_interactable(0);
|
||||||
|
// Disable V-Sync
|
||||||
|
media_disable_vsync();
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
#include "creative.h"
|
||||||
|
|
||||||
// Add Item To Inventory
|
// Add Item To Inventory
|
||||||
static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) {
|
static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) {
|
||||||
@ -51,10 +52,43 @@ static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(un
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check Restriction Status
|
||||||
|
static int is_restricted = 1;
|
||||||
|
int creative_is_restricted() {
|
||||||
|
return is_restricted;
|
||||||
|
}
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void init_creative() {
|
void init_creative() {
|
||||||
// Add Extra Items To Creative Inventory (Only Replace Specific Function Call)
|
// Add Extra Items To Creative Inventory (Only Replace Specific Function Call)
|
||||||
if (feature_has("Expand Creative Inventory", 0)) {
|
if (feature_has("Expand Creative Inventory", 0)) {
|
||||||
overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove Creative Restrictions (Opening Chests, Crafting, Etc)
|
||||||
|
if (feature_has("Remove Creative Restrictions", 0)) {
|
||||||
|
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||||
|
patch((void *) 0x1e3f4, nop_patch);
|
||||||
|
unsigned char slot_count_patch[4] = {0x18, 0x00, 0x00, 0xea}; // "b 0x27110"
|
||||||
|
patch((void *) 0x270a8, slot_count_patch);
|
||||||
|
patch((void *) 0x341c0, nop_patch);
|
||||||
|
patch((void *) 0x3adb4, nop_patch);
|
||||||
|
patch((void *) 0x3b374, nop_patch);
|
||||||
|
patch((void *) 0x43ee8, nop_patch);
|
||||||
|
patch((void *) 0x43f3c, nop_patch);
|
||||||
|
patch((void *) 0x43fd0, nop_patch);
|
||||||
|
patch((void *) 0x43fd8, nop_patch);
|
||||||
|
patch((void *) 0x8d080, nop_patch);
|
||||||
|
patch((void *) 0x8d090, nop_patch);
|
||||||
|
patch((void *) 0x91d48, nop_patch);
|
||||||
|
patch((void *) 0x92098, nop_patch);
|
||||||
|
unsigned char FillingContainer_removeResource_creative_check_patch[4] = {0x03, 0x00, 0x53, 0xe1}; // "cmp r3, r3"
|
||||||
|
patch((void *) 0x923c0, FillingContainer_removeResource_creative_check_patch);
|
||||||
|
patch((void *) 0x92828, nop_patch);
|
||||||
|
// Maximize Creative Inventory Stack Size
|
||||||
|
unsigned char maximize_stack_patch[4] = {0xff, 0xc0, 0xa0, 0xe3}; // "mov r12, 0xff"
|
||||||
|
patch((void *) 0x8e104, maximize_stack_patch);
|
||||||
|
// Disable Other Restrictions
|
||||||
|
is_restricted = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
11
mods/src/creative/creative.h
Normal file
11
mods/src/creative/creative.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int creative_is_restricted();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,7 +1,11 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
|
||||||
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
__attribute__((constructor)) static void init() {
|
__attribute__((constructor)) static void init() {
|
||||||
|
media_ensure_loaded();
|
||||||
run_tests();
|
run_tests();
|
||||||
|
init_version();
|
||||||
init_compat();
|
init_compat();
|
||||||
#ifdef MCPI_SERVER_MODE
|
#ifdef MCPI_SERVER_MODE
|
||||||
init_server();
|
init_server();
|
||||||
@ -22,5 +26,7 @@ __attribute__((constructor)) static void init() {
|
|||||||
init_options();
|
init_options();
|
||||||
init_chat();
|
init_chat();
|
||||||
init_home();
|
init_home();
|
||||||
init_version();
|
#if !defined(MCPI_SERVER_MODE) && !defined(MCPI_HEADLESS_MODE)
|
||||||
|
init_benchmark();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void run_tests();
|
void run_tests();
|
||||||
|
void init_version();
|
||||||
void init_compat();
|
void init_compat();
|
||||||
#ifdef MCPI_SERVER_MODE
|
#ifdef MCPI_SERVER_MODE
|
||||||
void init_server();
|
void init_server();
|
||||||
@ -25,7 +26,9 @@ void init_death();
|
|||||||
void init_options();
|
void init_options();
|
||||||
void init_chat();
|
void init_chat();
|
||||||
void init_home();
|
void init_home();
|
||||||
void init_version();
|
#if !defined(MCPI_SERVER_MODE) && !defined(MCPI_HEADLESS_MODE)
|
||||||
|
void init_benchmark();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
#include "../creative/creative.h"
|
||||||
|
|
||||||
// Enable Item Dropping
|
// Enable Item Dropping
|
||||||
static int enable_drop = 0;
|
static int enable_drop = 0;
|
||||||
@ -22,7 +23,7 @@ void input_drop(int drop_slot) {
|
|||||||
|
|
||||||
// Handle Drop Item Presses
|
// Handle Drop Item Presses
|
||||||
static void _handle_drop(unsigned char *minecraft) {
|
static void _handle_drop(unsigned char *minecraft) {
|
||||||
if (!(*Minecraft_isCreativeMode)(minecraft) && (drop_item_presses > 0 || drop_slot_pressed)) {
|
if ((!creative_is_restricted() || !(*Minecraft_isCreativeMode)(minecraft)) && (drop_item_presses > 0 || drop_slot_pressed)) {
|
||||||
// Get Player
|
// Get Player
|
||||||
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset);
|
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset);
|
||||||
if (player != NULL) {
|
if (player != NULL) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
#include "../creative/creative.h"
|
||||||
|
|
||||||
// Enable Miscellaneous Input Fixes
|
// Enable Miscellaneous Input Fixes
|
||||||
static int enable_misc = 0;
|
static int enable_misc = 0;
|
||||||
@ -59,9 +60,9 @@ static void _handle_mouse_grab(unsigned char *minecraft) {
|
|||||||
|
|
||||||
// Block UI Interaction When Mouse Is Locked
|
// Block UI Interaction When Mouse Is Locked
|
||||||
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned char *minecraft) {
|
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned char *minecraft) {
|
||||||
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
|
if (!enable_misc || SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
return (*Minecraft_isCreativeMode)(minecraft);
|
return creative_is_restricted() && (*Minecraft_isCreativeMode)(minecraft);
|
||||||
} else {
|
} else {
|
||||||
// Disable Item Drop Ticking
|
// Disable Item Drop Ticking
|
||||||
return 1;
|
return 1;
|
||||||
@ -82,12 +83,12 @@ void _init_misc() {
|
|||||||
if (enable_misc) {
|
if (enable_misc) {
|
||||||
// Fix OptionsScreen Ignoring The Back Button
|
// Fix OptionsScreen Ignoring The Back Button
|
||||||
patch_address(OptionsScreen_handleBackEvent_vtable_addr, (void *) OptionsScreen_handleBackEvent_injection);
|
patch_address(OptionsScreen_handleBackEvent_vtable_addr, (void *) OptionsScreen_handleBackEvent_injection);
|
||||||
|
|
||||||
// Disable Item Dropping Using The Cursor When Cursor Is Hidden
|
|
||||||
overwrite_call((void *) 0x27800, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection);
|
|
||||||
// Disable Opening Inventory Using The Cursor When Cursor Is Hidden
|
// Disable Opening Inventory Using The Cursor When Cursor Is Hidden
|
||||||
overwrite_calls((void *) Gui_handleClick, (void *) Gui_handleClick_injection);
|
overwrite_calls((void *) Gui_handleClick, (void *) Gui_handleClick_injection);
|
||||||
}
|
}
|
||||||
|
// 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_back);
|
||||||
input_run_on_tick(_handle_mouse_grab);
|
input_run_on_tick(_handle_mouse_grab);
|
||||||
}
|
}
|
||||||
|
108
mods/src/misc/logging.cpp
Normal file
108
mods/src/misc/logging.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
// Print Chat To Log
|
||||||
|
static bool Gui_addMessage_recursing = false;
|
||||||
|
static void Gui_addMessage_injection(unsigned char *gui, std::string const& text) {
|
||||||
|
// Sanitize Message
|
||||||
|
char *new_message = strdup(text.c_str());
|
||||||
|
ALLOC_CHECK(new_message);
|
||||||
|
sanitize_string(&new_message, -1, 1);
|
||||||
|
|
||||||
|
// Process Message
|
||||||
|
if (!Gui_addMessage_recursing) {
|
||||||
|
// Start Recursing
|
||||||
|
Gui_addMessage_recursing = true;
|
||||||
|
|
||||||
|
// Print Log Message
|
||||||
|
fprintf(stderr, "[CHAT]: %s\n", new_message);
|
||||||
|
|
||||||
|
// Call Original Method
|
||||||
|
(*Gui_addMessage)(gui, std::string(new_message));
|
||||||
|
|
||||||
|
// End Recursing
|
||||||
|
Gui_addMessage_recursing = false;
|
||||||
|
} else {
|
||||||
|
// Call Original Method
|
||||||
|
(*Gui_addMessage)(gui, std::string(new_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free
|
||||||
|
free(new_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If Two Percentages Are Different Enough To Be Logged
|
||||||
|
#define SIGNIFICANT_PROGRESS 5
|
||||||
|
static bool is_progress_difference_significant(int32_t new_val, int32_t old_val) {
|
||||||
|
if (new_val != old_val) {
|
||||||
|
if (new_val == -1 || old_val == -1) {
|
||||||
|
return true;
|
||||||
|
} else if (new_val == 0 || new_val == 100) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return new_val - old_val >= SIGNIFICANT_PROGRESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print Progress Reports
|
||||||
|
static int last_progress = -1;
|
||||||
|
static const char *last_message = NULL;
|
||||||
|
static void print_progress(unsigned char *minecraft) {
|
||||||
|
const char *message = (*Minecraft_getProgressMessage)(minecraft);
|
||||||
|
int32_t progress = *(int32_t *) (minecraft + Minecraft_progress_property_offset);
|
||||||
|
if ((*Minecraft_isLevelGenerated)(minecraft)) {
|
||||||
|
message = "Ready";
|
||||||
|
progress = -1;
|
||||||
|
}
|
||||||
|
if (message != NULL) {
|
||||||
|
bool message_different = message != last_message;
|
||||||
|
bool progress_significant = is_progress_difference_significant(progress, last_progress);
|
||||||
|
if (message_different || progress_significant) {
|
||||||
|
if (progress != -1) {
|
||||||
|
INFO("Status: %s: %i%%", message, progress);
|
||||||
|
} else {
|
||||||
|
INFO("Status: %s", message);
|
||||||
|
}
|
||||||
|
if (message_different) {
|
||||||
|
last_message = message;
|
||||||
|
}
|
||||||
|
if (progress_significant) {
|
||||||
|
last_progress = progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print Progress Reports Regularly
|
||||||
|
static void Minecraft_update_injection(unsigned char *minecraft) {
|
||||||
|
// Print Progress Reports
|
||||||
|
print_progress(minecraft);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log When Game Is Saved
|
||||||
|
void Level_saveLevelData_injection(unsigned char *level) {
|
||||||
|
// Print Log Message
|
||||||
|
INFO("%s", "Saving Game");
|
||||||
|
|
||||||
|
// Call Original Method
|
||||||
|
(*Level_saveLevelData)(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
void _init_misc_logging() {
|
||||||
|
// Print Chat To Log
|
||||||
|
overwrite_calls((void *) Gui_addMessage, (void *) Gui_addMessage_injection);
|
||||||
|
|
||||||
|
// Print Progress Reports
|
||||||
|
misc_run_on_update(Minecraft_update_injection);
|
||||||
|
|
||||||
|
// Print Log On Game Save
|
||||||
|
overwrite_calls((void *) Level_saveLevelData, (void *) Level_saveLevelData_injection);
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <GLES/gl.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <symbols/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
@ -12,23 +14,35 @@
|
|||||||
// Maximum Username Length
|
// Maximum Username Length
|
||||||
#define MAX_USERNAME_LENGTH 16
|
#define MAX_USERNAME_LENGTH 16
|
||||||
|
|
||||||
// Render Selected Item Text
|
// Additional GUI Rendering
|
||||||
static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t param_1, uint32_t param_2, uint32_t param_3, unsigned char *font) {
|
static int hide_chat_messages = 0;
|
||||||
|
static int render_selected_item_text = 0;
|
||||||
|
static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t y_offset, uint32_t max_messages, bool disable_fading, unsigned char *font) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
(*Gui_renderChatMessages)(gui, param_1, param_2, param_3, font);
|
if (!hide_chat_messages) {
|
||||||
|
(*Gui_renderChatMessages)(gui, y_offset, max_messages, disable_fading, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render Selected Item Text
|
||||||
|
if (render_selected_item_text) {
|
||||||
|
// Fix GL Mode
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
// Calculate Selected Item Text Scale
|
// Calculate Selected Item Text Scale
|
||||||
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset);
|
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset);
|
||||||
int32_t screen_width = *(int32_t *) (minecraft + Minecraft_screen_width_property_offset);
|
int32_t screen_width = *(int32_t *) (minecraft + Minecraft_screen_width_property_offset);
|
||||||
float scale = ((float) screen_width) * *InvGuiScale;
|
float scale = ((float) screen_width) * *InvGuiScale;
|
||||||
// Render Selected Item Text
|
// Render Selected Item Text
|
||||||
(*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, param_1 - 0x13);
|
(*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, y_offset - 0x13);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Reset Selected Item Text Timer On Slot Select
|
// Reset Selected Item Text Timer On Slot Select
|
||||||
static uint32_t reset_selected_item_text_timer = 0;
|
static uint32_t reset_selected_item_text_timer = 0;
|
||||||
static void Gui_tick_injection(unsigned char *gui) {
|
static void Gui_tick_injection(unsigned char *gui) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
(*Gui_tick)(gui);
|
(*Gui_tick)(gui);
|
||||||
|
|
||||||
// Handle Reset
|
// Handle Reset
|
||||||
|
if (render_selected_item_text) {
|
||||||
float *selected_item_text_timer = (float *) (gui + Gui_selected_item_text_timer_property_offset);
|
float *selected_item_text_timer = (float *) (gui + Gui_selected_item_text_timer_property_offset);
|
||||||
if (reset_selected_item_text_timer) {
|
if (reset_selected_item_text_timer) {
|
||||||
// Reset
|
// Reset
|
||||||
@ -36,13 +50,17 @@ static void Gui_tick_injection(unsigned char *gui) {
|
|||||||
reset_selected_item_text_timer = 0;
|
reset_selected_item_text_timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Trigger Reset Selected Item Text Timer On Slot Select
|
// Trigger Reset Selected Item Text Timer On Slot Select
|
||||||
static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slot) {
|
static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slot) {
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
(*Inventory_selectSlot)(inventory, slot);
|
(*Inventory_selectSlot)(inventory, slot);
|
||||||
|
|
||||||
// Trigger Reset Selected Item Text Timer
|
// Trigger Reset Selected Item Text Timer
|
||||||
|
if (render_selected_item_text) {
|
||||||
reset_selected_item_text_timer = 1;
|
reset_selected_item_text_timer = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sanitize Username
|
// Sanitize Username
|
||||||
static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit_stream) {
|
static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit_stream) {
|
||||||
@ -125,12 +143,12 @@ void init_misc() {
|
|||||||
patch((void *) 0x63c98, invalid_item_background_patch);
|
patch((void *) 0x63c98, invalid_item_background_patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix Selected Item Text
|
// Render Selected Item Text + Hide Chat Messages
|
||||||
if (feature_has("Render Selected Item Text", 0)) {
|
hide_chat_messages = feature_has("Hide Chat Messages", 0);
|
||||||
|
render_selected_item_text = feature_has("Render Selected Item Text", 0);
|
||||||
overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection);
|
overwrite_calls((void *) Gui_renderChatMessages, (void *) Gui_renderChatMessages_injection);
|
||||||
overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection);
|
overwrite_calls((void *) Gui_tick, (void *) Gui_tick_injection);
|
||||||
overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection);
|
overwrite_calls((void *) Inventory_selectSlot, (void *) Inventory_selectSlot_injection);
|
||||||
}
|
|
||||||
|
|
||||||
// Sanitize Username
|
// Sanitize Username
|
||||||
patch_address(LoginPacket_read_vtable_addr, (void *) LoginPacket_read_injection);
|
patch_address(LoginPacket_read_vtable_addr, (void *) LoginPacket_read_injection);
|
||||||
@ -144,6 +162,7 @@ void init_misc() {
|
|||||||
// Fix Bug Where RakNetInstance Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
// Fix Bug Where RakNetInstance Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||||
overwrite_calls((void *) RakNetInstance, (void *) RakNetInstance_injection);
|
overwrite_calls((void *) RakNetInstance, (void *) RakNetInstance_injection);
|
||||||
|
|
||||||
// Init C++
|
// Init C++ And Logging
|
||||||
_init_misc_cpp();
|
_init_misc_cpp();
|
||||||
|
_init_misc_logging();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -24,34 +25,24 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Chat To Log
|
// Run Functions On Input Tick
|
||||||
static bool Gui_addMessage_recursing = false;
|
static std::vector<misc_update_function_t> &get_misc_update_functions() {
|
||||||
static void Gui_addMessage_injection(unsigned char *gui, std::string const& text) {
|
static std::vector<misc_update_function_t> functions;
|
||||||
// Sanitize Message
|
return functions;
|
||||||
char *new_message = strdup(text.c_str());
|
}
|
||||||
ALLOC_CHECK(new_message);
|
void misc_run_on_update(misc_update_function_t function) {
|
||||||
sanitize_string(&new_message, -1, 1);
|
get_misc_update_functions().push_back(function);
|
||||||
|
|
||||||
// Process Message
|
|
||||||
if (!Gui_addMessage_recursing) {
|
|
||||||
// Start Recursing
|
|
||||||
Gui_addMessage_recursing = true;
|
|
||||||
|
|
||||||
// Print Log Message
|
|
||||||
fprintf(stderr, "[CHAT]: %s\n", new_message);
|
|
||||||
|
|
||||||
// Call Original Method
|
|
||||||
(*Gui_addMessage)(gui, std::string(new_message));
|
|
||||||
|
|
||||||
// End Recursing
|
|
||||||
Gui_addMessage_recursing = false;
|
|
||||||
} else {
|
|
||||||
// Call Original Method
|
|
||||||
(*Gui_addMessage)(gui, std::string(new_message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free
|
// Handle Custom Update Behavior
|
||||||
free(new_message);
|
static void Minecraft_update_injection(unsigned char *minecraft) {
|
||||||
|
// Call Original Method
|
||||||
|
(*Minecraft_update)(minecraft);
|
||||||
|
|
||||||
|
// Run Input Tick Functions
|
||||||
|
for (misc_update_function_t function : get_misc_update_functions()) {
|
||||||
|
(*function)(minecraft);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
@ -61,6 +52,6 @@ void _init_misc_cpp() {
|
|||||||
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Chat To Log
|
// Handle Custom Update Behavior
|
||||||
overwrite_calls((void *) Gui_addMessage, (void *) Gui_addMessage_injection);
|
overwrite_calls((void *) Minecraft_update, (void *) Minecraft_update_injection);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,13 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef void (*misc_update_function_t)(unsigned char *minecraft);
|
||||||
|
void misc_run_on_update(misc_update_function_t function);
|
||||||
|
|
||||||
|
void Level_saveLevelData_injection(unsigned char *level);
|
||||||
|
|
||||||
__attribute__((visibility("internal"))) void _init_misc_cpp();
|
__attribute__((visibility("internal"))) void _init_misc_cpp();
|
||||||
|
__attribute__((visibility("internal"))) void _init_misc_logging();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "server_properties.h"
|
#include "server_properties.h"
|
||||||
|
|
||||||
@ -23,9 +24,7 @@
|
|||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../home/home.h"
|
#include "../home/home.h"
|
||||||
#include "../compat/compat.h"
|
#include "../compat/compat.h"
|
||||||
#include "../version/version.h"
|
#include "../misc/misc.h"
|
||||||
|
|
||||||
#include <symbols/minecraft.h>
|
|
||||||
|
|
||||||
// --only-generate: Ony Generate World And Then Exit
|
// --only-generate: Ony Generate World And Then Exit
|
||||||
static bool only_generate = false;
|
static bool only_generate = false;
|
||||||
@ -66,17 +65,20 @@ static std::string get_world_name() {
|
|||||||
|
|
||||||
// Create/Start World
|
// Create/Start World
|
||||||
static void start_world(unsigned char *minecraft) {
|
static void start_world(unsigned char *minecraft) {
|
||||||
INFO("Starting Minecraft: Pi Edition: Dedicated Server (%s)", version_get());
|
// Get World Name
|
||||||
|
std::string world_name = get_world_name();
|
||||||
|
|
||||||
|
// Log
|
||||||
|
INFO("Loading World: %s", world_name.c_str());
|
||||||
|
|
||||||
// Specify Level Settings
|
// Specify Level Settings
|
||||||
LevelSettings settings;
|
LevelSettings settings;
|
||||||
settings.game_type = get_server_properties().get_int("game-mode", DEFAULT_GAME_MODE);;
|
settings.game_type = get_server_properties().get_int("game-mode", DEFAULT_GAME_MODE);
|
||||||
std::string seed_str = get_server_properties().get_string("seed", DEFAULT_SEED);
|
std::string seed_str = get_server_properties().get_string("seed", DEFAULT_SEED);
|
||||||
int32_t seed = seed_str.length() > 0 ? std::stoi(seed_str) : time(NULL);
|
int32_t seed = seed_str.length() > 0 ? std::stoi(seed_str) : time(NULL);
|
||||||
settings.seed = seed;
|
settings.seed = seed;
|
||||||
|
|
||||||
// Select Level
|
// Select Level
|
||||||
std::string world_name = get_world_name();
|
|
||||||
(*Minecraft_selectLevel)(minecraft, world_name, world_name, settings);
|
(*Minecraft_selectLevel)(minecraft, world_name, world_name, settings);
|
||||||
|
|
||||||
// Don't Open Port When Using --only-generate
|
// Don't Open Port When Using --only-generate
|
||||||
@ -94,51 +96,6 @@ static void start_world(unsigned char *minecraft) {
|
|||||||
(*Minecraft_setScreen)(minecraft, (unsigned char *) screen);
|
(*Minecraft_setScreen)(minecraft, (unsigned char *) screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check If Two Percentages Are Different Enough To Be Logged
|
|
||||||
#define SIGNIFICANT_PROGRESS 5
|
|
||||||
static bool is_progress_difference_significant(int32_t new_val, int32_t old_val) {
|
|
||||||
if (new_val != old_val) {
|
|
||||||
if (new_val == -1 || old_val == -1) {
|
|
||||||
return true;
|
|
||||||
} else if (new_val == 0 || new_val == 100) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return new_val - old_val >= SIGNIFICANT_PROGRESS;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print Progress Reports
|
|
||||||
static int last_progress = -1;
|
|
||||||
static const char *last_message = NULL;
|
|
||||||
static void print_progress(unsigned char *minecraft) {
|
|
||||||
const char *message = (*Minecraft_getProgressMessage)(minecraft);
|
|
||||||
int32_t progress = *(int32_t *) (minecraft + Minecraft_progress_property_offset);
|
|
||||||
if ((*Minecraft_isLevelGenerated)(minecraft)) {
|
|
||||||
message = "Ready";
|
|
||||||
progress = -1;
|
|
||||||
}
|
|
||||||
if (message != NULL) {
|
|
||||||
bool message_different = message != last_message;
|
|
||||||
bool progress_significant = is_progress_difference_significant(progress, last_progress);
|
|
||||||
if (message_different || progress_significant) {
|
|
||||||
if (progress != -1) {
|
|
||||||
INFO("Status: %s: %i%%", message, progress);
|
|
||||||
} else {
|
|
||||||
INFO("Status: %s", message);
|
|
||||||
}
|
|
||||||
if (message_different) {
|
|
||||||
last_message = message;
|
|
||||||
}
|
|
||||||
if (progress_significant) {
|
|
||||||
last_progress = progress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check If Running In Whitelist Mode
|
// Check If Running In Whitelist Mode
|
||||||
static bool is_whitelist() {
|
static bool is_whitelist() {
|
||||||
return get_server_properties().get_bool("whitelist", DEFAULT_WHITELIST);
|
return get_server_properties().get_bool("whitelist", DEFAULT_WHITELIST);
|
||||||
@ -244,15 +201,6 @@ static void list_callback(unsigned char *minecraft, std::string username, unsign
|
|||||||
INFO(" - %s (%s)", username.c_str(), get_player_ip(minecraft, player));
|
INFO(" - %s (%s)", username.c_str(), get_player_ip(minecraft, player));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log When Game Is Saved
|
|
||||||
static void Level_saveLevelData_injection(unsigned char *level) {
|
|
||||||
// Print Log Message
|
|
||||||
INFO("%s", "Saving Game");
|
|
||||||
|
|
||||||
// Call Original Method
|
|
||||||
(*Level_saveLevelData)(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Server Stop
|
// Handle Server Stop
|
||||||
static void handle_server_stop(unsigned char *minecraft) {
|
static void handle_server_stop(unsigned char *minecraft) {
|
||||||
if (compat_check_exit_requested()) {
|
if (compat_check_exit_requested()) {
|
||||||
@ -384,12 +332,6 @@ static void Minecraft_update_injection(unsigned char *minecraft) {
|
|||||||
only_generate = false;
|
only_generate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Progress Reports
|
|
||||||
print_progress(minecraft);
|
|
||||||
|
|
||||||
// Call Original Method
|
|
||||||
(*Minecraft_update)(minecraft);
|
|
||||||
|
|
||||||
// Handle Commands
|
// Handle Commands
|
||||||
handle_commands(minecraft);
|
handle_commands(minecraft);
|
||||||
|
|
||||||
@ -494,9 +436,9 @@ static void server_init() {
|
|||||||
// Open Properties File
|
// Open Properties File
|
||||||
std::string file(home_get());
|
std::string file(home_get());
|
||||||
file.append("/server.properties");
|
file.append("/server.properties");
|
||||||
|
|
||||||
std::ifstream properties_file(file);
|
std::ifstream properties_file(file);
|
||||||
|
|
||||||
|
// Check Properties File
|
||||||
if (!properties_file.good()) {
|
if (!properties_file.good()) {
|
||||||
// Write Defaults
|
// Write Defaults
|
||||||
std::ofstream properties_file_output(file);
|
std::ofstream properties_file_output(file);
|
||||||
@ -551,9 +493,7 @@ static void server_init() {
|
|||||||
unsigned char player_patch[4] = {0x00, 0x20, 0xa0, 0xe3}; // "mov r2, #0x0"
|
unsigned char player_patch[4] = {0x00, 0x20, 0xa0, 0xe3}; // "mov r2, #0x0"
|
||||||
patch((void *) 0x1685c, player_patch);
|
patch((void *) 0x1685c, player_patch);
|
||||||
// Start World On Launch
|
// Start World On Launch
|
||||||
overwrite_calls((void *) Minecraft_update, (void *) Minecraft_update_injection);
|
misc_run_on_update(Minecraft_update_injection);
|
||||||
// Print Log On Game Save
|
|
||||||
overwrite_calls((void *) Level_saveLevelData, (void *) Level_saveLevelData_injection);
|
|
||||||
// Set Max Players
|
// Set Max Players
|
||||||
unsigned char max_players_patch[4] = {get_max_players(), 0x30, 0xa0, 0xe3}; // "mov r3, #MAX_PLAYERS"
|
unsigned char max_players_patch[4] = {get_max_players(), 0x30, 0xa0, 0xe3}; // "mov r3, #MAX_PLAYERS"
|
||||||
patch((void *) 0x166d0, max_players_patch);
|
patch((void *) 0x166d0, max_players_patch);
|
||||||
|
@ -42,7 +42,7 @@ std::string _sound_get_source_file() {
|
|||||||
// Check If Sound Exists
|
// Check If Sound Exists
|
||||||
if (access(full_path, F_OK) == -1) {
|
if (access(full_path, F_OK) == -1) {
|
||||||
// Fail
|
// Fail
|
||||||
WARN("%s", "Audio Source File Doesn't Exists: " SOURCE_FILE_BASE);
|
WARN("%s", "Audio Source File Doesn't Exist: " SOURCE_FILE_BASE);
|
||||||
source.assign("");
|
source.assign("");
|
||||||
} else {
|
} else {
|
||||||
// Set
|
// Set
|
||||||
|
@ -31,4 +31,7 @@ void init_version() {
|
|||||||
overwrite((void *) Common_getGameVersionString, (void *) Common_getGameVersionString_injection);
|
overwrite((void *) Common_getGameVersionString, (void *) Common_getGameVersionString_injection);
|
||||||
// Normal GUI
|
// Normal GUI
|
||||||
patch_address((void *) minecraft_pi_version, version_get());
|
patch_address((void *) minecraft_pi_version, version_get());
|
||||||
|
|
||||||
|
// Log
|
||||||
|
INFO("Starting Minecraft: Pi Edition (%s)", version_get());
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,9 @@ static uint32_t Minecraft_handleBack_vtable_offset = 0x34;
|
|||||||
typedef unsigned char *(*Minecraft_getCreator_t)(unsigned char *minecraft);
|
typedef unsigned char *(*Minecraft_getCreator_t)(unsigned char *minecraft);
|
||||||
static Minecraft_getCreator_t Minecraft_getCreator = (Minecraft_getCreator_t) 0x17538;
|
static Minecraft_getCreator_t Minecraft_getCreator = (Minecraft_getCreator_t) 0x17538;
|
||||||
|
|
||||||
|
typedef unsigned char *(*Minecraft_getLevelSource_t)(unsigned char *minecraft);
|
||||||
|
static Minecraft_getLevelSource_t Minecraft_getLevelSource = (Minecraft_getLevelSource_t) 0x16e84;
|
||||||
|
|
||||||
static uint32_t Minecraft_screen_width_property_offset = 0x20; // int32_t
|
static uint32_t Minecraft_screen_width_property_offset = 0x20; // int32_t
|
||||||
static uint32_t Minecraft_network_handler_property_offset = 0x174; // NetEventCallback *
|
static uint32_t Minecraft_network_handler_property_offset = 0x174; // NetEventCallback *
|
||||||
static uint32_t Minecraft_rak_net_instance_property_offset = 0x170; // RakNetInstance *
|
static uint32_t Minecraft_rak_net_instance_property_offset = 0x170; // RakNetInstance *
|
||||||
@ -327,7 +330,7 @@ static Gui_handleClick_t Gui_handleClick = (Gui_handleClick_t) 0x2599c;
|
|||||||
typedef void (*Gui_renderOnSelectItemNameText_t)(unsigned char *gui, int32_t param_1, unsigned char *font, int32_t param_2);
|
typedef void (*Gui_renderOnSelectItemNameText_t)(unsigned char *gui, int32_t param_1, unsigned char *font, int32_t param_2);
|
||||||
static Gui_renderOnSelectItemNameText_t Gui_renderOnSelectItemNameText = (Gui_renderOnSelectItemNameText_t) 0x26aec;
|
static Gui_renderOnSelectItemNameText_t Gui_renderOnSelectItemNameText = (Gui_renderOnSelectItemNameText_t) 0x26aec;
|
||||||
|
|
||||||
typedef void (*Gui_renderChatMessages_t)(unsigned char *gui, int32_t param_1, uint32_t param_2, bool param_3, unsigned char *font);
|
typedef void (*Gui_renderChatMessages_t)(unsigned char *gui, int32_t y_offset, uint32_t max_messages, bool disable_fading, unsigned char *font);
|
||||||
static Gui_renderChatMessages_t Gui_renderChatMessages = (Gui_renderChatMessages_t) 0x273d8;
|
static Gui_renderChatMessages_t Gui_renderChatMessages = (Gui_renderChatMessages_t) 0x273d8;
|
||||||
|
|
||||||
static uint32_t Gui_minecraft_property_offset = 0x9f4; // Minecraft *
|
static uint32_t Gui_minecraft_property_offset = 0x9f4; // Minecraft *
|
||||||
@ -631,6 +634,11 @@ static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_read
|
|||||||
typedef void (*Minecraft_selectLevel_t)(unsigned char *minecraft, std::string const& level_dir, std::string const& level_name, LevelSettings const& vsettings);
|
typedef void (*Minecraft_selectLevel_t)(unsigned char *minecraft, std::string const& level_dir, std::string const& level_name, LevelSettings const& vsettings);
|
||||||
static Minecraft_selectLevel_t Minecraft_selectLevel = (Minecraft_selectLevel_t) 0x16f38;
|
static Minecraft_selectLevel_t Minecraft_selectLevel = (Minecraft_selectLevel_t) 0x16f38;
|
||||||
|
|
||||||
|
// ExternalFileLevelStorageSource
|
||||||
|
|
||||||
|
typedef void (*ExternalFileLevelStorageSource_deleteLevel_t)(unsigned char *external_file_level_storage_source, std::string const& level_name);
|
||||||
|
static uint32_t ExternalFileLevelStorageSource_deleteLevel_vtable_offset = 0x20;
|
||||||
|
|
||||||
// CommandServer
|
// CommandServer
|
||||||
|
|
||||||
typedef std::string (*CommandServer_parse_t)(unsigned char *command_server, struct ConnectedClient &client, std::string const& command);
|
typedef std::string (*CommandServer_parse_t)(unsigned char *command_server, struct ConnectedClient &client, std::string const& command);
|
||||||
|
Loading…
Reference in New Issue
Block a user