Remove GL Stubs From Headless Mode

This commit is contained in:
TheBrokenRail 2023-12-25 17:29:30 -05:00
parent 35c6adf94b
commit ef29e4fc0e
7 changed files with 62 additions and 195 deletions

View File

@ -14,6 +14,9 @@ void _overwrite_call(const char *file, int line, void *start, void *target);
void _overwrite_calls(const char *file, int line, void *start, void *target);
#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target);
void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *start, void *target);
#define overwrite_calls_within(from, to, start, target) _overwrite_calls(__FILE__, __LINE__, from, to, start, target);
void *extract_from_bl_instruction(unsigned char *from);
void _overwrite(const char *file, int line, void *start, void *target);

View File

@ -40,6 +40,26 @@ static uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruct
}
// Run For Every .text Section
static int _overwrite_calls_within_internal(const char *file, int line, void *from, void *to, void *target, void *replacement) {
int found = 0;
for (uint32_t i = (uint32_t) from; i < (uint32_t) to; i = i + 4) {
unsigned char *addr = (unsigned char *) i;
int use_b_instruction = addr[3] == B_INSTRUCTION;
// Check If Instruction is B Or BL
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
unsigned char *check_instruction_array = (unsigned char *) &check_instruction;
// Check If Instruction Calls Target
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
// Patch Instruction
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
_patch(file, line, addr, (unsigned char *) &new_instruction);
found++;
}
}
}
return found;
}
struct overwrite_data {
const char *file;
int line;
@ -50,23 +70,7 @@ struct overwrite_data {
static void overwrite_calls_callback(ElfW(Addr) section_addr, ElfW(Word) size, void *data) {
struct overwrite_data *args = (struct overwrite_data *) data;
void *section = (void *) section_addr;
for (uint32_t i = 0; i < size; i = i + 4) {
unsigned char *addr = ((unsigned char *) section) + i;
int use_b_instruction = addr[3] == B_INSTRUCTION;
// Check If Instruction is B Or BL
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
uint32_t check_instruction = generate_bl_instruction(addr, args->target, use_b_instruction);
unsigned char *check_instruction_array = (unsigned char *) &check_instruction;
// Check If Instruction Calls Target
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
// Patch Instruction
uint32_t new_instruction = generate_bl_instruction(addr, args->replacement, use_b_instruction);
_patch(args->file, args->line, addr, (unsigned char *) &new_instruction);
args->found++;
}
}
}
args->found += _overwrite_calls_within_internal(args->file, args->line, section, (void *) (section_addr + size), args->target, args->replacement);
}
// Limit To 512 overwrite_calls() Uses
@ -139,6 +143,20 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) {
ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) start);
}
}
void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *target, void *replacement) {
// Add New Target To Code Block
update_code_block(replacement);
// Patch
int found = _overwrite_calls_within_internal(file, line, from, to, target, code_block);
// Check
if (found < 1) {
ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) target);
}
// Increment Code Block Position
increment_code_block();
}
// Extract Target Address From B(L) Instruction
void *extract_from_bl_instruction(unsigned char *from) {

View File

@ -1,7 +1,9 @@
project(media-layer-core)
# OpenGL
add_subdirectory(gles)
if(NOT MCPI_HEADLESS_MODE)
add_subdirectory(gles)
endif()
# Configuration
set(CORE_SRC src/base.cpp src/media.c $<TARGET_OBJECTS:media-layer-extras>) # SDL Re-Implementation Using GLFW
@ -21,10 +23,10 @@ endif()
install(TARGETS media-layer-core-real DESTINATION "${MCPI_LIB_DIR}")
# Link
target_link_libraries(media-layer-core-real PUBLIC media-layer-headers PUBLIC reborn-util PUBLIC GLESv1_CM PUBLIC dl)
target_link_libraries(media-layer-core-real PUBLIC media-layer-headers PUBLIC reborn-util PUBLIC dl)
if(NOT MCPI_HEADLESS_MODE)
# OpenAL
find_library(OPENAL_LIBRARY NAMES openal REQUIRED)
# Link
target_link_libraries(media-layer-core-real PRIVATE "${OPENAL_LIBRARY}" PRIVATE m PRIVATE glfw PRIVATE LIB_LIEF)
target_link_libraries(media-layer-core-real PRIVATE "${OPENAL_LIBRARY}" PRIVATE m PRIVATE glfw PUBLIC GLESv1_CM PRIVATE LIB_LIEF)
endif()

View File

@ -1,11 +1,7 @@
project(media-layer-gles)
# Build
if(MCPI_HEADLESS_MODE)
# Stubs For Headless Mode
add_library(GLESv1_CM OBJECT src/stubs.c)
target_link_libraries(GLESv1_CM PRIVATE media-layer-headers)
elseif(MCPI_USE_GLES1_COMPATIBILITY_LAYER)
if(MCPI_USE_GLES1_COMPATIBILITY_LAYER)
# GLESv1_CM Compatibility Layer
add_library(GLESv1_CM INTERFACE)
target_link_libraries(GLESv1_CM INTERFACE gles-compatibility-layer)

View File

@ -1,170 +0,0 @@
#include <GLES/gl.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void glFogfv(GLenum pname, const GLfloat *params) {
}
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
}
void glLineWidth(GLfloat width) {
}
void glBlendFunc(GLenum sfactor, GLenum dfactor) {
}
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
}
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
}
void glClear(GLbitfield mask) {
}
void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
}
void glFogx(GLenum pname, GLfixed param) {
}
void glFogf(GLenum pname, GLfloat param) {
}
void glMatrixMode(GLenum mode) {
}
void glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
}
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
}
void glTexParameteri(GLenum target, GLenum pname, GLint param) {
}
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
}
void glEnable(GLenum cap) {
}
void glEnableClientState(GLenum array) {
}
void glPolygonOffset(GLfloat factor, GLfloat units) {
}
void glDisableClientState(GLenum array) {
}
void glDepthRangef(GLclampf near, GLclampf far) {
}
void glDepthFunc(GLenum func) {
}
static GLuint current_buffer = 0;
void glBindBuffer(GLenum target, GLuint buffer) {
if (target == GL_ARRAY_BUFFER) {
current_buffer = buffer;
}
}
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
}
void glPopMatrix() {
}
void glLoadIdentity() {
}
void glScalef(GLfloat x, GLfloat y, GLfloat z) {
}
void glPushMatrix() {
}
void glDepthMask(GLboolean flag) {
}
void glHint(GLenum target, GLenum mode) {
}
void glMultMatrixf(const GLfloat *m) {
}
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
}
void glDeleteBuffers(GLsizei n, const GLuint *buffers) {
}
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
}
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
}
void glGenTextures(GLsizei n, GLuint *textures) {
static int i = 1;
for (int j = 0; j < n; j++) {
textures[j] = i++;
}
}
void glDeleteTextures(GLsizei n, const GLuint *textures) {
}
void glAlphaFunc(GLenum func, GLclampf ref) {
}
void glGetFloatv(GLenum pname, GLfloat *params) {
switch (pname) {
case GL_MODELVIEW_MATRIX:
case GL_PROJECTION_MATRIX: {
params[0] = 1;
params[1] = 0;
params[2] = 0;
params[3] = 0;
params[4] = 0;
params[5] = 1;
params[6] = 0;
params[7] = 0;
params[8] = 0;
params[9] = 0;
params[10] = 1;
params[11] = 0;
params[12] = 0;
params[13] = 0;
params[14] = 0;
params[15] = 1;
break;
}
default: {
params[0] = 0;
break;
}
}
}
static GLuint current_texture = 0;
void glBindTexture(GLenum target, GLuint texture) {
if (target == GL_TEXTURE_2D) {
current_texture = texture;
}
}
void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
}
void glShadeModel(GLenum mode) {
}
void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) {
}
void glDisable(GLenum cap) {
}
void glCullFace(GLenum mode) {
}
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
}
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
}
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
}
GLboolean glIsEnabled(GLenum cap) {
return GL_FALSE;
}
void glGetIntegerv(GLenum pname, GLint *data) {
switch (pname) {
case GL_TEXTURE_BINDING_2D: {
data[0] = current_texture;
break;
}
case GL_ARRAY_BUFFER_BINDING: {
data[0] = current_buffer;
break;
}
case GL_UNPACK_ALIGNMENT: {
data[0] = 1;
break;
}
default: {
data[0] = 0;
break;
}
}
}
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data) {
}
void glGenBuffers(GLsizei n, GLuint *buffers) {
static int i = 1;
for (int j = 0; j < n; j++) {
buffers[j] = i++;
}
}
#pragma GCC diagnostic pop

