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...
This commit is contained in:
Daniel Ceregatti 2023-05-18 17:29:27 -07:00
parent 64f162001d
commit 2fc31fea37
9 changed files with 211 additions and 190 deletions

View file

@ -22,7 +22,7 @@ services:
- homedir_main:/home/user - homedir_main:/home/user
- serverfiles:/serverfiles - serverfiles:/serverfiles
- mods:/serverfiles/steamapps/workshop/content - mods:/serverfiles/steamapps/workshop/content
- mpmissions:/serverfiles/mpmissions - mods:/mods
- ./files:/files - ./files:/files
- ./web/bin/dz:/usr/local/bin/dz - ./web/bin/dz:/usr/local/bin/dz
- ./web:/web - ./web:/web
@ -34,9 +34,9 @@ services:
build: server build: server
volumes: volumes:
- homedir_server:/home/user - homedir_server:/home/user
- serverfiles:/serverfiles:ro - serverfiles:/serverfiles
- mods:/serverfiles/steamapps/workshop/content:ro - mods:/mods
- mpmissions:/serverfiles/mpmissions:ro - mpmissions:/serverfiles/mpmissions
- profiles:/profiles - profiles:/profiles
- ./files:/files - ./files:/files
- ./server/bin/dz:/usr/local/bin/dz - ./server/bin/dz:/usr/local/bin/dz

View file

