diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 1cc6c24..cd2ca98 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -22,6 +22,9 @@ target_link_libraries(screenshot GLESv1_CM freeimage) add_library(extra SHARED src/extra.c src/extra.cpp src/cxx11_util.cpp) target_link_libraries(extra core dl server screenshot) +add_library(override SHARED src/override.c) +target_link_libraries(override dl) + find_package(glfw3 3.3 REQUIRED) add_library(compat SHARED src/compat.c) diff --git a/mods/src/override.c b/mods/src/override.c new file mode 100644 index 0000000..48590ae --- /dev/null +++ b/mods/src/override.c @@ -0,0 +1,70 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include +#include + +#include + +static int starts_with(const char *s, const char *t) { + return strncmp(s, t, strlen(t)) == 0; +} + +static char *get_override_path(const char *filename) { + // Get Asset Override Path + char *overrides = NULL; + asprintf(&overrides, "%s/.minecraft/overrides", getenv("HOME")); + // Get data Path + char *data = NULL; + char *cwd = getcwd(NULL, 0); + asprintf(&data, "%s/data", cwd); + free(cwd); + // Get Full Path + char *new_path = NULL; + char *full_path = realpath(filename, NULL); + if (full_path != NULL) { + if (starts_with(full_path, data)) { + asprintf(&new_path, "%s%s", overrides, &full_path[strlen(data)]); + if (access(new_path, F_OK) == -1) { + free(new_path); + new_path = NULL; + } + } + free(full_path); + } + // Free Variables + free(overrides); + free(data); + // Return + return new_path; +} + +HOOK(fopen, FILE *, (const char *filename, const char *mode)) { + char *new_path = get_override_path(filename); + // Open File + ensure_fopen(); + FILE *file = (*real_fopen)(new_path != NULL ? new_path : filename, mode); + // Free Data + if (new_path != NULL) { + free(new_path); + } + // Return File + return file; +} + +HOOK(fopen64, FILE *, (const char *filename, const char *mode)) { + char *new_path = get_override_path(filename); + // Open File + ensure_fopen64(); + FILE *file = (*real_fopen64)(new_path != NULL ? new_path : filename, mode); + // Free Data + if (new_path != NULL) { + free(new_path); + } + // Return File + return file; +} \ No newline at end of file