From 2fc31fea372ead9d27f798b5c0abb606ef153af5 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Thu, 18 May 2023 17:29:27 -0700 Subject: [PATCH] The server doesn't like read only directories where it finds its files. Removing read-only flags from mounts for now. Rework directories so there are fewer volumes within volumes. Keep splitting up the code between the two scripts, removing unused variables, etc.. Add XML file merging integration. WIP. Fix lack of comma in cfg file that _might_ have been causing issues... --- docker-compose.yml | 8 +- files/dz-common | 12 +- files/mods/2692979668/{types.env => xml.env} | 7 +- files/mods/types.sh | 68 -------- files/mods/xml.sh | 25 +++ files/serverDZ.cfg | 6 +- server/Dockerfile | 5 +- server/bin/dz | 155 ++++++++----------- web/bin/dz | 115 ++++++++++++-- 9 files changed, 211 insertions(+), 190 deletions(-) rename files/mods/2692979668/{types.env => xml.env} (80%) delete mode 100755 files/mods/types.sh create mode 100755 files/mods/xml.sh diff --git a/docker-compose.yml b/docker-compose.yml index 4dabaa3..f7744f9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,7 @@ services: - homedir_main:/home/user - serverfiles:/serverfiles - mods:/serverfiles/steamapps/workshop/content - - mpmissions:/serverfiles/mpmissions + - mods:/mods - ./files:/files - ./web/bin/dz:/usr/local/bin/dz - ./web:/web @@ -34,9 +34,9 @@ services: build: server volumes: - homedir_server:/home/user - - serverfiles:/serverfiles:ro - - mods:/serverfiles/steamapps/workshop/content:ro - - mpmissions:/serverfiles/mpmissions:ro + - serverfiles:/serverfiles + - mods:/mods + - mpmissions:/serverfiles/mpmissions - profiles:/profiles - ./files:/files - ./server/bin/dz:/usr/local/bin/dz diff --git a/files/dz-common b/files/dz-common index 5d0e34d..81c5c25 100755 --- a/files/dz-common +++ b/files/dz-common @@ -81,9 +81,9 @@ check_mod_install(){ fi } -get_mod_id_by_index(){ +get_mod_id_by_index2(){ # If we were passed a valid mod id, just return it - if [[ -d "${WORKSHOP_DIR}/${1}" ]] + if [ -d "${WORKSHOP_DIR}/${1}" ] then echo -n ${1} return @@ -104,7 +104,7 @@ get_mod_id_by_index(){ # Get mod name by ID or index get_mod_name(){ - ID=$(get_mod_id_by_index ${1}) + ID=$(get_mod_id_by_index2 ${1}) if ! [ -d "${WORKSHOP_DIR}/${ID}" ] then echo "Mod ID ${1} doesn't exist" >&2 @@ -116,19 +116,19 @@ get_mod_name(){ # List mods list(){ - workshoplist="" X=1 C="${green}" spaces=" " - echo -e "\n ID Name URL Size" + echo "Installed mods:" + echo -e " ID Name URL Size" echo "------------------------------------------------------------------------------------------------------------------------" for dir in $(ls -tr ${WORKSHOP_DIR}) do ID=${dir} NAME=$(grep name "${WORKSHOP_DIR}/${dir}/meta.cpp" | cut -d '"' -f2 | sed -r 's/\s+//g') SIZE=$(du -sh "${WORKSHOP_DIR}/${dir}" | awk '{print $1}') - workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} printf "${C}%.3d %s %.23s %s https://steamcommunity.com/sharedfiles/filedetails/?id=%s %s${default}\n" ${X} ${ID} "${NAME}" "${spaces:${#NAME}+1}" ${ID} ${SIZE} X=$((X+1)) done + echo } diff --git a/files/mods/2692979668/types.env b/files/mods/2692979668/xml.env similarity index 80% rename from files/mods/2692979668/types.env rename to files/mods/2692979668/xml.env index 917f633..3a45bbe 100644 --- a/files/mods/2692979668/types.env +++ b/files/mods/2692979668/xml.env @@ -1,8 +1,9 @@ #!/usr/bin/env bash -CFGSPAWNABLETYPES=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/RFFSHelis_cfgspawnabletypes.xml -CFGEVENTSPAWNS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/Chernarus/RFFSHelis_cfgeventspawns.xml +CFGSPAWNABLETYPES=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/RFFSHelis_cfgspawnabletypes.xml #CFGEVENTSPAWNS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/Banov/RFFSHelis_cfgeventspawns.xml +CFGEVENTSPAWNS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/Chernarus/RFFSHelis_cfgeventspawns.xml +#CFGEVENTSPAWNS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/DeerIsle/RFFSHelis_cfgeventspawns.xml #CFGEVENTSPAWNS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/Namalsk/RFFSHelis_cfgeventspawns.xml -EVENTS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/RFFSHelis_events.xml +EVENTS=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/RFFSHelis_events.xml TYPES=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Types.XML/RFFSHelis_Types.xml diff --git a/files/mods/types.sh b/files/mods/types.sh deleted file mode 100755 index ac57196..0000000 --- a/files/mods/types.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -# A generic script to manage a mod's types.xml against all installed missions - -set -eE - -ID=${1} -MODE=${2} -TYPES_FILE="${WORKSHOP_DIR}/${ID}/extras/types.xml" - -if [[ ${3} != "" ]] -then - TYPES_FILE="${3}" -fi - -for file in $(find ${SERVER_FILES}/mpmissions -name types.xml -print -prune) -do - if [[ ${MODE} = "uninstall" ]] - then - # Remove the lines that were added by the mod's extras/types.xml from - # every db/types.xml in all mission directories - - # Chop the top tag from the source file - tail -n+2 ${TYPES_FILE} > /tmp/types-tmp.xml - - # Chop the bottom tag from the source file - head -n-1 /tmp/types-tmp.xml > /tmp/types-src.xml - - # Remove that content from the original file - grep -qvxFf /tmp/types-src.xml ${file} - else - # Add the contents of extras/types.xml to every db/types.xml in all - # mission directories - xmllint --noout ${TYPES_FILE} 2> /dev/null && { - echo -e "${green}${TYPES_FILE} passes XML lint test!" - echo -e "Merging to $file...${default}" - # Chop the bottom tag from the destination file - head -n-1 ${file} > /tmp/types-dst.xml - - # Chop the top 2 tags, xml and types, from the source file - tail -n+2 ${TYPES_FILE} > /tmp/types-src.xml - - # Concatenate the two files back into the source file - cat /tmp/types-dst.xml /tmp/types-src.xml > /tmp/types.xml - - xmllint --noout /tmp/types.xml 2> /dev/null && { - cp -v /tmp/types.xml ${file} - } || { - # Try again, but chop the top 3 tags, hopefully xml and types, from the source file... - echo "First merge attempt failed, trying again..." - tail -n+3 ${TYPES_FILE} > /tmp/types-src.xml - - # Concatenate the two files back into the source file - cat /tmp/types-dst.xml /tmp/types-src.xml > /tmp/types.xml - - # And lint again. This should probably be a recursive function... - xmllint --noout /tmp/types.xml && { - cp -v /tmp/types.xml ${file} - } || { - echo "XML lint check after merge failed! No files changed!" - } - } - } || { - echo -e "${red}${TYPES_FILE} fails XML lint test!" - echo -e "This will have to be merged by hand!${default}" - } - fi -done diff --git a/files/mods/xml.sh b/files/mods/xml.sh new file mode 100755 index 0000000..e4a6e57 --- /dev/null +++ b/files/mods/xml.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# A generic script to manage merging mod XML files to mpmissions XML files + +set -eE + +ID=${1} + +source ${FILES}/mods/${ID}/xml.env + +# Iterate over the file names we can handle +for var in CFGEVENTSPAWNS CFGSPAWNABLETYPES EVENTS TYPES +do + if echo ${!var} | grep -q http + then + OUT="${WORKSHOP_DIR}/${ID}/${var,,}.xml" + echo "${var} is a URL, downloading to ${OUT}" + curl -so ${OUT} ${!var} + xmllint --noout ${OUT} 2> /dev/null || { + echo -e "${red}${var,,}.xml does not pass XML lint test!${default}" + } && { + echo -e "${green}${var,,}.xml passes XML lint test!${default}" + } + fi +done diff --git a/files/serverDZ.cfg b/files/serverDZ.cfg index d692701..3a19c82 100644 --- a/files/serverDZ.cfg +++ b/files/serverDZ.cfg @@ -85,8 +85,8 @@ class Missions { template="dayzOffline.chernarusplus"; // Chernarus // template="dayzOffline.enoch"; // Livonia -// template="empty.banov" // Banov -// template="empty.deerisle" // Deer Isle -// template="serverMission.Pripyat" // Pripyat +// template="empty.banov"; // Banov +// template="empty.deerisle"; // Deer Isle +// template="serverMission.Pripyat"; // Pripyat }; }; diff --git a/server/Dockerfile b/server/Dockerfile index 947ce97..426f7aa 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -23,6 +23,7 @@ RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-reco nano \ procps \ python3-pip \ + strace \ wget RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1 @@ -43,8 +44,8 @@ RUN cd /usr/local && git clone https://github.com/indepth666/py3rcon.git # Setup a non-privileged user RUN groupadd user && \ useradd -l -g user user && \ - mkdir -p /home/user /serverfiles/mpmissions /serverfiles/steamapps/workshop/content /profiles /mods && \ - chown -R user:user /home/user /serverfiles /profiles /mods + mkdir -p /home/user /serverfiles/mpmissions /mods /mpmissions /profiles && \ + chown -R user:user /home/user /serverfiles /mods /mpmissions /profiles # Use our non-privileged user USER user diff --git a/server/bin/dz b/server/bin/dz index b50622b..7074a96 100755 --- a/server/bin/dz +++ b/server/bin/dz @@ -18,18 +18,10 @@ parameters="-config=${SERVER_CFG_DST} -port=${port} -freezecheck -BEpath=${SERVE # Used to check if dayZ is installed SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer" -# Workshop. This file will store metadata about what mods are in use in this server instance -WORKSHOP_CFG="${SERVER_PROFILE}/workshop.cfg" -if [ ! -f "${WORKSHOP_CFG}" ] -then - touch "${WORKSHOP_CFG}" -fi - -INSTALLED_MODS="${SERVER_FILES}/workshop.cfg" - # An array to store Workshop items. Each element contains the mod's ID, name, and state (active or not). -declare -a workshopID -WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}" +#WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}" +WORKSHOP_DIR="/mods/${release_client_appid}" +mod_command_line="" # Backups BACKUP_DIR="${HOME}/backup" @@ -56,7 +48,7 @@ Options and arguments: f|force - Forcibly kill the server. Use only as a last resort if the server won't shut down l|list - List Workshop items and their details n|rcon - Connect to the server using a python RCON client - restart - Restart the server without restarting the container + r|restart - Restart the server without restarting the container s|status - Shows the server's status: Running, uptime, mods, parameters, mod parameter, etc. stop - Stop the server ${default}" @@ -119,17 +111,19 @@ EOF > ~/py3rcon.config.json } -# Manage the mod symlink -symlink(){ - W=${1} - ID=${2} - NAME=${3} - if [ ! -L "${SERVER_FILES}/@${NAME}" ] && [[ ${W} = 1 ]] +get_mods(){ + workshoplist="" + mod_command_line="" + for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null) + do + ID=$(readlink ${link} | awk -F/ '{print $NF}') + MODNAME=$(get_mod_name ${ID}) + workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} + mod_command_line+="@${MODNAME};" + done + if [[ ${mod_command_line} != "" ]] then - ln -sv ${WORKSHOP_DIR}/${ID} "${SERVER_FILES}/@${NAME}" - elif [[ "${W}" = "0" ]] - then - rm -vf "${SERVER_FILES}/@${NAME}" + mod_command_line="-mod=${mod_command_line::-1}" fi } @@ -155,7 +149,7 @@ start(){ trap ' report ' EXIT - mod_cmd + get_mods cd ${SERVER_FILES} # Run the server. Allow docker to restart the container if the script exits with a code other than 0. This is so we can # safely shut the container down without killing the server within. @@ -164,7 +158,7 @@ start(){ # actual status with those echo ${mod_command_line} > /tmp/mod_command_line echo ${parameters} > /tmp/parameters - ./DayZServer ${mod_command_line} ${parameters} + ./DayZServer "${mod_command_line}" ${parameters} EXIT_CODE=$? if [ -f ${SERVER_FILES}/restart ] then @@ -213,42 +207,15 @@ config(){ fi } -# Assemble the workshop variables -get_installed_mods(){ - mapfile -t installedModsID < "${INSTALLED_MODS}" - workshoplist="" - for i in "${installedModsID[@]}" - do - ID=$(echo ${i} | cut -d: -f1) - workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} - done -} - -get_mods(){ - mapfile -t workshopID < "${WORKSHOP_CFG}" - workshoplist="" - for i in "${workshopID[@]}" - do - ID=$(echo ${i} | cut -d: -f1) - workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} - done -} - get_mod_id_by_index(){ - # If we were passed a valid mod id, just return it - if [[ -d "${workshopdir}/${1}" ]] - then - echo ${1} - return - fi X=1 - # Loop over mod list - for i in "${workshopID[@]}" + # Loop over mods + for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null) do - ID=$(echo ${i} | cut -d: -f1) + ID=$(readlink ${link} | awk -F/ '{print $NF}') if [[ ${X} = ${1} ]] then - echo ${ID} + echo -n ${ID} return fi X=$((X+1)) @@ -258,19 +225,13 @@ get_mod_id_by_index(){ # Get mod name by ID or index get_mod_name(){ # Check for an ID - if [ -d "${WORKSHOP_DIR}/${1}" ] - then - ID=${1} - else - ID=$(get_mod_id_by_index ${1}) - fi if ! [ -d "${WORKSHOP_DIR}/${ID}" ] then echo "Mod ID ${1} doesn't exist" >&2 exit 1 fi NAME=$(grep name ${WORKSHOP_DIR}/${ID}/meta.cpp | cut -d '"' -f2 | sed -r 's/\s+//g') - echo ${NAME} + echo -n ${NAME} } # Activate / Deactivate a mod @@ -285,35 +246,20 @@ activate(){ UU="un" COLOR="${red}" fi - ID=$(get_mod_id_by_index ${1}) - MODNAME=$(get_mod_name ${1}) + ID=$(get_mod_id_by_index2 ${1}) + MODNAME=$(get_mod_name ${ID}) # Toggle state or report nothing burger - if [[ "${ACTIVE}" != "${W}" ]] + pushd "${SERVER_PROFILE}" > /dev/null + if [ -L "${SERVER_PROFILE}/@${MODNAME}" ] then - sed -i "${WORKSHOP_CFG}" -e "s/${ID}:${MODNAME}:[0-1]/${ID}:${MODNAME}:${W}/" - echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} ${WW}activated" + rm -vf "${SERVER_PROFILE}/@${MODNAME}" else - echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} - is already ${WW}active" - fi - list -} - -# Assemble the mod command line -mod_cmd(){ - mod_command_line="" - for i in "${workshopID[@]}" - do - NAME=$(echo ${i} | cut -d: -f2) - ACTIVE=$(echo ${i} | cut -d: -f3) - if [[ ${ACTIVE} = "1" ]] - then - mod_command_line="${mod_command_line}@${NAME};" - fi - done - if [[ ${mod_command_line} != "" ]] - then - mod_command_line='-mod='${mod_command_line::-1} + ln -s "${WORKSHOP_DIR}/${ID}" "${SERVER_PROFILE}/@${MODNAME}" +# echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} - is already ${WW}active" fi + echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} ${WW}activated" + popd > /dev/null + status } checkXML(){ @@ -359,6 +305,29 @@ rcon(){ exec /usr/local/py3rcon/py3rcon.py --gui ~/py3rcon.config.json } +# List mods +activelist(){ + X=1 + C="${green}" + spaces=" " + have=no + for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null) + do + if [[ ${have} = "no" ]] + then + have="yes" + echo -e "\n ID Name URL Size" + echo "------------------------------------------------------------------------------------------------------------------------" + fi + ID=$(readlink ${link} | awk -F/ '{print $NF}') + MODNAME=$(get_mod_name ${ID}) + SIZE=$(du -sh "${WORKSHOP_DIR}/${ID}" | awk '{print $1}') + printf "${C}%.3d %s %.23s %s https://steamcommunity.com/sharedfiles/filedetails/?id=%s %s${default}\n" ${X} ${ID} "${MODNAME}" "${spaces:${#MODNAME}+1}" ${ID} ${SIZE} + X=$((X+1)) + done + echo +} + # Display the status of everything status(){ loadconfig @@ -385,8 +354,6 @@ status(){ RUNNING="${RUNNING}\nRunning Parameters: $(cat /tmp/parameters)\nRunning mod parameter: $(cat /tmp/mod_command_line)" fi - mod_cmd - MAP="none" # Map name if [[ -f ${SERVER_CFG_DST} ]] @@ -402,9 +369,10 @@ Server files installed: ${INSTALLED}" echo exit 0 fi + get_mods echo -ne " -Mods: " - MODS=$(list) +Active mods: " + activelist if [[ ${MODS} == "" ]] then echo -n "none" @@ -418,6 +386,7 @@ Working mod parameter: ${mod_command_line}" MAP=$(grep template ${SERVER_CFG_DST} | grep -v "^//" | cut -d= -f2 | cut -d\; -f1) echo "Map: ${MAP}" fi + echo } backup(){ @@ -438,8 +407,6 @@ shift || { usage } -get_mods - case "${C}" in a|activate) activate 1 "${@}" @@ -477,7 +444,7 @@ case "${C}" in r|remove) remove "${@}" ;; - restart) + r|restart) restart "${@}" ;; start) diff --git a/web/bin/dz b/web/bin/dz index adc3414..8d2235e 100755 --- a/web/bin/dz +++ b/web/bin/dz @@ -3,7 +3,7 @@ source /files/dz-common # An array to store Workshop items. Each element contains the mod's ID, name, and state (active or not). -WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}" +WORKSHOP_DIR="/mods/${release_client_appid}" workshoplist="" @@ -18,18 +18,96 @@ Usage: ${green}$(basename $0)${yellow} option [ arg1 [ arg2 ] ] Options and arguments: - add id - Add a DayZ Workshop item by id. Added items become active by default + a|add id - Add a DayZ Workshop item by id. Added items become active by default i|install - Install the DayZ server files - l|list - List Workshop items and their details g|login - Login to Steam. m|modupdate - Update the mod files r|remove id - Remove all files and directories of a Workshop item by id - s|status - Shows the server's status: Running, uptime, mods, parameters, mod parameter, etc. + s|status - Shows Steam login status, if base files are installed, installed mods u|update - Update the server files ${default}" exit 1 } +# "Manage" XML files. +xml(){ + /files/mods/xml.sh ${1} +} + +# Copy mod keys +copy_keys(){ + if [[ ${1} = 1 ]] + then + echo "Copying key files..." + find ${WORKSHOP_DIR}/${2} -name "*.bikey" -exec cp -v {} "${SERVER_FILES}/keys/" \; + fi +} + +# Manage the mod symlink +symlink(){ + W=${1} + ID=${2} + NAME=${3} + if [ ! -L "${SERVER_FILES}/@${NAME}" ] && [[ ${W} = 1 ]] + then + ln -sv ${WORKSHOP_DIR}/${ID} "${SERVER_FILES}/@${NAME}" + elif [[ "${W}" = "0" ]] + then + rm -vf "${SERVER_FILES}/@${NAME}" + fi +} + +# Add a mod +add(){ + if [ -d "${WORKSHOP_DIR}/${1}" ] + then + echo -e "${yellow}Warning: The mod directory ${WORKSHOP_DIR}/${1} already exists!${default}" + MODNAME=$(get_mod_name ${1}) + fi + if [ -L "${SERVER_FILES}/@${MODNAME}" ] + then + echo -e "${yellow}Warning: The mod symlink ${SERVER_FILES}/@${MODNAME} already exists!${default}" + fi + echo "Adding mod id ${1}" + dologin + ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" +workshop_download_item "${release_client_appid}" "${1}" +quit + # Make sure the install succeeded + if [ ! -d "${WORKSHOP_DIR}/${1}" ] + then + echo -e "${red}Mod installation failed: The mod directory ${WORKSHOP_DIR}/${1} was not created!${default}" + echo "Installation failed! See above (You probably need to use a real Steam login)" + return + fi + # Get the name of the newly added mod + MODNAME=$(get_mod_name ${1}) + symlink 1 ${1} "${MODNAME}" + # Lower case all the files in mod directories. + find "${WORKSHOP_DIR}/${1}" -depth -exec rename -f 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \; + # Copy the key files + copy_keys 1 ${1} + echo -e "Mod id ${1} - ${green}${MODNAME}${default} - added" +# checkTypesXML ${1} install +# checkInstall ${1} install +} + +# Remove a mod +remove(){ +# checkTypesXML ${1} uninstall +# checkInstall ${1} uninstall + if [ -d "${WORKSHOP_DIR}/${1}" ] + then + MODNAME=$(get_mod_name ${1}) + echo "Removing directory ${WORKSHOP_DIR}/${1}" + rm -rf "${WORKSHOP_DIR}/${1}" + fi + if [ -L "${SERVER_FILES}/@${MODNAME}" ] + then + echo "Removing symlink ${SERVER_FILES}/@${MODNAME}" + rm -f "${SERVER_FILES}/@${MODNAME}" + fi + echo -e "Mod id ${1} - ${red}${MODNAME}${default} - removed" +} + # Handle the Steam login information. login(){ if [ -f "${STEAM_LOGIN}" ] @@ -125,11 +203,28 @@ update(){ fi } +get_mods(){ + workshoplist="" + mod_command_line="" + for link in $(ls -tdr ${SERVER_FILES}/@* 2> /dev/null) + do + ID=$(readlink ${link} | cut -d/ -f7) + MODNAME=$(get_mod_name ${ID}) + workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} + mod_command_line+="@${MODNAME};" + done + if [[ ${mod_command_line} != "" ]] + then + mod_command_line='-mod='${mod_command_line::-1} + fi +} + + # Update mods modupdate(){ echo "Updating mods..." dologin -# echo ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit + get_mods ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit # Updated files come in with mixed cases. Fix that. echo -ne "\nFixing file names..." @@ -187,16 +282,13 @@ shift || { } case "${C}" in - add) + a|add) add "${@}" ;; i|install) install "${@}" ;; - l|list) - list "${@}" - ;; - login) + g|login) login "${@}" ;; m|modupdate) @@ -211,6 +303,9 @@ case "${C}" in u|update) update "${@}" ;; + x|xml) + xml "${@}" + ;; *) usage "$*" ;;