@ -81,9 +81,9 @@ check_mod_install(){
fi fi
} }
get_mod_id_by_index(){ get_mod_id_by_index2(){
# If we were passed a valid mod id, just return it # If we were passed a valid mod id, just return it
if [[ -d "${WORKSHOP_DIR}/${1}" ]] if [ -d "${WORKSHOP_DIR}/${1}" ]
then then
echo -n ${1} echo -n ${1}
return return
@ -104,7 +104,7 @@ get_mod_id_by_index(){
# Get mod name by ID or index # Get mod name by ID or index
get_mod_name(){ get_mod_name(){
ID=$(get_mod_id_by_index ${1}) ID=$(get_mod_id_by_index2 ${1})
if ! [ -d "${WORKSHOP_DIR}/${ID}" ] if ! [ -d "${WORKSHOP_DIR}/${ID}" ]
then then
echo "Mod ID ${1} doesn't exist" >&2 echo "Mod ID ${1} doesn't exist" >&2
@ -116,19 +116,19 @@ get_mod_name(){
# List mods # List mods
list(){ list(){
workshoplist=""
X=1 X=1
C="${green}" C="${green}"
spaces=" " spaces=" "
echo -e "\n ID Name URL Size" echo "Installed mods:"
echo -e " ID Name URL Size"
echo "------------------------------------------------------------------------------------------------------------------------" echo "------------------------------------------------------------------------------------------------------------------------"
for dir in $(ls -tr ${WORKSHOP_DIR}) for dir in $(ls -tr ${WORKSHOP_DIR})
do do
ID=${dir} ID=${dir}
NAME=$(grep name "${WORKSHOP_DIR}/${dir}/meta.cpp" | cut -d '"' -f2 | sed -r 's/\s+//g') 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}') 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} 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)) X=$((X+1))
done done
echo
} }

View file

@ -1,8 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
CFGSPAWNABLETYPES=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Event%20Spawn%20Config/RFFSHelis_cfgspawnabletypes.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/Chernarus/RFFSHelis_cfgeventspawns.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/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 #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 TYPES=https://raw.githubusercontent.com/RedFalconKen/RedFalconFlightSystem-Heliz/main/Config%20Files/Types.XML/RFFSHelis_Types.xml

View file

@ -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

25
files/mods/xml.sh Executable file
View file

@ -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

View file

@ -85,8 +85,8 @@ class Missions
{ {
template="dayzOffline.chernarusplus"; // Chernarus template="dayzOffline.chernarusplus"; // Chernarus
// template="dayzOffline.enoch"; // Livonia // template="dayzOffline.enoch"; // Livonia
// template="empty.banov" // Banov // template="empty.banov"; // Banov
// template="empty.deerisle" // Deer Isle // template="empty.deerisle"; // Deer Isle
// template="serverMission.Pripyat" // Pripyat // template="serverMission.Pripyat"; // Pripyat
}; };
}; };

View file

@ -23,6 +23,7 @@ RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-reco
nano \ nano \
procps \ procps \
python3-pip \ python3-pip \
strace \
wget wget
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1 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 # Setup a non-privileged user
RUN groupadd user && \ RUN groupadd user && \
useradd -l -g user user && \ useradd -l -g user user && \
mkdir -p /home/user /serverfiles/mpmissions /serverfiles/steamapps/workshop/content /profiles /mods && \ mkdir -p /home/user /serverfiles/mpmissions /mods /mpmissions /profiles && \
chown -R user:user /home/user /serverfiles /profiles /mods chown -R user:user /home/user /serverfiles /mods /mpmissions /profiles
# Use our non-privileged user # Use our non-privileged user
USER user USER user

View file

@ -18,18 +18,10 @@ parameters="-config=${SERVER_CFG_DST} -port=${port} -freezecheck -BEpath=${SERVE
# Used to check if dayZ is installed # Used to check if dayZ is installed
SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer" 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). # 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 # Backups
BACKUP_DIR="${HOME}/backup" 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 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 l|list - List Workshop items and their details
n|rcon - Connect to the server using a python RCON client 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. s|status - Shows the server's status: Running, uptime, mods, parameters, mod parameter, etc.
stop - Stop the server stop - Stop the server
${default}" ${default}"
@ -119,17 +111,19 @@ EOF
> ~/py3rcon.config.json > ~/py3rcon.config.json
} }
# Manage the mod symlink get_mods(){
symlink(){ workshoplist=""
W=${1} mod_command_line=""
ID=${2} for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null)
NAME=${3} do
if [ ! -L "${SERVER_FILES}/@${NAME}" ] && [[ ${W} = 1 ]] 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 then
ln -sv ${WORKSHOP_DIR}/${ID} "${SERVER_FILES}/@${NAME}" mod_command_line="-mod=${mod_command_line::-1}"
elif [[ "${W}" = "0" ]]
then
rm -vf "${SERVER_FILES}/@${NAME}"
fi fi
} }
@ -155,7 +149,7 @@ start(){
trap ' trap '
report report
' EXIT ' EXIT
mod_cmd get_mods
cd ${SERVER_FILES} 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 # 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. # safely shut the container down without killing the server within.
@ -164,7 +158,7 @@ start(){
# actual status with those # actual status with those
echo ${mod_command_line} > /tmp/mod_command_line echo ${mod_command_line} > /tmp/mod_command_line
echo ${parameters} > /tmp/parameters echo ${parameters} > /tmp/parameters
./DayZServer ${mod_command_line} ${parameters} ./DayZServer "${mod_command_line}" ${parameters}
EXIT_CODE=$? EXIT_CODE=$?
if [ -f ${SERVER_FILES}/restart ] if [ -f ${SERVER_FILES}/restart ]
then then
@ -213,42 +207,15 @@ config(){
fi 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(){ 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 X=1
# Loop over mod list # Loop over mods
for i in "${workshopID[@]}" for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null)
do do
ID=$(echo ${i} | cut -d: -f1) ID=$(readlink ${link} | awk -F/ '{print $NF}')
if [[ ${X} = ${1} ]] if [[ ${X} = ${1} ]]
then then
echo ${ID} echo -n ${ID}
return return
fi fi
X=$((X+1)) X=$((X+1))
@ -258,19 +225,13 @@ get_mod_id_by_index(){
# Get mod name by ID or index # Get mod name by ID or index
get_mod_name(){ get_mod_name(){
# Check for an ID # 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}" ] if ! [ -d "${WORKSHOP_DIR}/${ID}" ]
then then
echo "Mod ID ${1} doesn't exist" >&2 echo "Mod ID ${1} doesn't exist" >&2
exit 1 exit 1
fi fi
NAME=$(grep name ${WORKSHOP_DIR}/${ID}/meta.cpp | cut -d '"' -f2 | sed -r 's/\s+//g') 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 # Activate / Deactivate a mod
@ -285,35 +246,20 @@ activate(){
UU="un" UU="un"
COLOR="${red}" COLOR="${red}"
fi fi
ID=$(get_mod_id_by_index ${1}) ID=$(get_mod_id_by_index2 ${1})
MODNAME=$(get_mod_name ${1}) MODNAME=$(get_mod_name ${ID})
# Toggle state or report nothing burger # Toggle state or report nothing burger
if [[ "${ACTIVE}" != "${W}" ]] pushd "${SERVER_PROFILE}" > /dev/null
if [ -L "${SERVER_PROFILE}/@${MODNAME}" ]
then then
sed -i "${WORKSHOP_CFG}" -e "s/${ID}:${MODNAME}:[0-1]/${ID}:${MODNAME}:${W}/" rm -vf "${SERVER_PROFILE}/@${MODNAME}"
echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} ${WW}activated"
else else
echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} - is already ${WW}active" ln -s "${WORKSHOP_DIR}/${ID}" "${SERVER_PROFILE}/@${MODNAME}"
fi # echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} - is already ${WW}active"
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}
fi fi
echo -e "Mod id ${ID} - ${COLOR}${MODNAME}${default} ${WW}activated"
popd > /dev/null
status
} }
checkXML(){ checkXML(){
@ -359,6 +305,29 @@ rcon(){
exec /usr/local/py3rcon/py3rcon.py --gui ~/py3rcon.config.json 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 # Display the status of everything
status(){ status(){
loadconfig loadconfig
@ -385,8 +354,6 @@ status(){
RUNNING="${RUNNING}\nRunning Parameters: $(cat /tmp/parameters)\nRunning mod parameter: $(cat /tmp/mod_command_line)" RUNNING="${RUNNING}\nRunning Parameters: $(cat /tmp/parameters)\nRunning mod parameter: $(cat /tmp/mod_command_line)"
fi fi
mod_cmd
MAP="none" MAP="none"
# Map name # Map name
if [[ -f ${SERVER_CFG_DST} ]] if [[ -f ${SERVER_CFG_DST} ]]
@ -402,9 +369,10 @@ Server files installed: ${INSTALLED}"
echo echo
exit 0 exit 0
fi fi
get_mods
echo -ne " echo -ne "
Mods: " Active mods: "
MODS=$(list) activelist
if [[ ${MODS} == "" ]] if [[ ${MODS} == "" ]]
then then
echo -n "none" 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) MAP=$(grep template ${SERVER_CFG_DST} | grep -v "^//" | cut -d= -f2 | cut -d\; -f1)
echo "Map: ${MAP}" echo "Map: ${MAP}"
fi fi
echo
} }
backup(){ backup(){
@ -438,8 +407,6 @@ shift || {
usage usage
} }
get_mods
case "${C}" in case "${C}" in
a|activate) a|activate)
activate 1 "${@}" activate 1 "${@}"
@ -477,7 +444,7 @@ case "${C}" in
r|remove) r|remove)
remove "${@}" remove "${@}"
;; ;;
restart) r|restart)
restart "${@}" restart "${@}"
;; ;;
start) start)

