Compare commits

...

7 commits

6 changed files with 82 additions and 57 deletions

View file

@ -16,10 +16,11 @@ This project started when the Linux DayZ server was released for DayZ experiment
* The save file becomes corrupted and when the server restarts so the changes do not persist.
* There are other bugs:
* [Server doesn't stop with SIGTERM](https://feedback.bistudio.com/T170721)
* When deleting a docker volume, permissions are reset, which causes this error: `ERROR! Failed to install app '223350' (Missing file permissions)`. To fix:
* After deleting the `serverfiles` docker volume, permissions are incorrect when restarting the stack, which causes file permissions errors. To fix:
```shell
docker compose run -u0 --rm web chown user:user /serverfiles/steamapps`
docker compose run -u0 --rm web chown user:user /serverfiles -R
```
Unfortunately, this cannot be easily mitigated within the code, so it remains a manual process.
This project is a work in progress: See the [roadmap](ROADMAP.md).

View file

@ -83,7 +83,7 @@ list(){
do
if [[ ${FIRST} = 1 ]]
then
echo
echo "Installed mods:"
echo -e " ID Name URL Size"
echo "-------------------------------------------------------------------------------------------------------------------------"
FIRST=0
@ -114,6 +114,20 @@ get_mod_name(){
echo -n ${NAME}
}
# Lint XML files
lint(){
FILE=${1}
ID=${2}
var=${3}
xmllint --noout ${FILE} && (
# Keep the normalized version in the /mods directory
echo -e "${green}The ${var,,} file passes XML lint test! Copying to install location ${WORKSHOP_DIR}/${ID}/${var,,}.xml${default}"
cp -v ${FILE} ${WORKSHOP_DIR}/${ID}/${var,,}.xml
) || (
echo -e "${yellow}The ${var,,} file does not pass XML lint test! IT WAS NOT COPIED!${default}"
)
}
get_mod_id(){
# If we were passed a valid mod id, just return it
if [ -d "${WORKSHOP_DIR}/${1}" ]

View file

@ -0,0 +1,5 @@
# Merge all the XML files into a single types.xml file in the run time mods directory:
source /files/bin/dz-common
cd /mods/221100/2663169692/files/types
xmlmerge -o /tmp/x *.xml
lint /tmp/x 2663169692 TYPES

View file

@ -586,7 +586,7 @@ status(){
else
RELEASE="Experimental"
fi
VERSION=$(cat /serverfiles/version)
VERSION="$(cat /serverfiles/version) - Release: ${RELEASE}"
# Map
MAP=${MAP}
# Number of mods plus the list denoting on or off

View file

@ -66,9 +66,9 @@ RUN groupadd -g ${USER_ID} user && \
RUN cd /usr/lib/i386-linux-gnu && ln -s /web/bin/steamservice.so
# Add bercon https://github.com/WoozyMasta/bercon
RUN wget https://github.com/WoozyMasta/bercon/releases/download/1.0.0/bercon \
&& chmod +x bercon \
&& mv bercon /usr/bin
RUN wget https://github.com/WoozyMasta/bercon-cli/releases/latest/download/bercon-cli-linux-amd64 -O bercon-cli \
&& chmod +x bercon-cli \
&& mv bercon-cli /usr/bin
# Use our non-privileged user
USER user

View file

@ -6,7 +6,7 @@ source dz-common
WORKSHOP_DIR="/mods/${release_client_appid}"
if [ ! -d ${WORKSHOP_DIR} ]
then
mkdir -p ${WORKSHOP_DIR}
mkdir -p ${WORKSHOP_DIR}
fi
workshoplist=""
@ -15,7 +15,7 @@ workshoplist=""
# Usage
usage(){
echo -e "
echo -e "
${red}Bad option or arguments! ${yellow}${*}${default}
Usage: ${green}$(basename $0)${yellow} option [ arg1 [ arg2 ] ]
@ -50,19 +50,19 @@ symlink(){
}
installxml(){
ID=${1}
# Going to have to maintain a matrix of file names -> root node -> child node permutations
for i in "CFGEVENTGROUPS:eventgroupdef:group" "CFGEVENTSPAWNS:eventposdef:event" "CFGSPAWNABLETYPES:spawnabletypes:type" "EVENTS:events:event" "TYPES:types:type"
do
var=$(echo ${i} | cut -d: -f1)
CHECK=$(echo ${i} | cut -d: -f2)
if [ -f "${WORKSHOP_DIR}/${ID}/${var,,}.xml" ]
then
echo "Normalizing ${WORKSHOP_DIR}/${ID}/${var,,}.xml..."
cp ${WORKSHOP_DIR}/${ID}/${var,,}.xml /tmp/x
# Quirks
# Some cfgeventspanws.xml files have <events> instead of <eventposdef>. Let's just try to fix that first.
if [[ ${var} = "CFGEVENTSPAWNS" ]]
ID=${1}
# Going to have to maintain a matrix of file names -> root node -> child node permutations
for i in "CFGEVENTGROUPS:eventgroupdef:group" "CFGEVENTSPAWNS:eventposdef:event" "CFGSPAWNABLETYPES:spawnabletypes:type" "EVENTS:events:event" "TYPES:types:type"
do
var=$(echo ${i} | cut -d: -f1)
CHECK=$(echo ${i} | cut -d: -f2)
if [ -f "${WORKSHOP_DIR}/${ID}/${var,,}.xml" ]
then
echo "Normalizing ${WORKSHOP_DIR}/${ID}/${var,,}.xml..."
cp ${WORKSHOP_DIR}/${ID}/${var,,}.xml /tmp/x
# Quirks
# Some cfgeventspanws.xml files have <events> instead of <eventposdef>. Let's just try to fix that first.
if [[ ${var} = "CFGEVENTSPAWNS" ]]
then
if grep -q '<events>' /tmp/x
then
@ -70,30 +70,23 @@ installxml(){
xmlstarlet ed -L -r "events" -v "eventposdef" /tmp/x
fi
fi
if ! grep -q '<'${CHECK}'>' /tmp/x
then
echo " - has no root node <${CHECK}>. fixing..."
echo '<'${CHECK}'>' > /tmp/y
cat /tmp/x >> /tmp/y
echo '</'${CHECK}'>' >> /tmp/y
xmlstarlet fo /tmp/y > /tmp/x
fi
if ! grep -q '<?xml' /tmp/x
then
echo " - has no XML node, fixing..."
xmlstarlet fo /tmp/x > /tmp/y
mv /tmp/y /tmp/x
fi
xmllint --noout /tmp/x && (
# Keep the normalized version in the /mods directory
cp /tmp/x ${WORKSHOP_DIR}/${ID}/${var,,}.xml
echo -e "${green}${WORKSHOP_DIR}/${ID}/${var,,}.xml passes XML lint test!${default}"
) || (
echo -e "${yellow}The final ${WORKSHOP_DIR}/${ID}/${var,,}.xml does not pass XML lint test! IT WAS NOT COPIED!${default}"
)
fi
done
exit 0
if ! grep -q '<'${CHECK}'>' /tmp/x
then
echo " - has no root node <${CHECK}>. fixing..."
echo '<'${CHECK}'>' > /tmp/y
cat /tmp/x >> /tmp/y
echo '</'${CHECK}'>' >> /tmp/y
xmlstarlet fo /tmp/y > /tmp/x
fi
if ! grep -q '<?xml' /tmp/x
then
echo " - has no XML node, fixing..."
xmlstarlet fo /tmp/x > /tmp/y
mv /tmp/y /tmp/x
fi
lint /tmp/x ${ID} ${var}
fi
done
}
# Add a mod
@ -122,6 +115,7 @@ add(){
symlink 1 ${1} "${MODNAME}"
echo -e "Mod id ${1} - ${green}${MODNAME}${default} - added"
xml ${ID}
installMod ${ID}
map ${ID}
}
@ -146,6 +140,18 @@ remove(){
echo -e "Mod id ${1} - ${red}${MODNAME}${default} - removed"
}
# Handle custom scripts after installing a mod
installMod(){
FILE="${FILES}/mods/${1}/install.sh"
if [ -f "${FILE}" ]
then
MODNAME=$(get_mod_name ${1})
echo
echo "Running custom install script for ${MODNAME}"
${FILE}
fi
}
# Handle the Steam login information.
login(){
if [ -f "${STEAM_LOGIN}" ]
@ -262,7 +268,7 @@ function getVersion() {
else
RELEASE="Experimental"
fi
echo "${VERSION} - ${RELEASE}"
echo "${VERSION} - Release: ${RELEASE}"
}
# Update mods
@ -312,8 +318,7 @@ Server files installed: ${INSTALLED}"
Version: ${VERSION}"
# Mods
echo -ne "
Mods: "
echo
MODS=$(list)
if [[ ${MODS} == "" ]]
then
@ -324,14 +329,14 @@ Mods: "
map(){
# Install map mpmissions for mods that have them. Presumes a map.env was created for the mod, with the required metadata (git URL, etc.)
TERM="map"
if [[ "${1}" =~ ^[0-9]+$ ]]
then
TERM="mod id"
fi
WHICH="map"
if [[ "${1}" =~ ^[0-9]+$ ]]
then
WHICH="mod id"
fi
if [ -f "${FILES}/mods/${1}/map.env" ]
then
echo "Installing mpmissions files for ${TERM} ${1}..."
echo "Installing mpmissions files for ${WHICH} ${1}..."
source ${FILES}/mods/${1}/map.env
${FILES}/bin/map.sh ${1} install
fi
@ -348,8 +353,8 @@ mod_install(){
# "Manage" XML files.
xml(){
/files/bin/xml.sh ${1}
installxml ${1}
/files/bin/xml.sh ${1}
installxml ${1}
}
# Capture the first argument and shift it off so we can pass $@ to every function