From 9d5441aa52642ef7993cb5dce214c30395f7cbbd Mon Sep 17 00:00:00 2001 From: ehellas Date: Sun, 28 Apr 2024 23:19:57 -0300 Subject: [PATCH] add steam build option --- README.md | 32 +++++++ docker-compose-steam.yml | 143 ++++++++++++++++++++++++++++++ docker/Dockerfile-steam | 62 +++++++++++++ docker/docker-entrypoint-steam.sh | 40 +++++++++ docker/start.sh | 8 ++ 5 files changed, 285 insertions(+) create mode 100644 docker-compose-steam.yml create mode 100644 docker/Dockerfile-steam create mode 100644 docker/docker-entrypoint-steam.sh create mode 100644 docker/start.sh diff --git a/README.md b/README.md index b18fc20..3b4c585 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,38 @@ for more info.) - [Remote Control](https://github.com/Novex/stardew-remote-control) (Default: On) - [TimeSpeed](https://www.nexusmods.com/stardewvalley/mods/169) (Default: Off) + +## Steam Setup + +This image will download the game from Steam server using [steamcmd](https://developer.valvesoftware.com/wiki/SteamCMD) if you own the game, for that it requires your steam login. + +The credential variables are required only during building, not during game run. + +``` +## Setup those variable only during the first build or updates +export STEAM_USER= +export STEAM_PASS= +export STEAM_GUARD= # If you account is not protected don't set + +docker-compose -f docker-compose-steam.yml up +``` + +### Steam Guard + +If your account is protected by steam Guard the build is a little time sensitive. You must open your app and +export the current Steam Guard to `STEAM_GUARD` environment variable code right before building. + +**Note: the code lasts a little longer than shown but not much.** + +After start building pay attention to your app, even with the code it will request for authorization, which must be granted. + +If the build fails or when you want to update with `docker-compose build --no-cache` you should set the newers `STEAM_GUARD` again. + +``` +## Remove env variables after build +unset STEAM_USER STEAM_PASS STEAM_GUARD +``` + ## Troubleshooting ### Waiting for Day to End diff --git a/docker-compose-steam.yml b/docker-compose-steam.yml new file mode 100644 index 0000000..5fb1ffa --- /dev/null +++ b/docker-compose-steam.yml @@ -0,0 +1,143 @@ +version: '2.2' + +services: + valley: + build: + context: docker + dockerfile: Dockerfile-steam + args: + STEAM_USER: ${STEAM_USER} ## Recommended: set as env_variable during build + STEAM_PASS: ${STEAM_PASS} ## Recommended: set as env_variable during build + STEAM_GUARD: ${STEAM_GUARD} ## Recommended: set as env_variable during build + SRCDS_APPID: 413150 ## Stardew steamId + container_name: stardew + environment: + # VNC + - VNC_PASSWORD=insecure + - DISPLAY_HEIGHT=900 + - DISPLAY_WIDTH=1200 + + # Always On Server mod + ## Removing this will probably defeat the point of ever using this? + - ENABLE_ALWAYSONSERVER_MOD=${ENABLE_ALWAYSONSERVER_MOD-true} + - ALWAYS_ON_SERVER_HOTKEY=${ALWAYS_ON_SERVER_HOTKEY-F9} + - ALWAYS_ON_SERVER_PROFIT_MARGIN=${ALWAYS_ON_SERVER_PROFIT_MARGIN-100} + - ALWAYS_ON_SERVER_UPGRADE_HOUSE=${ALWAYS_ON_SERVER_UPGRADE_HOUSE-0} + - ALWAYS_ON_SERVER_PET_NAME=${ALWAYS_ON_SERVER_PET_NAME-Rufus} + - ALWAYS_ON_SERVER_FARM_CAVE_CHOICE_MUSHROOMS=${ALWAYS_ON_SERVER_FARM_CAVE_CHOICE_MUSHROOMS-true} + - ALWAYS_ON_SERVER_COMMUNITY_CENTER_RUN=${ALWAYS_ON_SERVER_COMMUNITY_CENTER_RUN-true} + - ALWAYS_ON_SERVER_TIME_OF_DAY_TO_SLEEP=${ALWAYS_ON_SERVER_TIME_OF_DAY_TO_SLEEP-2200} + - ALWAYS_ON_SERVER_LOCK_PLAYER_CHESTS=${ALWAYS_ON_SERVER_LOCK_PLAYER_CHESTS-false} + - ALWAYS_ON_SERVER_CLIENTS_CAN_PAUSE=${ALWAYS_ON_SERVER_CLIENTS_CAN_PAUSE-true} + - ALWAYS_ON_SERVER_COPY_INVITE_CODE_TO_CLIPBOARD=${ALWAYS_ON_SERVER_COPY_INVITE_CODE_TO_CLIPBOARD-false} + + - ALWAYS_ON_SERVER_FESTIVALS_ON=${ALWAYS_ON_SERVER_FESTIVALS_ON-true} + - ALWAYS_ON_SERVER_EGG_HUNT_COUNT_DOWN=${ALWAYS_ON_SERVER_EGG_HUNT_COUNT_DOWN-600} + - ALWAYS_ON_SERVER_FLOWER_DANCE_COUNT_DOWN=${ALWAYS_ON_SERVER_FLOWER_DANCE_COUNT_DOWN-600} + - ALWAYS_ON_SERVER_LUAU_SOUP_COUNT_DOWN=${ALWAYS_ON_SERVER_LUAU_SOUP_COUNT_DOWN-600} + - ALWAYS_ON_SERVER_JELLY_DANCE_COUNT_DOWN=${ALWAYS_ON_SERVER_JELLY_DANCE_COUNT_DOWN-600} + - ALWAYS_ON_SERVER_GRANGE_DISPLAY_COUNT_DOWN=${ALWAYS_ON_SERVER_GRANGE_DISPLAY_COUNT_DOWN-600} + - ALWAYS_ON_SERVER_ICE_FISHING_COUNT_DOWN=${ALWAYS_ON_SERVER_ICE_FISHING_COUNT_DOWN-600} + + - ALWAYS_ON_SERVER_END_OF_DAY_TIMEOUT=${ALWAYS_ON_SERVER_END_OF_DAY_TIMEOUT-300} + - ALWAYS_ON_SERVER_FAIR_TIMEOUT=${ALWAYS_ON_SERVER_FAIR_TIMEOUT-1200} + - ALWAYS_ON_SERVER_SPIRITS_EVE_TIMEOUT=${ALWAYS_ON_SERVER_SPIRITS_EVE_TIMEOUT-900} + - ALWAYS_ON_SERVER_WINTER_STAR_TIMEOUT=${ALWAYS_ON_SERVER_WINTER_STAR_TIMEOUT-900} + + - ALWAYS_ON_SERVER_EGG_FESTIVAL_TIMEOUT=${ALWAYS_ON_SERVER_EGG_FESTIVAL_TIMEOUT-120} + - ALWAYS_ON_SERVER_FLOWER_DANCE_TIMEOUT=${ALWAYS_ON_SERVER_FLOWER_DANCE_TIMEOUT-120} + - ALWAYS_ON_SERVER_LUAU_TIMEOUT=${ALWAYS_ON_SERVER_LUAU_TIMEOUT-120} + - ALWAYS_ON_SERVER_DANCE_OF_JELLIES_TIMEOUT=${ALWAYS_ON_SERVER_DANCE_OF_JELLIES_TIMEOUT-120} + - ALWAYS_ON_SERVER_FESTIVAL_OF_ICE_TIMEOUT=${ALWAYS_ON_SERVER_FESTIVAL_OF_ICE_TIMEOUT-120 } + + # Auto Load Game mod + ## Removing this will mean you need to VNC in to manually start the game each boot + - ENABLE_AUTOLOADGAME_MOD=${ENABLE_AUTOLOADGAME-true} + - AUTO_LOAD_GAME_LAST_FILE_LOADED=${AUTO_LOAD_GAME_LAST_FILE_LOADED-null} + - AUTO_LOAD_GAME_FORGET_LAST_FILE_ON_TITLE=${AUTO_LOAD_GAME_FORGET_LAST_FILE_ON_TITLE-true} + - AUTO_LOAD_GAME_LOAD_INTO_MULTIPLAYER=${AUTO_LOAD_GAME_LOAD_INTO_MULTIPLAYER-true} + + # Save Backup mod + ## Disabling this will stop saves being backed up + - ENABLE_SAVEBACKUP_MOD=${ENABLE_SAVEBACKUP_MOD-true} + + # Chat Commands mod + - ENABLE_CHATCOMMANDS_MOD=${ENABLE_CHATCOMMANDS_MOD-false} + + # Console Commands mod + - ENABLE_CONSOLECOMMANDS_MOD=${ENABLE_CONSOLECOMMANDS_MOD-false} + + # Time Speed mod + - ENABLE_TIMESPEED_MOD=${ENABLE_TIMESPEED_MOD-false} + + ## Days are only 20 hours long + ## 7.0 = 14 mins per in game day (default) + ## 10.0 = 20 mins + ## 15.0 = 30 mins + ## 20.0 = 40 mins + ## 30.0 = 1 hour + ## 120.0 = 4 hours + ## 300.0 = 10 hours + ## 600.0 = 20 hours (realtime) + + - TIME_SPEED_DEFAULT_TICK_LENGTH=${TIME_SPEED_DEFAULT_TICK_LENGTH-7.0} + - TIME_SPEED_TICK_LENGTH_BY_LOCATION_INDOORS=${TIME_SPEED_TICK_LENGTH_BY_LOCATION_INDOORS-7.0} + - TIME_SPEED_TICK_LENGTH_BY_LOCATION_OUTDOORS=${TIME_SPEED_TICK_LENGTH_BY_LOCATION_OUTDOORS-7.0} + - TIME_SPEED_TICK_LENGTH_BY_LOCATION_MINE=${TIME_SPEED_TICK_LENGTH_BY_LOCATION_MINE-7.0} + + - TIME_SPEED_ENABLE_ON_FESTIVAL_DAYS=${TIME_SPEED_ENABLE_ON_FESTIVAL_DAYS-false} + - TIME_SPEED_FREEZE_TIME_AT=${TIME_SPEED_FREEZE_TIME_AT-null} + - TIME_SPEED_LOCATION_NOTIFY=${TIME_SPEED_LOCATION_NOTIFY-false} + + - TIME_SPEED_KEYS_FREEZE_TIME=${TIME_SPEED_KEYS_FREEZE_TIME-N} + - TIME_SPEED_KEYS_INCREASE_TICK_INTERVAL=${TIME_SPEED_KEYS_INCREASE_TICK_INTERVAL-OemPeriod} + - TIME_SPEED_KEYS_DECREASE_TICK_INTERVAL=${TIME_SPEED_KEYS_DECREASE_TICK_INTERVAL-OemComma} + - TIME_SPEED_KEYS_RELOAD_CONFIG=${TIME_SPEED_KEYS_RELOAD_CONFIG-B} + + # Crops Anytime Anywhere mod + - ENABLE_CROPSANYTIMEANYWHERE_MOD=${ENABLE_CROPSANYTIMEANYWHERE_MOD-false} + + - CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_SPRING=${CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_SPRING-true} + - CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_SUMMER=${CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_SUMMER-true} + - CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_FALL=${CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_FALL-true} + - CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_WINTER=${CROPS_ANYTIME_ANYWHERE_ENABLE_IN_SEASONS_WINTER-true} + + - CROPS_ANYTIME_ANYWHERE_FARM_ANY_LOCATION=${CROPS_ANYTIME_ANYWHERE_FARM_ANY_LOCATION-true} + + - CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_DIRT=${CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_DIRT-true} + - CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_GRASS=${CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_GRASS-true} + - CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_STONE=${CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_STONE-false} + - CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_OTHER=${CROPS_ANYTIME_ANYWHERE_FORCE_TILLABLE_OTHER-false} + + # Friends Forever mod + - ENABLE_FRIENDSFOREVER_MOD=${ENABLE_FRIENDSFOREVER_MOD-false} + + - FRIENDS_FOREVER_AFFECT_SPOUSE=${FRIENDS_FOREVER_AFFECT_SPOUSE-false} + - FRIENDS_FOREVER_AFFECT_DATES=${FRIENDS_FOREVER_AFFECT_DATES-true} + - FRIENDS_FOREVER_AFFECT_EVERYONE_ELSE=${FRIENDS_FOREVER_AFFECT_EVERYONE_ELSE-true} + - FRIENDS_FOREVER_AFFECT_ANIMALS=${FRIENDS_FOREVER_AFFECT_ANIMALS-true} + + # No Fence Decay mod + - ENABLE_NOFENCEDECAY_MOD=${ENABLE_NOFENCEDECAY_MOD-false} + + # Non-destructive NPCs mod + - ENABLE_NONDESTRUCTIVENPCS_MOD=${ENABLE_NONDESTRUCTIVENPCS_MOD-false} + + ports: + # VNC + - 5902:5900 + # NOVNC WEB + - 5801:5800 + # Game + - 24642:24642/udp + volumes: + # Saves go here now + - ./valley_saves:/config/xdg/config/StardewValley/Saves + # If you'd like to set an existing savegame before the first start otherwise this file will be edited when starting the first game + - ./configs/autoload.json:/data/Stardew/game/Mods/AutoLoadGame/config.json + # deploy: + # ## The container is CPU hungry, you can limit using this block + # ## If you don't plan to play using VNC, 1 core should be enough to host for others + # resources: + # limits: + # cpus: "1" diff --git a/docker/Dockerfile-steam b/docker/Dockerfile-steam new file mode 100644 index 0000000..d2357a7 --- /dev/null +++ b/docker/Dockerfile-steam @@ -0,0 +1,62 @@ +# Pull base image. +FROM jlesage/baseimage-gui:debian-11 + +ARG STEAM_USER +ARG STEAM_PASS +ARG SRCDS_APPID # Steam appId +ARG STEAM_GUARD + +# Set the name of the application. +ENV APP_NAME="StardewValley" +## Uses a distinct PATH from Stardew/game/ that GOG has. +ENV GAME_PATH="/data/Stardew/" + +## lib32gcc-s1 is required for steamcmd +RUN apt-get update && apt-get install -y wget unzip tar strace mono-complete xterm gettext-base jq netcat procps lib32gcc-s1 && apt-get clean + +# Game + ModLoader 1.6.2 4.0.1 + +RUN mkdir -p /data/Stardew && \ + mkdir -p /data/nexus && \ + mkdir -p /data/steamcmd + +## FOR STEAM VERSION +RUN wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz -qO steamcmd.tar.gz && \ + tar -xzvf steamcmd.tar.gz -C /data/steamcmd && \ + cd /data/steamcmd + +RUN chown -R 1000:1000 /data && \ + export HOME=/data && \ + /data/steamcmd/steamcmd.sh +force_install_dir /data/Stardew +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_GUARD} +app_update ${SRCDS_APPID} validate +quit + +RUN mkdir -p /data/.steam/sdk32 && \ + cp -v /data/steamcmd/linux32/steamclient.so /data/.steam/sdk32/steamclient.so && \ + mkdir -p /data/.steam/sdk64 && \ + cp -v /data/steamcmd/linux64/steamclient.so /data/.steam/sdk64/steamclient.so +## END STEAM VERSION + +RUN wget -qO dotnet.tar.gz https://download.visualstudio.microsoft.com/download/pr/d4b71fac-a2fd-4516-ac58-100fb09d796a/e79d6c2a8040b59bf49c0d167ae70a7b/dotnet-sdk-5.0.408-linux-arm64.tar.gz &&\ + tar -zxf dotnet.tar.gz -C /usr/share/dotnet &&\ + rm dotnet.tar.gz &&\ + ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet + +RUN wget --user-agent="Mozilla" https://mirror.cloudcraft.info/SMAPI_latest.tar.gz -qO /data/nexus.tar.gz && \ + tar xf /data/nexus.tar.gz -C /data/nexus && \ + SMAPI_INSTALLER=$(find /data/nexus -name 'SMAPI*.*Installer' -type f -path "*/SMAPI * installer/internal/linux/*" | head -n 1) && \ + /bin/bash -c "SMAPI_NO_TERMINAL=true SMAPI_USE_CURRENT_SHELL=true echo -e '2\n\n' | \"$SMAPI_INSTALLER\" --install --game-path \"$GAME_PATH\"" || : + +# Add Mods & Scripts +COPY ["mods/", "$GAME_PATH/Mods/"] +COPY scripts/ /opt/ + +RUN chmod +x $GAME_PATH/StardewValley && \ + chmod -R 777 $GAME_PATH && \ + chown -R 1000:1000 /data/Stardew && \ + chmod +x /opt/*.sh + +RUN mkdir /etc/services.d/utils && touch /etc/services.d/app/utils.dep +COPY run /etc/services.d/utils/run +RUN chmod +x /etc/services.d/utils/run + +COPY docker-entrypoint.sh /startapp.sh +RUN chmod +x /startapp.sh diff --git a/docker/docker-entrypoint-steam.sh b/docker/docker-entrypoint-steam.sh new file mode 100644 index 0000000..2bca5c8 --- /dev/null +++ b/docker/docker-entrypoint-steam.sh @@ -0,0 +1,40 @@ +#!/bin/bash +export HOME=/config + +for modPath in $GAME_PATH/Mods/*/ +do + mod=$(basename "$modPath") + + # Normalize mod name ot uppercase and only characters, eg. "Always On Server" => ENABLE_ALWAYSONSERVER_MOD + var="ENABLE_$(echo "${mod^^}" | tr -cd '[A-Z]')_MOD" + + # Remove the mod if it's not enabled + if [ "${!var}" != "true" ]; then + echo "Removing ${modPath} (${var}=${!var})" + rm -rf "$modPath" + continue + fi + + if [ -f "${modPath}/config.json.template" ]; then + echo "Configuring ${modPath}config.json" + + # Seed the config.json only if one isn't manually mounted in (or is empty) + if [ "$(cat "${modPath}config.json" 2> /dev/null)" == "" ]; then + envsubst < "${modPath}config.json.template" > "${modPath}config.json" + fi + fi +done + +# Run extra steps for certain mods +/opt/configure-remotecontrol-mod.sh + +/opt/tail-smapi-log.sh & + +# Ready to start! + +export XAUTHORITY=~/.Xauthority +sed -i 's/env TERM=xterm $LAUNCHER "$@"/env SHELL=\/bin\/bash TERM=xterm xterm -e "\/bin\/bash -c $LAUNCHER \"$@\""/' $GAME_PATH/Stardew\ Valley + +bash -c "$GAME_PATH/start.sh" + +sleep 233333333333333 diff --git a/docker/start.sh b/docker/start.sh new file mode 100644 index 0000000..f11085e --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Used only on STEAM DOCKERFILE +# Steam Version doesn't have a proper SH start File +# and we require on to execute properly on xterm +echo "Running Stardew Valley" +cd "${GAME_PATH}" +chmod +x * +./"StardewValley"