View file

@ -3,7 +3,7 @@
source /files/dz-common source /files/dz-common
# An array to store Workshop items. Each element contains the mod's ID, name, and state (active or not). # 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="" workshoplist=""
@ -18,18 +18,96 @@ Usage: ${green}$(basename $0)${yellow} option [ arg1 [ arg2 ] ]
Options and arguments: 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 i|install - Install the DayZ server files
l|list - List Workshop items and their details
g|login - Login to Steam. g|login - Login to Steam.
m|modupdate - Update the mod files m|modupdate - Update the mod files
r|remove id - Remove all files and directories of a Workshop item by id 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 u|update - Update the server files
${default}" ${default}"
exit 1 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. # Handle the Steam login information.
login(){ login(){
if [ -f "${STEAM_LOGIN}" ] if [ -f "${STEAM_LOGIN}" ]
@ -125,11 +203,28 @@ update(){
fi 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 # Update mods
modupdate(){ modupdate(){
echo "Updating mods..." echo "Updating mods..."
dologin dologin
# echo ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit get_mods
${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit
# Updated files come in with mixed cases. Fix that. # Updated files come in with mixed cases. Fix that.
echo -ne "\nFixing file names..." echo -ne "\nFixing file names..."
@ -187,16 +282,13 @@ shift || {
} }
case "${C}" in case "${C}" in
add) a|add)
add "${@}" add "${@}"
;; ;;
i|install) i|install)
install "${@}" install "${@}"
;; ;;
l|list) g|login)
list "${@}"
;;
login)
login "${@}" login "${@}"
;; ;;
m|modupdate) m|modupdate)
@ -211,6 +303,9 @@ case "${C}" in
u|update) u|update)
update "${@}" update "${@}"
;; ;;
x|xml)
xml "${@}"
;;
*) *)
usage "$*" usage "$*"
;; ;;