diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 59c464d..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/data -/steamcred.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index afe92f8..e2640f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/runtime +FROM public.ecr.aws/docker/library/debian:12 ENV \ LANG="en_US.UTF-8" \ @@ -9,26 +9,48 @@ WORKDIR /root # Install Base Packages RUN apt update && apt upgrade -y \ - && dpkg --add-architecture i386 -RUN DEBIAN_FRONTEND=noninteractive \ - apt install -y \ + && dpkg --add-architecture i386 \ + && apt install -y \ apt-transport-https \ - curl \ - jq \ + dirmngr \ + gnupg \ + ca-certificates \ + iproute2 \ + unzip \ + sqlite3 \ + fontconfig \ lib32gcc-s1 \ - libopus-dev \ - libopus0 \ - locales \ - mono-complete \ - opus-tools \ - sudo + curl \ + wget \ + screen \ + sudo \ + youtube-dl \ + jq + +# Install Mono +RUN export GNUPGHOME=$(mktemp -d) \ + && gpg --recv-keys --no-default-keyring --keyring /etc/apt/trusted.gpg.d/mono-keyring.gpg --keyserver keyserver.ubuntu.com 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \ + && echo "deb [signed-by=/etc/apt/trusted.gpg.d/mono-keyring.gpg] https://download.mono-project.com/repo/debian stable-buster main" > /etc/apt/sources.list.d/mono-official-stable.list \ + && wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ + && dpkg -i packages-microsoft-prod.deb \ + && rm packages-microsoft-prod.deb \ + && apt-get update \ + && apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y mono-complete + +# Install Crystite +RUN echo 'deb [signed-by=/usr/share/keyrings/algiz.gpg] https://repo.algiz.nu/crystite bookworm main' | tee /etc/apt/sources.list.d/crystite.list \ + && mkdir -p /usr/share/keyrings \ + && wget -O /usr/share/keyrings/algiz.gpg https://repo.algiz.nu/algiz.gpg \ + && apt-get update \ + && apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y crystite # make data directories RUN mkdir -p /data/resonite /data/steamcmd -VOLUME [ "/data/resonite", "/data/steamcmd", "/data/home" ] +VOLUME [ "/etc/crystite", "/data/resonite", "/data/steamcmd", "/data/home" ] # DEFAULT ENVS ENV DISABLE_STEAMCMD=false +ENV USE_CRYSTITE=false ENV CONFIG_FILE="/data/Config.json" ENV COMMAND="/scripts/99_start.sh" ENV RESONITE_ARGS="" @@ -36,7 +58,7 @@ ENV RESONITE_MOD_LOADER=false ENV MOD_URLS="" ENV STOP_LAUNCH=false -COPY defaults /mnt/defaults +COPY crystite /mnt/crystite COPY scripts /scripts RUN chmod +x /scripts/* ENTRYPOINT ["/scripts/00_setup.sh"] diff --git a/crystite/appsettings.json b/crystite/appsettings.json new file mode 100644 index 0000000..2f7e4de --- /dev/null +++ b/crystite/appsettings.json @@ -0,0 +1,23 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Debug" ], + "WriteTo": [ + { + "Name": "Console" + } + ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Information", + "Microsoft": "Information", + "System.Net.Http.HttpClient": "Warning" + } + } + }, + "Headless": { + "resonitePath": "/data/resonite", + "assetCleanupInterval": "06:00:00", + "maxAssetAge": "07:00:00:00" + } +} \ No newline at end of file diff --git a/defaults/resonite.json b/crystite/resonite.json similarity index 100% rename from defaults/resonite.json rename to crystite/resonite.json diff --git a/docker-compose.yml b/docker-compose.yml index b97e11f..a79aaf5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,6 @@ services: resonite: # build: . image: git.merith.xyz/oci/resonite:nightly - container_name: resonite network_mode: host stdin_open: true @@ -10,22 +9,33 @@ services: volumes: # general data - ./data:/data:rw - + # have volume entires in dockerfile, if removed this data will persist # until the volume is removed - - ./data/resonite:/data/resonite:rw - - ./data/steamcmd:/data/steamcmd:rw + # - ./data/crystite/:/etc/crystite:rw + # - ./data/resonite:/data/resonite:rw + # - ./data/steamcmd:/data/steamcmd:rw - # mount scripts for runtime, optional - - ./scripts:/scripts:ro + # mount scripts for runtime, optional + - .build/scripts:/scripts:ro + - .build/crystite:/mnt/crystite:ro ## EDIT THESE ENVIRONMENT VARIABLES ## environment: + # DO NOT REMOVE THIS VALUE + RUN_AS: 1000 + # THIS CONTROLS THE USER ID THAT THE SERVER RUNS AS + # This is specifically so *you* have control over the files] + ## Options ## ## These have their defualts set in the Dockerfile, and are safe to remove from this file - + # Prevents SteamCMD from updating the gamefiles - DISABLE_STEAMCMD: false + DISABLE_STEAMCMD: "false" + + # Wether to use crystite or not. + # if no STEAM_BETA key is provided, this is force set to true + USE_CRYSTITE: "false" # Where to located the config file, defaults to /data/Config.json # if config file does not exist, it will generate a template one at that location @@ -35,16 +45,13 @@ services: COMMAND: "/scripts/99_start.sh" # Wether to enable the Resonite Mod Loader + # Crystite Support is expiremental at best. RESONITE_MOD_LOADER: true - # list of mods to load, MOD_URLS: | - https://github.com/Raidriar796/StresslessHeadless/releases/download/2.0.0-rc1/StresslessHeadless.dll - # https://github.com/New-Project-Final-Final-WIP/HeadlessTweaks/releases/latest/download/HeadlessTweaks.dll - - # Controls the UID:GID of the headless, defaults to `root` if not set - RUN_AS: 1000 - + https://github.com/New-Project-Final-Final-WIP/HeadlessTweaks/releases/latest/download/HeadlessTweaks.dll + https://github.com/Raidriar796/StresslessHeadless/releases/latest/download/StresslessHeadless.dll + # Does not allow the server to start, helpful for debugging the container as a whole STOP_LAUNCH: false diff --git a/scripts/00_setup.sh b/scripts/00_setup.sh old mode 100755 new mode 100644 index 11e8183..8a97a56 --- a/scripts/00_setup.sh +++ b/scripts/00_setup.sh @@ -17,12 +17,7 @@ export DEFAULT_RESONITE_ARGS="-LogsPath /data/resonite/logs \ -HeadlessConfig $CONFIG_FILE \ $RESONITE_ARGS" -mkdir -p /data/home /data/resonite /data/steamcmd - -## set /data to be owned by root user during install -# required because steamcmd checks if folder is owned by current user -chown root:root /data/ -R - +mkdir -p /data/home /data/resonite /data/steamcmd /etc/crystite/conf.d ## Have to do this here, as otherwise stuff doesnt work for some reason # using source so runtime vars can be updated as needed source /scripts/01_install.sh @@ -40,6 +35,7 @@ if [ "$RUN_AS" != "" ]; then export HOME="/home/user" chown $USER_ID:$GROUP_ID /data -R + chown $USER_ID:$GROUP_ID /etc/crystite -R echo "executing command: $COMMAND" exec sudo -E -u user $COMMAND diff --git a/scripts/01_install.sh b/scripts/01_install.sh old mode 100755 new mode 100644 index fa62c31..1378d29 --- a/scripts/01_install.sh +++ b/scripts/01_install.sh @@ -8,11 +8,19 @@ if [ "$DISABLE_STEAMCMD" != "true" ]; then fi # if steam beta is empty, or matchs "beta_access_key" we don't need to dwonload the beta if [ -z "$STEAM_BETA" ] || [ "$STEAM_BETA" == "beta_access_key" ]; then - echo "[ERROR] Unable to Download Headless, No Beta Key" - exit + echo "Downloading Resonite" + /data/steamcmd/steamcmd.sh +login anonymous +force_install_dir /data/resonite +app_update 2519830 +quit else echo "Downloading Resonite Headless" - /data/steamcmd/steamcmd.sh +force_install_dir /data/resonite +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +app_license_request 2519830 +app_update 2519830 -beta headless -betapassword ${STEAM_BETA} validate +quit + /data/steamcmd/steamcmd.sh +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir /data/resonite +app_update 2519830 -beta headless -betapassword ${STEAM_BETA} validate +quit fi - ln -s /data/resonite/Headless/Resonite.dll /data/resonite/Headless/dotnet-Resonite.dll fi + +# if crystite is enabled, we don't need to check for resonite +if [ "$USE_CRYSTITE" != "true" ]; then + if [ ! -f "/data/resonite/Headless/Resonite.exe" ]; then + echo "Headless/Resonite.exe not found!" + echo "Forcing use of Crystite" + USE_CRYSTITE="true" + fi +fi \ No newline at end of file diff --git a/scripts/02_setup_config.sh b/scripts/02_setup_config.sh old mode 100755 new mode 100644 index 5ec5d7c..282b32d --- a/scripts/02_setup_config.sh +++ b/scripts/02_setup_config.sh @@ -6,20 +6,29 @@ echo "Setting up Resonite Config" # if CONFIG_FILE is not set, use default config path if [ ! -f $CONFIG_FILE ]; then echo "No Resonite Config found, copying from template" - cp /mnt/defaults/resonite.json $CONFIG_FILE + cp /mnt/crystite/resonite.json $CONFIG_FILE + # cat /mnt/crystite/resonite.json | jq '.' > $CONFIG_FILE +fi +echo "Generating Crystite configs" +if [ ! -f "/etc/crystite/appsettings.json" ]; then + cat /mnt/crystite/appsettings.json | jq '.' > /etc/crystite/appsettings.json fi CONFIG_DATA=$(grep -v " null," "$CONFIG_FILE") if [ ! -n "$CONFIG_DATA" ]; then echo "Config file is empty, copying from template" - cp /mnt/defaults/resonite.json $CONFIG_FILE + cp /mnt/crystite/resonite.json $CONFIG_FILE CONFIG_DATA=$(grep -v " null," "$CONFIG_FILE") fi +CONFIG_DATA=$(echo "$CONFIG_DATA" | jq ".comment = \"DO NOT EDIT: This file was automatically generated. Please edit $CONFIG_FILE instead.\"") +echo "{ \"Resonite\": $CONFIG_DATA }" > /etc/crystite/conf.d/_generated_resonite.json ## Setup Modloader Configs if [ "$RESONITE_MOD_LOADER" == "true" ]; then echo "Setting up Modloader Configs" + echo "{\"Resonite\": {\"pluginAssemblies\": [\"/data/resonite/Headless/Libraries/ResoniteModLoader.dll\"]}}" | jq '.' > /etc/crystite/conf.d/_generated_rml.json DEFAULT_RESONITE_ARGS=$(echo "$DEFAULT_RESONITE_ARGS -LoadAssembly /data/resonite/Headless/Libraries/ResoniteModLoader.dll") else echo "Modloader is disabled" + rm -f /etc/crystite/conf.d/_generated_rml.json fi \ No newline at end of file diff --git a/scripts/03_download_mods.sh b/scripts/03_download_mods.sh old mode 100755 new mode 100644 index 9087bf3..7b26c2c --- a/scripts/03_download_mods.sh +++ b/scripts/03_download_mods.sh @@ -10,9 +10,7 @@ # Define file URLs and their associated positions file_urls=( "https://github.com/resonite-modding-group/ResoniteModLoader/releases/latest/download/ResoniteModLoader.dll /data/resonite/Headless/Libraries/ResoniteModLoader.dll" - # "https://github.com/resonite-modding-group/ResoniteModLoader/releases/latest/download/0Harmony.dll /data/resonite/Headless/rml_libs/0Harmony.dll" - # net9 Harmony - "https://github.com/stiefeljackal/pardeike.Harmony/releases/download/temp-release/0Harmony.dll /data/resonite/Headless/rml_libs/0Harmony.dll" + "https://github.com/resonite-modding-group/ResoniteModLoader/releases/latest/download/0Harmony.dll /data/resonite/Headless/rml_libs/0Harmony.dll" ) # Function to download a file from URL to destination @@ -55,11 +53,11 @@ done # if resonte mod loader is enabled, create and link rml_mods, libs, and config if [ "$RESONITE_MOD_LOADER" == "true" ]; then for dir in rml_mods rml_libs rml_config; do - if [ -d "/data/resonite/Headless/$dir" ]; then + if [ -d "/data/resonite/$dir" ]; then continue fi mkdir -p "/data/resonite/Headless/$dir" - ln -s "./Headless/$dir" "./$dir" + ln -s "/data/resonite/Headless/$dir" "/data/resonite/$dir" done if [ ! -f "/data/resonite/Libraries/ResoniteModLoader.dll" ]; then mkdir -p "/data/resonite/Libraries" diff --git a/scripts/99_start.sh b/scripts/99_start.sh old mode 100755 new mode 100644 index a7eeab5..597347f --- a/scripts/99_start.sh +++ b/scripts/99_start.sh @@ -5,7 +5,14 @@ if [ "$STOP_LAUNCH" == "true" ]; then exit 0 fi -cd /data/resonite/Headless || exit -echo "Running Resonite" -echo "exec: dotnet Resonite.dll $DEFAULT_RESONITE_ARGS $RESONITE_ARGS" -dotnet Resonite.dll $DEFAULT_RESONITE_ARGS $RESONITE_ARGS +# Check if Crystite is enabled +if [ "$USE_CRYSTITE" == "true" ]; then + echo "Running Crystite" + echo "exec: /usr/lib/crystite/crystite" + /usr/lib/crystite/crystite +else + cd /data/resonite/Headless || exit + echo "Running Resonite" + echo "exec: mono Resonite.exe $DEFAULT_RESONITE_ARGS $RESONITE_ARGS" + mono Resonite.exe $DEFAULT_RESONITE_ARGS $RESONITE_ARGS +fi \ No newline at end of file