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. * The save file becomes corrupted and when the server restarts so the changes do not persist.
* There are other bugs: * There are other bugs:
* [Server doesn't stop with SIGTERM](https://feedback.bistudio.com/T170721) * [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 ```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). This project is a work in progress: See the [roadmap](ROADMAP.md).

View file

@ -83,7 +83,7 @@ list(){
do do
if [[ ${FIRST} = 1 ]] if [[ ${FIRST} = 1 ]]
then then
echo echo "Installed mods:"
echo -e " ID Name URL Size" echo -e " ID Name URL Size"
echo "-------------------------------------------------------------------------------------------------------------------------" echo "-------------------------------------------------------------------------------------------------------------------------"
FIRST=0 FIRST=0
@ -114,6 +114,20 @@ get_mod_name(){
echo -n ${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(){ get_mod_id(){
# 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}" ]

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 else
RELEASE="Experimental" RELEASE="Experimental"
fi fi
VERSION=$(cat /serverfiles/version) VERSION="$(cat /serverfiles/version) - Release: ${RELEASE}"
# Map # Map
MAP=${MAP} MAP=${MAP}
# Number of mods plus the list denoting on or off # 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 RUN cd /usr/lib/i386-linux-gnu && ln -s /web/bin/steamservice.so
# Add bercon https://github.com/WoozyMasta/bercon # Add bercon https://github.com/WoozyMasta/bercon
RUN wget https://github.com/WoozyMasta/bercon/releases/download/1.0.0/bercon \ RUN wget https://github.com/WoozyMasta/bercon-cli/releases/latest/download/bercon-cli-linux-amd64 -O bercon-cli \
&& chmod +x bercon \ && chmod +x bercon-cli \
&& mv bercon /usr/bin && mv bercon-cli /usr/bin
# Use our non-privileged user # Use our non-privileged user
USER user USER user

View file

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