minecraft-pi-reborn/launcher/src/launcher.c

157 lines
5.0 KiB
C
Raw Normal View History

2020-09-25 16:43:53 +00:00
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
2021-02-09 03:52:39 +00:00
#include <sys/stat.h>
2020-09-25 16:43:53 +00:00
2021-02-21 19:53:17 +00:00
// Check String Prefix/Suffix
2020-09-25 16:43:53 +00:00
static int starts_with(const char *s, const char *t) {
return strncmp(s, t, strlen(t)) == 0;
}
static int ends_with(const char *s, const char *t) {
size_t slen = strlen(s);
size_t tlen = strlen(t);
if (tlen > slen) return 1;
return strcmp(s + slen - tlen, t) == 0;
}
2021-02-21 19:53:17 +00:00
// Set Environmental Variable
2020-10-03 20:18:53 +00:00
static void trim(char *value) {
// Remove Trailing Colon
2020-09-25 18:52:28 +00:00
int length = strlen(value);
if (value[length - 1] == ':') {
value[length - 1] = '\0';
}
2020-10-03 20:18:53 +00:00
}
static void set_and_print_env(char *name, char *value) {
2021-02-21 19:53:17 +00:00
// Set Variable With No Trailing Colon
2020-10-03 20:18:53 +00:00
trim(value);
2020-09-25 18:52:28 +00:00
2020-09-25 16:43:53 +00:00
fprintf(stderr, "Set %s = %s\n", name, value);
setenv(name, value, 1);
}
2021-02-21 19:53:17 +00:00
// Get Environmental Variable
2020-09-25 16:43:53 +00:00
static char *get_env_safe(const char *name) {
2020-10-03 20:18:53 +00:00
// Get Variable Or Blank String If Not Set
2020-09-25 16:43:53 +00:00
char *ret = getenv(name);
return ret != NULL ? ret : "";
}
2021-02-21 19:53:17 +00:00
// Get All SO Files In Folder
static void load(char **ld_preload, char *folder) {
int folder_name_length = strlen(folder);
2021-02-21 19:53:17 +00:00
// Retry Until Successful
while (1) {
2021-02-21 19:53:17 +00:00
// Open Folder
DIR *dp = opendir(folder);
if (dp != NULL) {
2021-02-21 19:53:17 +00:00
// Loop Through Folder
struct dirent *entry = NULL;
errno = 0;
while (1) {
entry = readdir(dp);
if (entry != NULL) {
2020-10-03 20:18:53 +00:00
// Check If File Is A Shared Library
if (entry->d_type == DT_REG && starts_with(entry->d_name, "lib") && ends_with(entry->d_name, ".so")) {
int name_length = strlen(entry->d_name);
int total_length = folder_name_length + name_length;
char name[total_length + 1];
for (int i = 0; i < folder_name_length; i++) {
name[i] = folder[i];
}
for (int i = 0; i < name_length; i++) {
name[folder_name_length + i] = entry->d_name[i];
}
name[total_length] = '\0';
2020-10-03 20:18:53 +00:00
// Add To LD_PRELOAD
asprintf(ld_preload, "%s:%s", name, *ld_preload);
}
} else if (errno != 0) {
2020-10-03 20:18:53 +00:00
// Error Reading Contents Of Folder
2021-02-09 03:52:39 +00:00
fprintf(stderr, "Error Reading Directory: %s: %s\n", folder, strerror(errno));
2020-11-19 19:52:41 +00:00
exit(EXIT_FAILURE);
} else {
2021-02-21 19:53:17 +00:00
// Done!
break;
}
}
2021-02-21 19:53:17 +00:00
// Close Folder
closedir(dp);
2020-10-03 20:18:53 +00:00
2021-02-21 19:53:17 +00:00
// Exit Function
return;
} else if (errno == ENOENT) {
2020-10-03 20:18:53 +00:00
// Folder Doesn't Exists, Attempt Creation
2021-02-09 03:52:39 +00:00
int ret = mkdir(folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
2021-02-09 03:52:39 +00:00
// Unable To Create Folder
fprintf(stderr, "Error Creating Directory: %s: %s\n", folder, strerror(errno));
exit(EXIT_FAILURE);
}
2021-02-21 19:53:17 +00:00
// Continue Retrying
} else {
2020-10-03 20:18:53 +00:00
// Unable To Open Folder
2021-02-09 03:52:39 +00:00
fprintf(stderr, "Error Opening Directory: %s: %s\n", folder, strerror(errno));
2020-11-19 19:52:41 +00:00
exit(EXIT_FAILURE);
}
}
}
2020-09-25 16:43:53 +00:00
int main(__attribute__((unused)) int argc, char *argv[]) {
fprintf(stderr, "Configuring Game...\n");
2021-02-09 03:52:39 +00:00
// Minecraft Folder
char *minecraft_folder = NULL;
2021-02-10 20:47:38 +00:00
asprintf(&minecraft_folder, "%s/.minecraft-pi", getenv("HOME"));
2021-02-09 03:52:39 +00:00
{
// Check Minecraft Folder
struct stat obj;
if (stat(minecraft_folder, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
// Create Minecraft Folder
int ret = mkdir(minecraft_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
fprintf(stderr, "Error Creating Directory: %s: %s\n", minecraft_folder, strerror(errno));
exit(EXIT_FAILURE);
}
}
}
free(minecraft_folder);
2020-10-04 20:45:00 +00:00
2021-02-21 19:53:17 +00:00
// Configure LD_LIBRARY_PATH
char *ld_path;
asprintf(&ld_path, "./lib:/usr/arm-linux-gnueabihf/lib:%s", get_env_safe("LD_LIBRARY_PATH"));
set_and_print_env("LD_LIBRARY_PATH", ld_path);
free(ld_path);
2020-10-03 20:18:53 +00:00
// Start Configuring LD_PRELOAD
2020-09-25 16:43:53 +00:00
char *ld_preload = NULL;
asprintf(&ld_preload, "%s", get_env_safe("LD_PRELOAD"));
2020-10-03 20:18:53 +00:00
// Load Mods From ./mods
2021-02-21 19:53:17 +00:00
load(&ld_preload, "./mods/");
2021-02-10 20:47:38 +00:00
// Loads Mods From ~/.minecraft-pi/mods
char *home_mods = NULL;
2021-02-10 20:47:38 +00:00
asprintf(&home_mods, "%s/.minecraft-pi/mods/", getenv("HOME"));
2021-02-21 19:53:17 +00:00
load(&ld_preload, home_mods);
free(home_mods);
2021-01-27 21:26:19 +00:00
2020-10-03 20:18:53 +00:00
// Set LD_PRELOAD
2020-09-25 16:43:53 +00:00
set_and_print_env("LD_PRELOAD", ld_preload);
free(ld_preload);
2020-10-03 20:18:53 +00:00
// Start Game
2020-09-25 16:43:53 +00:00
fprintf(stderr, "Starting Game...\n");
return execve("./minecraft-pi", argv, environ);
}