Continue refactoring file locations in the two containers.

Also refactor variables so they're consistent.
Set container names in PS1.
Update docs.
This commit is contained in:
Daniel Ceregatti 2023-05-16 09:03:41 -07:00
parent 206c838f9d
commit 64f162001d
7 changed files with 119 additions and 204 deletions

View file

@ -32,6 +32,8 @@ cd /serverfiles
mv DayZServer DayZServer.release
wget https://cdn.discordapp.com/attachments/491622000935305217/1105089599983853698/DayZServer
chmod 755 DayZServer
exit
docker compose exec server bash
dz start # Will start a vanilla Chernarus map
```
## Configure and Build

View file

@ -36,7 +36,7 @@ services:
- homedir_server:/home/user
- serverfiles:/serverfiles:ro
- mods:/serverfiles/steamapps/workshop/content:ro
- mpmissions:/serverfiles/mpmissions
- mpmissions:/serverfiles/mpmissions:ro
- profiles:/profiles
- ./files:/files
- ./server/bin/dz:/usr/local/bin/dz

View file

@ -31,15 +31,10 @@ release_server_appid=223350
# DayZ release client SteamID. This is for mods, as only the release client has them.
release_client_appid=221100
# Main container base directories
CFG_SRC_FILES="/files"
# Common container base directories
FILES="/files"
SERVER_FILES="/serverfiles"
# Server configuration file
SERVER_CFG_FILE="serverDZ.cfg"
SERVER_CFG_DST="${SERVER_FILES}/${SERVER_CFG_FILE}"
SERVER_CFG_SRC="${CFG_SRC_FILES}/${SERVER_CFG_FILE}"
# Used to check if dayZ is installed
SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer"
@ -47,16 +42,8 @@ SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer"
STEAM_LOGIN="${HOME}/steamlogin"
STEAMCMD=steamcmd
# Workshop. This file will store metadata about what mods are installed.
WORKSHOP_CFG="${HOME}/workshop.cfg"
if [ ! -f "${WORKSHOP_CFG}" ]
then
touch "${WORKSHOP_CFG}"
fi
# An array to store Workshop items. Each element contains the mod's ID, name, and state (active or not).
declare -a workshopID
workshopfolder="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
# Workshop files (mods)
WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
# Other stuff
YES="${green}yes${default}"
@ -64,22 +51,6 @@ NO="${red}no${default}"
# Functions
checkInstall(){
# See if this mod id exists in files/mods, and offer to install other server side files if an install.sh is found
if [ -f /files/mods/${1}/${2}.sh ]
then
echo "An ${2}.sh was found for mod id ${1}. Running..."
/files/mods/${1}/${2}.sh
fi
# A generic map install script. Presumes a git repo as the source
if [ -f /files/mods/${1}/install.env ]
then
echo "An ${2}.env was found for mod id ${1}. Performing ${2}..."
source /files/mods/${1}/install.env
/files/mods/install.sh ${1} ${2}
fi
}
# Convenience function
prompt_yn(){
echo -n "${1} (y|N) " >&2
@ -94,31 +65,37 @@ prompt_yn(){
fi
}
check_install(){
if [ ! -f "${SERVER_INSTALL_FILE}" ]
check_mod_install(){
# See if this mod id exists in files/mods, and offer to install other server side files if an install.sh is found
if [ -f ${FILES}/mods/${1}/${2}.sh ]
then
echo
echo -e "The DayZ server files are not installed. Run '${green}docker-compose run --rm main dayzserver install${default}'"
echo
exit 1
echo "An ${2}.sh was found for mod id ${1}. Running..."
${FILES}/mods/${1}/${2}.sh
fi
# A generic map install script. Presumes a git repo as the source
if [ -f ${FILES}/mods/${1}/install.env ]
then
echo "An ${2}.env was found for mod id ${1}. Performing ${2}..."
source ${FILES}/mods/${1}/install.env
${FILES}/mods/install.sh ${1} ${2}
fi
}
get_mod_id_by_index(){
# If we were passed a valid mod id, just return it
if [[ -d "${workshopdir}/${1}" ]]
if [[ -d "${WORKSHOP_DIR}/${1}" ]]
then
echo ${1}
echo -n ${1}
return
fi
X=1
# Loop over mod list
for i in "${workshopID[@]}"
# Loop over mods
for dir in $(ls -tr ${WORKSHOP_DIR})
do
ID=$(echo ${i} | cut -d: -f1)
ID=${dir}
if [[ ${X} = ${1} ]]
then
echo ${ID}
echo -n ${ID}
return
fi
X=$((X+1))
@ -127,18 +104,31 @@ get_mod_id_by_index(){
# Get mod name by ID or index
get_mod_name(){
# Check for an ID
if [ -d "${workshopfolder}/${1}" ]
then
ID=${1}
else
ID=$(get_mod_id_by_index ${1})
fi
if ! [ -d "${workshopfolder}/${ID}" ]
if ! [ -d "${WORKSHOP_DIR}/${ID}" ]
then
echo "Mod ID ${1} doesn't exist" >&2
exit 1
fi
NAME=$(grep name ${workshopfolder}/${ID}/meta.cpp | cut -d '"' -f2 | sed -r 's/\s+//g')
echo ${NAME}
NAME=$(grep name ${WORKSHOP_DIR}/${ID}/meta.cpp | cut -d '"' -f2 | sed -r 's/\s+//g')
echo -n ${NAME}
}
# List mods
list(){
workshoplist=""
X=1
C="${green}"
spaces=" "
echo -e "\n 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
}

View file

@ -6,7 +6,7 @@ set -eE
ID=${1}
MODE=${2}
TYPES_FILE="${workshopfolder}/${ID}/extras/types.xml"
TYPES_FILE="${WORKSHOP_DIR}/${ID}/extras/types.xml"
if [[ ${3} != "" ]]
then

View file

@ -1,14 +1,10 @@
#!/usr/bin/env bash
# Set PS1 so we know we're in the container
if ! [ -f .bashrc ]
then
echo "Creating .bashrc..."
cat > .bashrc <<EOF
cat > .bashrc <<EOF
alias ls='ls --color'
export PS1="${debian_chroot:+($debian_chroot)}\u@dz-server:\w\$ "
EOF
fi
# Uncomment the line below to run things manually in the container, then run:
# docker compose exec main bash

View file

@ -10,7 +10,7 @@ mkdir -p ${SERVER_PROFILE}/battleye
# Server configuration file
SERVER_CFG_FILE="serverDZ.cfg"
SERVER_CFG_DST="${SERVER_PROFILE}/${SERVER_CFG_FILE}"
SERVER_CFG_SRC="${CFG_SRC_FILES}/${SERVER_CFG_FILE}"
SERVER_CFG_SRC="${FILES}/${SERVER_CFG_FILE}"
# Command line parameters except mod, as that is handled separately.
parameters="-config=${SERVER_CFG_DST} -port=${port} -freezecheck -BEpath=${SERVER_PROFILE}/battleye -profiles=${SERVER_PROFILE} -nologs"
@ -19,7 +19,7 @@ parameters="-config=${SERVER_CFG_DST} -port=${port} -freezecheck -BEpath=${SERVE
SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer"
# Workshop. This file will store metadata about what mods are in use in this server instance
WORKSHOP_CFG="${HOME}/workshop.cfg"
WORKSHOP_CFG="${SERVER_PROFILE}/workshop.cfg"
if [ ! -f "${WORKSHOP_CFG}" ]
then
touch "${WORKSHOP_CFG}"
@ -29,7 +29,7 @@ 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
workshopfolder="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
# Backups
BACKUP_DIR="${HOME}/backup"
@ -63,6 +63,62 @@ ${default}"
exit 1
}
loadconfig(){
if [ ! -f "${SERVER_INSTALL_FILE}" ]
then
echo
echo -e "The DayZ server files are not installed. Run '${green}docker-compose run --rm main dayzserver install${default}'"
echo
exit 1
fi
# Handle the initial server configuration file
if [ ! -f ${SERVER_CFG_DST} ]
then
echo "Creating initial server configuration file"
cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}"
fi
# battleye config and rconpassword setup
# The server creates a new file from this file, which it then uses.
# Let's make sure to delete it first
BE_SERVER_FILE="${SERVER_PROFILE}/battleye/beserver_x64.cfg"
ALT_BE_SERVER_FILE=$(find ${SERVER_PROFILE}/battleye -name "beserver_x64_active*")
if [ ! -f "${BE_SERVER_FILE}" ] && [ ! -f "${ALT_BE_SERVER_FILE}" ]
then
passwd=$(openssl rand -base64 8 | tr -dc 'A-Za-z0-9')
if [ "${passwd}" == "" ]
then
passwd=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10)
fi
if [ "${passwd}" == "" ]
then
printf "[ ${red}FAIL${default} ] Could not generate a passwort for RCON!\nOpen the Battleye config with 'dayzserver rcon'."
exit 1
else
cat > "${BE_SERVER_FILE}" <<EOF
RConPassword ${passwd}
RestrictRCon 0
RConPort ${rcon_port}
EOF
fi
printf "[ ${cyan}INFO${default} ] New RCON password: ${yellow}${passwd}${default}\n"
else
if [ -f "${BE_SERVER_FILE}" ]
then
FILE="${BE_SERVER_FILE}"
elif [ -f "${ALT_BE_SERVER_FILE}" ]
then
FILE="${ALT_BE_SERVER_FILE}"
fi
passwd=$(grep RConPassword ${FILE} | awk '{print $2}')
# printf "[ ${cyan}INFO${default} ] Using existing RCON password: ${yellow}${passwd}${default}\n"
fi
cp /usr/local/py3rcon/configexample.json ~/py3rcon.config.json
jq --arg port 2303 --arg rcon_password b0fNIBVfkM \
'.logfile="py3rcon.log" | .loglevel=0 | .server.port=$port | .server.rcon_password=$rcon_password | del(.repeatMessage)' \
/usr/local/py3rcon/configexample.json \
> ~/py3rcon.config.json
}
# Manage the mod symlink
symlink(){
W=${1}
@ -70,7 +126,7 @@ symlink(){
NAME=${3}
if [ ! -L "${SERVER_FILES}/@${NAME}" ] && [[ ${W} = 1 ]]
then
ln -sv ${workshopfolder}/${ID} "${SERVER_FILES}/@${NAME}"
ln -sv ${WORKSHOP_DIR}/${ID} "${SERVER_FILES}/@${NAME}"
elif [[ "${W}" = "0" ]]
then
rm -vf "${SERVER_FILES}/@${NAME}"
@ -202,18 +258,18 @@ get_mod_id_by_index(){
# Get mod name by ID or index
get_mod_name(){
# Check for an ID
if [ -d "${workshopfolder}/${1}" ]
if [ -d "${WORKSHOP_DIR}/${1}" ]
then
ID=${1}
else
ID=$(get_mod_id_by_index ${1})
fi
if ! [ -d "${workshopfolder}/${ID}" ]
if ! [ -d "${WORKSHOP_DIR}/${ID}" ]
then
echo "Mod ID ${1} doesn't exist" >&2
exit 1
fi
NAME=$(grep name ${workshopfolder}/${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}
}
@ -242,35 +298,6 @@ activate(){
list
}
# List available mods
list(){
get_installed_mods
if [[ "${workshopID[@]}" = "" ]]
then
return
fi
X=1
spaces=" "
echo -e "\n ID Name Active URL Size"
echo "------------------------------------------------------------------------------------------------------------------------"
for i in "${workshopID[@]}"
do
ID=$(echo ${i} | cut -d: -f1)
NAME=$(echo ${i} | cut -d: -f2)
ACTIVE=$(echo ${i} | cut -d: -f3)
SIZE=$(du -sh ${SERVER_FILES}/steamapps/workshop/content/221100/${ID} | awk '{print $1}')
if [[ ${ACTIVE} = "1" ]]
then
C="${green}"
else
C="${red}"
fi
printf "${C}%.3d %s %.23s %s %s https://steamcommunity.com/sharedfiles/filedetails/?id=%s %s${default}\n" ${X} ${ID} "${NAME}" "${spaces:${#NAME}+1}" ${ACTIVE} ${ID} ${SIZE}
X=$((X+1))
done
}
# Assemble the mod command line
mod_cmd(){
mod_command_line=""
@ -301,15 +328,15 @@ checkXML(){
if echo ${!xml} | grep -q http
then
echo "${NAME} file is remote, downloading..."
curl -o ${workshopfolder}/${1}/${NAME}.xml ${!xml}
curl -o ${WORKSHOP_DIR}/${1}/${NAME}.xml ${!xml}
else
echo "${NAME} file is in the mod, copying..."
cp -vf ${!xml} ${workshopfolder}/${1}/${NAME}.xml
cp -vf ${!xml} ${WORKSHOP_DIR}/${1}/${NAME}.xml
fi
done
# else
# See if this mod has a types.xml in the "standard" locations
# for path in "${workshopfolder}/${1}/extras" "${workshopfolder}/${1}"
# for path in "${WORKSHOP_DIR}/${1}/extras" "${WORKSHOP_DIR}/${1}"
# do
# if [ -f "${path}/types.xml" ]
# then
@ -368,7 +395,6 @@ status(){
fi
# Number of mods plus the list denoting on or off
echo -ne "
Logged in to Steam: ${LOGGED_IN} ${ANONYMOUS}
Server files installed: ${INSTALLED}"
if [[ "${INSTALLED}" = "${NO}" ]]
then

View file

@ -2,16 +2,8 @@
source /files/dz-common
# Workshop. This file will store metadata about what mods are installed.
WORKSHOP_CFG="${SERVER_FILES}/workshop.cfg"
if [ ! -f "${WORKSHOP_CFG}" ]
then
touch "${WORKSHOP_CFG}"
fi
# An array to store Workshop items. Each element contains the mod's ID, name, and state (active or not).
declare -a workshopID
workshopfolder="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
WORKSHOP_DIR="${SERVER_FILES}/steamapps/workshop/content/${release_client_appid}"
workshoplist=""
@ -38,63 +30,8 @@ ${default}"
exit 1
}
# Ensures all is installed and ready before allowing operations that depends on things being ready.
# Installs the initial server config file from its template.
# Handles the importing of changes to that template.
# Installs the initial Battleye RCON config.
loadconfig(){
# check_install
# Handle the initial server configuration file
if [ ! -f ${SERVER_CFG_DST} ]
then
echo "Creating initial server configuration file"
cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}"
fi
# battleye config and rconpassword setup
# The server creates a new file from this file, which it then uses.
# Let's make sure to delete it first
BE_SERVER_FILE="${SERVER_FILES}/battleye/beserver_x64.cfg"
ALT_BE_SERVER_FILE=$(find ${SERVER_FILES}/battleye -name "beserver_x64_active*")
if [ ! -f "${BE_SERVER_FILE}" ] && [ ! -f "${ALT_BE_SERVER_FILE}" ]
then
passwd=$(openssl rand -base64 8 | tr -dc 'A-Za-z0-9')
if [ "${passwd}" == "" ]
then
passwd=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10)
fi
if [ "${passwd}" == "" ]
then
printf "[ ${red}FAIL${default} ] Could not generate a passwort for RCON!\nOpen the Battleye config with 'dayzserver rcon'."
exit 1
else
cat > "${BE_SERVER_FILE}" <<EOF
RConPassword ${passwd}
RestrictRCon 0
RConPort ${rcon_port}
EOF
fi
printf "[ ${cyan}INFO${default} ] New RCON password: ${yellow}${passwd}${default}\n"
else
if [ -f "${BE_SERVER_FILE}" ]
then
FILE="${BE_SERVER_FILE}"
elif [ -f "${ALT_BE_SERVER_FILE}" ]
then
FILE="${ALT_BE_SERVER_FILE}"
fi
passwd=$(grep RConPassword ${FILE} | awk '{print $2}')
# printf "[ ${cyan}INFO${default} ] Using existing RCON password: ${yellow}${passwd}${default}\n"
fi
cp /usr/local/py3rcon/configexample.json ~/py3rcon.config.json
jq --arg port 2303 --arg rcon_password b0fNIBVfkM \
'.logfile="py3rcon.log" | .loglevel=0 | .server.port=$port | .server.rcon_password=$rcon_password | del(.repeatMessage)' \
/usr/local/py3rcon/configexample.json \
> ~/py3rcon.config.json
}
# Handle the Steam login information.
login(){
loadconfig
if [ -f "${STEAM_LOGIN}" ]
then
if prompt_yn "The steam login is already set. Reset it?"
@ -122,7 +59,6 @@ login(){
# "Perform" the Steam login. This just sources the file with the Steam login name.
dologin(){
loadconfig
if [ -f "${STEAM_LOGIN}" ]
then
source "${STEAM_LOGIN}"
@ -134,7 +70,6 @@ dologin(){
# Perform the installation of the server files.
install(){
loadconfig
if [ ! -f "${SERVER_INSTALL_FILE}" ] || [[ ${1} = "force" ]]
then
printf "[ ${yellow}DayZ${default} ] Downloading DayZ Server-Files!\n"
@ -198,45 +133,11 @@ modupdate(){
${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" ${workshoplist} +quit
# Updated files come in with mixed cases. Fix that.
echo -ne "\nFixing file names..."
find "${workshopfolder}" -depth -exec rename -f 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
find "${WORKSHOP_DIR}" -depth -exec rename -f 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
echo "done"
echo
}
# List mods
list(){
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
if [[ "${workshopID[@]}" = "" ]]
then
return
fi
X=1
spaces=" "
echo -e "\n ID Name URL Size"
echo "------------------------------------------------------------------------------------------------------------------------"
for i in "${workshopID[@]}"
do
ID=$(echo ${i} | cut -d: -f1)
NAME=$(echo ${i} | cut -d: -f2)
# ACTIVE=$(echo ${i} | cut -d: -f3)
SIZE=$(du -sh ${SERVER_FILES}/steamapps/workshop/content/221100/${ID} | awk '{print $1}')
# if [[ ${ACTIVE} = "1" ]]
# then
C="${green}"
# else
# C="${red}"
# fi
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
}
# Display the status of everything
status(){
INSTALLED="${NO}"