diff --git a/Dockerfile.client b/Dockerfile.client index 47d642b..b239150 100644 --- a/Dockerfile.client +++ b/Dockerfile.client @@ -5,7 +5,7 @@ ENV DEBIAN_FRONTEND noninteractive RUN \ # Install Runtime Dependencies apt-get update && \ - apt-get install -y --no-install-recommends tini libgles1 libx11-6 libsdl1.2debian zlib1g libfreeimage3 libglfw3 xinput libxfixes3 && \ + apt-get install -y --no-install-recommends tini libgles1 libx11-6 libsdl1.2debian zlib1g libfreeimage3 libglfw3 xinput libxfixes3 gosu && \ rm -rf /var/lib/apt/lists/* # Compile Environment @@ -51,4 +51,4 @@ COPY --from=build /app/minecraft-pi /app/minecraft-pi WORKDIR /app/minecraft-pi ENTRYPOINT ["/usr/bin/tini", "--"] -CMD ["./launcher"] +CMD ["./run.sh"] diff --git a/debian/client/common/usr/bin/minecraft-pi b/debian/client/common/usr/bin/minecraft-pi index 47538f7..1c076bf 100755 --- a/debian/client/common/usr/bin/minecraft-pi +++ b/debian/client/common/usr/bin/minecraft-pi @@ -39,7 +39,12 @@ xhost local:root # Prepare Environment export USER_HOME="${HOME}" -export USER_UID="$(id -u):$(getent group video | cut -d : -f 3)" +export USER_UID="$(id -u)" +export USER_GID="$(id -g)" +get_gid() { + echo "$(getent group "$1" | cut -d : -f 3)" +} +export USER_OTHER_GIDS="$(get_gid video) $(get_gid render)" # Run set +e diff --git a/debian/client/native/usr/share/minecraft-pi/client/docker-compose.yml b/debian/client/native/usr/share/minecraft-pi/client/docker-compose.yml index ec2ac8a..f68c27f 100644 --- a/debian/client/native/usr/share/minecraft-pi/client/docker-compose.yml +++ b/debian/client/native/usr/share/minecraft-pi/client/docker-compose.yml @@ -3,7 +3,6 @@ services: minecraft-pi: image: 'thebrokenrail/minecraft-pi-reborn:client' network_mode: 'host' - user: '${USER_UID}' volumes: - /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static - '/tmp/.X11-unix:/tmp/.X11-unix' @@ -11,9 +10,11 @@ services: devices: - '/dev/dri:/dev/dri' environment: - - 'HOME=/home' - 'DISPLAY=unix${DISPLAY}' - 'MCPI_FEATURES=${MCPI_FEATURES}' - 'MCPI_RENDER_DISTANCE=${MCPI_RENDER_DISTANCE}' - 'MCPI_USERNAME=${MCPI_USERNAME}' - 'MCPI_MODE=native' + - 'USER_UID=${USER_UID}' + - 'USER_GID=${USER_GID}' + - 'USER_OTHER_GIDS=${USER_OTHER_GIDS}' diff --git a/debian/client/virgl/usr/lib/minecraft-pi/run.sh b/debian/client/virgl/usr/lib/minecraft-pi/run.sh index 8caeb8c..685a824 100755 --- a/debian/client/virgl/usr/lib/minecraft-pi/run.sh +++ b/debian/client/virgl/usr/lib/minecraft-pi/run.sh @@ -13,6 +13,6 @@ RET=$? set -e # Kill VirGL -kill ${VIRGL_PID} +kill ${VIRGL_PID} > /dev/null 2>&1 exit ${RET} \ No newline at end of file diff --git a/debian/client/virgl/usr/share/minecraft-pi/client/docker-compose.yml b/debian/client/virgl/usr/share/minecraft-pi/client/docker-compose.yml index d84d328..90a81bb 100644 --- a/debian/client/virgl/usr/share/minecraft-pi/client/docker-compose.yml +++ b/debian/client/virgl/usr/share/minecraft-pi/client/docker-compose.yml @@ -3,16 +3,17 @@ services: minecraft-pi: image: 'thebrokenrail/minecraft-pi-reborn:client' network_mode: 'host' - user: '${USER_UID}' volumes: - /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static - '/tmp/.X11-unix:/tmp/.X11-unix' - '/tmp/.virgl_test:/tmp/.virgl_test' - '${USER_HOME}/.minecraft-pi:/home/.minecraft' environment: - - 'HOME=/home' - 'DISPLAY=unix${DISPLAY}' - 'MCPI_FEATURES=${MCPI_FEATURES}' - 'MCPI_RENDER_DISTANCE=${MCPI_RENDER_DISTANCE}' - 'MCPI_USERNAME=${MCPI_USERNAME}' - 'MCPI_MODE=virgl' + - 'USER_UID=${USER_UID}' + - 'USER_GID=${USER_GID}' + - 'USER_OTHER_GIDS=${USER_OTHER_GIDS}' diff --git a/debian/server/usr/bin/minecraft-pi-server b/debian/server/usr/bin/minecraft-pi-server index 4f0bfd9..3f504f6 100755 --- a/debian/server/usr/bin/minecraft-pi-server +++ b/debian/server/usr/bin/minecraft-pi-server @@ -4,7 +4,8 @@ set -e # Prepare Environment export MCPI_ROOT="${PWD}" -export USER_UID="${UID}" +export USER_UID="$(id -u)" +export USER_GID="$(id -g)" # Launch Minecraft DOCKER_COMPOSE_YML='/usr/share/minecraft-pi/server/docker-compose.yml' diff --git a/debian/server/usr/share/minecraft-pi/server/docker-compose.yml b/debian/server/usr/share/minecraft-pi/server/docker-compose.yml index 6705ae8..0c5b5b0 100644 --- a/debian/server/usr/share/minecraft-pi/server/docker-compose.yml +++ b/debian/server/usr/share/minecraft-pi/server/docker-compose.yml @@ -3,9 +3,9 @@ services: minecraft-pi-server: image: 'thebrokenrail/minecraft-pi-reborn:server' network_mode: 'host' - user: '${USER_UID}' volumes: - /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static - '${MCPI_ROOT}:/home/.minecraft' environment: - - 'HOME=/home' + - 'USER_UID=${USER_UID}' + - 'USER_GID=${USER_GID}' diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 5a4b6d4..bc47c53 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -8,3 +8,4 @@ add_executable(launcher src/launcher.c) # Install install(TARGETS launcher DESTINATION /) +install(PROGRAMS src/run.sh DESTINATION /) \ No newline at end of file diff --git a/launcher/src/launcher.c b/launcher/src/launcher.c index 6e78e76..c5e3747 100644 --- a/launcher/src/launcher.c +++ b/launcher/src/launcher.c @@ -7,6 +7,7 @@ #include #include #include +#include static int starts_with(const char *s, const char *t) { return strncmp(s, t, strlen(t)) == 0; @@ -71,7 +72,7 @@ static void load(char **ld_path, char **ld_preload, char *folder) { } } else if (errno != 0) { // Error Reading Contents Of Folder - fprintf(stderr, "Error Reading Directory: %s\n", strerror(errno)); + fprintf(stderr, "Error Reading Directory: %s: %s\n", folder, strerror(errno)); exit(EXIT_FAILURE); } else { break; @@ -85,15 +86,15 @@ static void load(char **ld_path, char **ld_preload, char *folder) { return; } else if (errno == ENOENT) { // Folder Doesn't Exists, Attempt Creation - char *cmd = NULL; - asprintf(&cmd, "mkdir -p %s", folder); - int ret = system(cmd); + int ret = mkdir(folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if (ret != 0) { - exit(ret); + // Unable To Create Folder + fprintf(stderr, "Error Creating Directory: %s: %s\n", folder, strerror(errno)); + exit(EXIT_FAILURE); } } else { // Unable To Open Folder - fprintf(stderr, "Error Opening Directory: %s\n", strerror(errno)); + fprintf(stderr, "Error Opening Directory: %s: %s\n", folder, strerror(errno)); exit(EXIT_FAILURE); } } @@ -102,11 +103,23 @@ static void load(char **ld_path, char **ld_preload, char *folder) { int main(__attribute__((unused)) int argc, char *argv[]) { fprintf(stderr, "Configuring Game...\n"); - // Create Screenshots Folder - char *screenshots_cmd = NULL; - asprintf(&screenshots_cmd, "mkdir -p %s/.minecraft/screenshots", getenv("HOME")); - system(screenshots_cmd); - free(screenshots_cmd); + // Minecraft Folder + char *minecraft_folder = NULL; + asprintf(&minecraft_folder, "%s/.minecraft", getenv("HOME")); + { + // 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); char *ld_path = NULL; diff --git a/launcher/src/run.sh b/launcher/src/run.sh new file mode 100755 index 0000000..85d3353 --- /dev/null +++ b/launcher/src/run.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +set -e + +# Check Root +if [ ! "$(id -u)" = '0' ]; then + echo 'Must Run As Root' 1>&2 + exit 1 +fi + +# Create User Groups +if [ -z "${USER_GID+x}" ]; then + USER_GID='1000' +fi +groupadd --force --gid "${USER_GID}" user + +# Create User +if [ -z "${USER_UID+x}" ]; then + USER_UID='1000' +fi +useradd --shell /bin/sh --home-dir /home --no-create-home --uid "${USER_UID}" --gid "${USER_GID}" user + +# Add Other Groups +if [ ! -z "${USER_OTHER_GIDS+x}" ]; then + for gid in ${USER_OTHER_GIDS}; do + groupadd --force --gid "${gid}" "group-${gid}" + usermod -aG "${gid}" user + done +fi + +# Start +exec gosu "${USER_UID}" ./launcher \ No newline at end of file diff --git a/mods/src/screenshot/screenshot.c b/mods/src/screenshot/screenshot.c index 8a6abc6..73aad69 100644 --- a/mods/src/screenshot/screenshot.c +++ b/mods/src/screenshot/screenshot.c @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include @@ -13,7 +16,7 @@ #include "screenshot.h" -// 4 (Year + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Terminator) +// 4 (Year) + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Null Terminator) #define TIME_SIZE 20 // Take Screenshot @@ -73,7 +76,25 @@ void take_screenshot() { free(screenshots); } -// Init FreeImage +// Init __attribute__((constructor)) static void init() { + // Init FreeImage FreeImage_Initialise(0); + + // Screenshots Folder + char *screenshots_folder = NULL; + asprintf(&screenshots_folder, "%s/.minecraft/screenshots", getenv("HOME")); + { + // Check Screenshots Folder + struct stat obj; + if (stat(screenshots_folder, &obj) != 0 || !S_ISDIR(obj.st_mode)) { + // Create Screenshots Folder + int ret = mkdir(screenshots_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (ret != 0) { + // Unable To Create Folder + ERR("Error Creating Directory: %s: %s", screenshots_folder, strerror(errno)); + } + } + } + free(screenshots_folder); } \ No newline at end of file