View File

@ -301,10 +301,12 @@ int32_t misc_get_real_selected_slot(unsigned char *player) {
return selected_slot;
}
#ifndef MCPI_HEADLESS_MODE
// Properly Generate Buffers
static void anGenBuffers_injection(int32_t count, uint32_t *buffers) {
glGenBuffers(count, buffers);
}
#endif
// Fix Graphics Bug When Switching To First-Person While Sneaking
static void HumanoidMobRenderer_render_injection(unsigned char *model_renderer, unsigned char *entity, float param_2, float param_3, float param_4, float param_5, float param_6) {
@ -554,6 +556,9 @@ void init_misc() {
#ifdef MCPI_HEADLESS_MODE
// Don't Render Game In Headless Mode
overwrite_calls((void *) GameRenderer_render, (void *) nop);
overwrite_calls((void *) NinecraftApp_initGLStates, (void *) nop);
overwrite_calls((void *) Gui_onConfigChanged, (void *) nop);
overwrite_calls((void *) LevelRenderer_generateSky, (void *) nop);
#else
// Improved Cursor Rendering
if (feature_has("Improved Cursor Rendering", server_disabled)) {
@ -580,8 +585,10 @@ void init_misc() {
overwrite_calls((void *) sleepMs, (void *) nop);
}
#ifndef MCPI_HEADLESS_MODE
// Properly Generate Buffers
overwrite((void *) anGenBuffers, (void *) anGenBuffers_injection);
#endif
// Fix Graphics Bug When Switching To First-Person While Sneaking
patch_address(PlayerRenderer_render_vtable_addr, (void *) HumanoidMobRenderer_render_injection);

View File

@ -170,6 +170,11 @@ static TileRenderer_tesselateBlockInWorld_t TileRenderer_tesselateBlockInWorld =
typedef void (*GameMode_releaseUsingItem_t)(unsigned char *game_mode, unsigned char *player);
static uint32_t GameMode_releaseUsingItem_vtable_offset = 0x5c;
// NinecraftApp
typedef void (*NinecraftApp_initGLStates_t)(unsigned char *minecraft);
static NinecraftApp_initGLStates_t NinecraftApp_initGLStates = (NinecraftApp_initGLStates_t) 0x148c8;
// Minecraft
typedef void (*Minecraft_init_t)(unsigned char *minecraft);
@ -506,6 +511,9 @@ static Gui_renderToolBar_t Gui_renderToolBar = (Gui_renderToolBar_t) 0x26c30;
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;
typedef void (*Gui_onConfigChanged_t)(unsigned char *gui, unsigned char *config);
static Gui_onConfigChanged_t Gui_onConfigChanged = (Gui_onConfigChanged_t) 0x255bc;
static uint32_t Gui_minecraft_property_offset = 0x9f4; // Minecraft *
static uint32_t Gui_selected_item_text_timer_property_offset = 0x9fc; // float
@ -563,6 +571,9 @@ static LevelRenderer_render_t LevelRenderer_render = (LevelRenderer_render_t) 0x
typedef void (*LevelRenderer_renderDebug_t)(unsigned char *level_renderer, struct AABB *aabb, float delta);
static LevelRenderer_renderDebug_t LevelRenderer_renderDebug = (LevelRenderer_renderDebug_t) 0x4d310;
typedef void (*LevelRenderer_generateSky_t)(unsigned char *level_renderer);
static LevelRenderer_generateSky_t LevelRenderer_generateSky = (LevelRenderer_generateSky_t) 0x4d0d4;
static uint32_t LevelRenderer_minecraft_property_offset = 0x4; // Minecraft *
// PerfRenderer