From 0ad721b1e0329bbfc0b50399278bc3a2460ba583 Mon Sep 17 00:00:00 2001
From: DeathByDenim
Date: Fri, 26 May 2023 16:41:57 -0400
Subject: [PATCH] Copy of gameserver with minimal website
---
.gitignore | 12 +-
README.md | 84 +++-
configs/supertuxkart.xml | 170 ++++++++
deploy.sh | 156 +++++++
pack_web_offline.sh | 77 ++++
scripts/deploy_armagetron_advanced.sh | 57 +++
scripts/deploy_bzflag.sh | 94 ++++
scripts/deploy_cortexcommand.sh | 117 +++++
scripts/deploy_hedgewars.sh | 46 ++
scripts/deploy_lix.sh | 60 +++
scripts/deploy_mindustry.sh | 63 +++
scripts/deploy_minetest.sh | 75 ++++
scripts/deploy_monitoring.sh | 37 ++
scripts/deploy_odamex.sh | 117 +++++
scripts/deploy_openhv.sh | 51 +++
scripts/deploy_opensoldat.sh | 232 ++++++++++
scripts/deploy_openspades.sh | 78 ++++
scripts/deploy_shatteredparadise.sh | 51 +++
scripts/deploy_supertuxkart.sh | 59 +++
scripts/deploy_supertuxparty.sh | 50 +++
scripts/deploy_teeworlds-ddrace.sh | 90 ++++
scripts/deploy_teeworlds.sh | 137 ++++++
scripts/deploy_ufoai.sh | 46 ++
scripts/deploy_unvanquished.sh | 86 ++++
scripts/deploy_webserver.sh | 117 +++++
scripts/deploy_xonotic-br.sh | 88 ++++
scripts/deploy_xonotic.sh | 92 ++++
website/_data/events.yml | 99 +++++
website/_data/games.yml | 118 +++++
website/_includes/event.html | 24 ++
website/_includes/nav.html | 28 ++
website/_includes/offline.html | 2 +
website/_includes/online.html | 21 +
website/_layouts/default.html | 32 ++
website/_layouts/help.html | 13 +
website/_layouts/post.html | 8 +
website/_posts/2023-05-06-more-bananas.md | 6 +
website/_posts/2023-05-08-bananas.md | 6 +
website/_sass/base.scss | 71 +++
website/admin.html | 10 +
website/assets/css/help.css | 15 +
website/assets/css/main.scss | 5 +
website/assets/css/serverstats.css | 39 ++
website/assets/css/terminal.css | 121 ++++++
website/assets/img/armagetron.png | Bin 0 -> 63793 bytes
website/assets/img/bzflag.png | Bin 0 -> 123769 bytes
website/assets/img/element_interface.png | Bin 0 -> 46498 bytes
website/assets/img/hedgewars.png | Bin 0 -> 89289 bytes
website/assets/img/help_bzflag.png | Bin 0 -> 208648 bytes
website/assets/img/help_hedgewars.png | Bin 0 -> 37420 bytes
website/assets/img/help_mindustry.png | Bin 0 -> 100600 bytes
website/assets/img/help_minetest.png | Bin 0 -> 26750 bytes
website/assets/img/help_openhv.png | Bin 0 -> 63127 bytes
website/assets/img/help_openspades.png | Bin 0 -> 97536 bytes
website/assets/img/help_shatteredparadise.png | Bin 0 -> 159565 bytes
website/assets/img/help_supertuxkart.png | Bin 0 -> 62813 bytes
website/assets/img/help_teeworlds_name.png | Bin 0 -> 158862 bytes
website/assets/img/help_teeworlds_server.png | Bin 0 -> 72364 bytes
website/assets/img/help_ufoai.png | Bin 0 -> 108610 bytes
website/assets/img/help_ufoai_connect.png | Bin 0 -> 45955 bytes
website/assets/img/help_unvanquished.png | Bin 0 -> 23170 bytes
website/assets/img/help_xonotic.png | Bin 0 -> 168868 bytes
website/assets/img/icon.svg | 408 ++++++++++++++++++
website/assets/img/lix.png | Bin 0 -> 16471 bytes
website/assets/img/mindustry.png | Bin 0 -> 107819 bytes
website/assets/img/minetest.png | Bin 0 -> 127084 bytes
website/assets/img/movim_interface.png | Bin 0 -> 37806 bytes
website/assets/img/movim_interface2.png | Bin 0 -> 24182 bytes
website/assets/img/mumble_interface.png | Bin 0 -> 46522 bytes
website/assets/img/odamex.png | Bin 0 -> 159042 bytes
website/assets/img/openhv.png | Bin 0 -> 166280 bytes
website/assets/img/opensoldat.png | Bin 0 -> 97173 bytes
website/assets/img/openspades.png | Bin 0 -> 66820 bytes
website/assets/img/shatteredparadise.png | Bin 0 -> 194467 bytes
website/assets/img/supertuxkart.png | Bin 0 -> 137722 bytes
website/assets/img/supertuxparty.png | Bin 0 -> 119535 bytes
website/assets/img/teeworlds.png | Bin 0 -> 51799 bytes
website/assets/img/ufoai.png | Bin 0 -> 167275 bytes
website/assets/img/unvanquished.png | Bin 0 -> 129022 bytes
website/assets/img/xonotic.png | Bin 0 -> 179091 bytes
website/assets/js/terminalcolors.js | 117 +++++
website/help.html | 12 +
website/help_armagetron.html | 19 +
website/help_bzflag.html | 18 +
website/help_hedgewars.html | 34 ++
website/help_lix.html | 17 +
website/help_mindustry.html | 22 +
website/help_minetest.html | 19 +
website/help_odamex.html | 17 +
website/help_openhv.html | 30 ++
website/help_opensoldat.html | 20 +
website/help_openspades.html | 53 +++
website/help_shatteredparadise.html | 30 ++
website/help_supertuxkart.html | 28 ++
website/help_supertuxparty.html | 4 +
website/help_teeworlds.html | 17 +
website/help_ufoai.html | 25 ++
website/help_unvanquished.html | 20 +
website/help_xonotic.html | 28 ++
website/index.html | 45 ++
website/js/consoles.js | 150 +++++++
website/js/serverstats.js | 60 +++
website/js/xonscore.js | 137 ++++++
website/schedule.html | 18 +
website/tournament.html | 52 +++
105 files changed, 4350 insertions(+), 10 deletions(-)
create mode 100644 configs/supertuxkart.xml
create mode 100755 deploy.sh
create mode 100755 pack_web_offline.sh
create mode 100755 scripts/deploy_armagetron_advanced.sh
create mode 100755 scripts/deploy_bzflag.sh
create mode 100755 scripts/deploy_cortexcommand.sh
create mode 100755 scripts/deploy_hedgewars.sh
create mode 100755 scripts/deploy_lix.sh
create mode 100755 scripts/deploy_mindustry.sh
create mode 100755 scripts/deploy_minetest.sh
create mode 100755 scripts/deploy_monitoring.sh
create mode 100755 scripts/deploy_odamex.sh
create mode 100755 scripts/deploy_openhv.sh
create mode 100755 scripts/deploy_opensoldat.sh
create mode 100755 scripts/deploy_openspades.sh
create mode 100755 scripts/deploy_shatteredparadise.sh
create mode 100755 scripts/deploy_supertuxkart.sh
create mode 100755 scripts/deploy_supertuxparty.sh
create mode 100755 scripts/deploy_teeworlds-ddrace.sh
create mode 100755 scripts/deploy_teeworlds.sh
create mode 100755 scripts/deploy_ufoai.sh
create mode 100755 scripts/deploy_unvanquished.sh
create mode 100755 scripts/deploy_webserver.sh
create mode 100755 scripts/deploy_xonotic-br.sh
create mode 100755 scripts/deploy_xonotic.sh
create mode 100644 website/_data/events.yml
create mode 100644 website/_data/games.yml
create mode 100644 website/_includes/event.html
create mode 100644 website/_includes/nav.html
create mode 100644 website/_includes/offline.html
create mode 100644 website/_includes/online.html
create mode 100644 website/_layouts/default.html
create mode 100644 website/_layouts/help.html
create mode 100644 website/_layouts/post.html
create mode 100644 website/_posts/2023-05-06-more-bananas.md
create mode 100644 website/_posts/2023-05-08-bananas.md
create mode 100644 website/_sass/base.scss
create mode 100644 website/admin.html
create mode 100644 website/assets/css/help.css
create mode 100644 website/assets/css/main.scss
create mode 100644 website/assets/css/serverstats.css
create mode 100644 website/assets/css/terminal.css
create mode 100644 website/assets/img/armagetron.png
create mode 100644 website/assets/img/bzflag.png
create mode 100644 website/assets/img/element_interface.png
create mode 100644 website/assets/img/hedgewars.png
create mode 100644 website/assets/img/help_bzflag.png
create mode 100644 website/assets/img/help_hedgewars.png
create mode 100644 website/assets/img/help_mindustry.png
create mode 100644 website/assets/img/help_minetest.png
create mode 100644 website/assets/img/help_openhv.png
create mode 100644 website/assets/img/help_openspades.png
create mode 100644 website/assets/img/help_shatteredparadise.png
create mode 100644 website/assets/img/help_supertuxkart.png
create mode 100644 website/assets/img/help_teeworlds_name.png
create mode 100644 website/assets/img/help_teeworlds_server.png
create mode 100644 website/assets/img/help_ufoai.png
create mode 100644 website/assets/img/help_ufoai_connect.png
create mode 100644 website/assets/img/help_unvanquished.png
create mode 100644 website/assets/img/help_xonotic.png
create mode 100644 website/assets/img/icon.svg
create mode 100644 website/assets/img/lix.png
create mode 100644 website/assets/img/mindustry.png
create mode 100644 website/assets/img/minetest.png
create mode 100644 website/assets/img/movim_interface.png
create mode 100644 website/assets/img/movim_interface2.png
create mode 100644 website/assets/img/mumble_interface.png
create mode 100644 website/assets/img/odamex.png
create mode 100644 website/assets/img/openhv.png
create mode 100644 website/assets/img/opensoldat.png
create mode 100644 website/assets/img/openspades.png
create mode 100644 website/assets/img/shatteredparadise.png
create mode 100644 website/assets/img/supertuxkart.png
create mode 100644 website/assets/img/supertuxparty.png
create mode 100644 website/assets/img/teeworlds.png
create mode 100644 website/assets/img/ufoai.png
create mode 100644 website/assets/img/unvanquished.png
create mode 100644 website/assets/img/xonotic.png
create mode 100644 website/assets/js/terminalcolors.js
create mode 100644 website/help.html
create mode 100644 website/help_armagetron.html
create mode 100644 website/help_bzflag.html
create mode 100644 website/help_hedgewars.html
create mode 100644 website/help_lix.html
create mode 100644 website/help_mindustry.html
create mode 100644 website/help_minetest.html
create mode 100644 website/help_odamex.html
create mode 100644 website/help_openhv.html
create mode 100644 website/help_opensoldat.html
create mode 100644 website/help_openspades.html
create mode 100644 website/help_shatteredparadise.html
create mode 100644 website/help_supertuxkart.html
create mode 100644 website/help_supertuxparty.html
create mode 100644 website/help_teeworlds.html
create mode 100644 website/help_ufoai.html
create mode 100644 website/help_unvanquished.html
create mode 100644 website/help_xonotic.html
create mode 100644 website/index.html
create mode 100644 website/js/consoles.js
create mode 100644 website/js/serverstats.js
create mode 100644 website/js/xonscore.js
create mode 100644 website/schedule.html
create mode 100644 website/tournament.html
diff --git a/.gitignore b/.gitignore
index c7038cd..03eedc8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,5 @@
-# ---> Jekyll
-_site/
.sass-cache/
-.jekyll-cache/
-.jekyll-metadata
-# Ignore folders generated by Bundler
-.bundle/
-vendor/
-
+website/_sass/bootstrap/
+website/_site/
+website/_config.yml
+web.tar.bz2
diff --git a/README.md b/README.md
index f1b9f11..16b36ef 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,83 @@
-# Gameserver
+# Game server
-The official general gameserver repository for onFOSS events.
\ No newline at end of file
+This is a collection of scripts to deploy game servers on Debian 11. All game
+servers are wrapped in SystemD units and can be controlled by systemctl.
+
+It also comes with a web front end which features the games hosted as well as
+their respective download link. It also displays server stats and has an admin
+panel for game servers that have interactive shells.
+
+The following games are deployed:
+
+* Armagetron Advanced
+* Bzflag
+* Hedgewars
+* Lix
+* Mindustry
+* Minetest (Blockbomber mod)
+* Odamex
+* OpenHV
+* OpenSpades
+* OpenSoldat
+* Shattered Paradise
+* SuperTuxKart
+* Super Tux Party
+* Teeworlds (optionally as DDrace)
+* UFO: Alien Invasion
+* Unvanquished
+* Xonotic (optionally as Battle Royale)
+
+It is based on https://git.libregaming.org/c/onFOSS-LAN-Serverconfiguration
+
+## Installation
+
+The main script is `deploy.sh`. You only need to give if your domain name and your own name.
+```
+DOMAINNAME=play.jarno.ca HOSTEDBYNAME=DeathByDenim ./deploy.sh
+```
+This will download all the game servers, install them, configure them, and start them up. It should take less than an hour for all game servers to be up and running.
+
+If you don't have a domainname, just use the IP address.
+
+It also retrieves a certificate for Let's Encrypt for the web interface. If you don't want the certificate, you can also specify `NOSSL=1`. This will also convert all internal links to http, meaning that if you add a certificate later things will break due to modern browser not allowing mixed http/https content.
+
+There is also support for generating just the website without the game server which is useful if you want to host the website somewhere else while your main server is down.
+```
+DOMAINNAME=play.jarno.ca HOSTEDBYNAME=DeathByDenim ./pack_web_offline.sh
+```
+The webpage will display "OFFLINE" and not attempt to show the server stats.
+
+The password for the admin panel as well as for game servers that support admin password is stored in `/etc/gameserverpassword`. The username for the admin panel is just `onfoss`.
+
+## Website
+
+The website is generated using Jekyll which uses a config.yml that is generated by the deploy script. Additionally, there is a YAML file called events.yml in the _data directory where events are stored. The formatting is:
+
+```
+- date: 2022-12-17T14:00:00UTC
+ intro: "onFOSS-LAN hosted by DeathByDenim"
+ games:
+ - time: "14:00"
+ title: "Get together"
+ - time: "14:30"
+ title: "Doom (ODAMEX) XMAS mod"
+ - time: "15:15"
+ title: "Teeworlds"
+ tournament: true
+ - time: "16:00"
+ title: "OpenSpades"
+ - time: "17:00"
+ title: "Break"
+ - time: "18:00"
+ title: "Lix"
+ - time: "18:30"
+ title: "Free Play!"
+ extras: ["Shattered Paradise"]
+```
+Each game must have a title and it optionally can have a time as well. The optional field extras lists games that were played as part of a bigger category, in this example the free play section.
+
+Finally, you can also specify tournament which will make this game appear in the tournament page.
+
+## Repository
+
+The main version of this git repository is on [git.libregaming.org](https://git.libregaming.org/DeathByDenim/gameserver). There is a mirror on [Github](https://github.com/DeathByDenim/gameserver)
diff --git a/configs/supertuxkart.xml b/configs/supertuxkart.xml
new file mode 100644
index 0000000..75be701
--- /dev/null
+++ b/configs/supertuxkart.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..c40875c
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,156 @@
+#!/bin/bash
+
+# Collection of scripts to deploy a server hosting several open-source games
+# Copyright (C) 2022 Jarno van der Kolk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+### Deploy script for a game server running multiple open-source game servers
+### This script is intended for Debian 11, but may work on other apt-based
+### systems too
+###
+### Specify domain name:
+### DOMAINNAME=example.com HOSTEDBYNAME=DeathByDenim ./deploy.sh
+
+set -e
+
+if [ -z $DOMAINNAME ]; then
+ echo "Domain name was not set. Please export DOMAINNAME first"
+ exit 1
+fi
+if [ -z $HOSTEDBYNAME ]; then
+ echo "Hosted-by name was not set. Please export HOSTEDBYNAME first"
+ exit 1
+fi
+
+export stk_version="latest"
+export bzflag_version="2.4"
+export mindustry_version="latest"
+export odamex_version="latest"
+export openhv_version="latest"
+export teeworlds_version="latest"
+export teeworldsddrace_version="16.1"
+export unvanquished_version="latest"
+export xonotic_version="0.8.5"
+export lix_version="latest"
+export shatteredparadise_version="latest"
+
+export systemuser="onfoss"
+export letsencryptemail="jarno@jarno.ca"
+
+# Store the randomly generated password. This is used for the web interface
+# as well as for admin access for the game servers
+if [ -f /etc/gameserverpassword ]; then
+ export systempassword=$(cat /etc/gameserverpassword)
+else
+ export systempassword="$(< /dev/urandom tr -dc a-z | head -c${1:-8};echo;)"
+ echo "$systempassword" > /etc/gameserverpassword
+ chmod go= /etc/gameserverpassword
+fi
+
+# Install what we need
+apt update -y && apt full-upgrade -y
+apt install --assume-yes \
+ git tmux unzip curl vim openjdk-11-jdk xz-utils python3-venv python3-pip \
+ python3-dev apt virtualenv python3-virtualenv libjpeg-dev zlib1g-dev \
+ fuse g++ gcc curl firewalld automake autoconf libtool \
+ libcurl3-dev libc-ares-dev zlib1g-dev libncurses-dev make python3-aiohttp \
+ nginx-core certbot python3-certbot-nginx sudo python3-psutil \
+ ldc dub libenet-dev python3-bcrypt jq telnet jekyll ruby-jekyll-feed
+
+# Create the user for running the game servers
+if ! getent passwd ${systemuser}; then
+ useradd ${systemuser} --system --create-home --shell=/bin/false
+fi
+export systemuserhome="$( getent passwd "${systemuser}" | cut -d: -f6 )"
+
+# Install the web interface for servers that require interactive shells
+if [ -d console2web ]; then
+ cd console2web
+ git pull
+ cd -
+else
+ git clone https://github.com/DeathByDenim/console2web.git
+fi
+cp console2web/console2web.py /usr/bin/console2web
+
+# Deploy web interface stuff
+"$(dirname "$0")"/scripts/deploy_monitoring.sh
+"$(dirname "$0")"/scripts/deploy_webserver.sh
+
+# Deploy the game servers
+games="\
+supertuxkart \
+bzflag \
+hedgewars \
+lix \
+mindustry \
+minetest \
+odamex \
+openhv \
+openspades \
+teeworlds \
+teeworlds-ddrace \
+unvanquished \
+xonotic \
+xonotic-br \
+armagetron_advanced \
+opensoldat \
+supertuxparty \
+ufoai \
+shatteredparadise"
+failed_games=""
+for game in $games; do
+ if ! "$(dirname "$0")"/scripts/deploy_${game}.sh; then
+ failed_games+="${game}\n"
+ fi
+done
+
+# Apply all pending firewall rules. NGINX shouldn't have to be restarted, but it seems to help.
+firewall-cmd --reload
+systemctl restart nginx
+
+echo
+echo "Installation complete. Password is ${systempassword}"
+if [ -n "$failed_games" ]; then
+ echo "The following games failed to install:"
+ echo -e "$failed_games"
+ echo
+ echo "Use /usr/local/bin/redeploy.sh [game] to try again"
+fi
+
+cat > /usr/local/bin/redeploy.sh <.
+
+### Package a version of the website for offline use on a different web server.
+### Used to indicate that the VM running the game servers is off.
+### Specify domain name:
+### DOMAINNAME=example.com HOSTEDBYNAME=DeathByDenim ./pack_web_offline.sh
+
+set -e
+
+if ! which jekyll > /dev/null; then
+ echo "Jekyll is required to generate the website"
+ exit 1
+fi
+
+webroot=${TMPDIR:-/tmp}/website
+mkdir -p ${webroot}
+cp -r "$(dirname "$0")"/website/* ${webroot}
+
+curl --location https://github.com/twbs/bootstrap/archive/v5.2.3.zip > ${TMPDIR:-/tmp}/bootstrap.zip
+unzip -o -d ${TMPDIR:-/tmp}/bootstrap ${TMPDIR:-/tmp}/bootstrap.zip "bootstrap-5.2.3/scss/*"
+if [ -d "$(dirname "$0")"/../website/_sass/bootstrap ]; then
+ rm -r "$(dirname "$0")"/../website/_sass/bootstrap
+fi
+mv ${TMPDIR:-/tmp}/bootstrap/bootstrap-5.2.3/scss ${webroot}/_sass/bootstrap
+rm -r ${TMPDIR:-/tmp}/bootstrap.zip ${TMPDIR:-/tmp}/bootstrap
+
+if [ x"$NOSSL" = "x" ] || [ $NOSSL -ne 1 ]; then
+ ssl="true"
+ s_for_https="s"
+else
+ ssl="false"
+ s_for_https=""
+fi
+
+cat > ${webroot}/_config.yml <
+ onFOSS-LAN is a online, "Free (as Freedom) and Open Source" LAN-Party hosted by ${HOSTEDBYNAME} The goal is to get people together, enjoying the art of computer games and having a great time in these days. The FOSS community is a place of being open minded and acceptance to all different kinds of people with the focus of fully transparent systems and protecting individuals. So it does not matter if you are on Windows, Mac or Linux and it is also NOT necessary to have a PC MASTERRACE setup to run those games.
+url: http${s_for_https}://${DOMAINNAME}
+
+content:
+ hosted_by_name: "${HOSTEDBYNAME}"
+ domain_name: "${DOMAINNAME}"
+ offline: true
+ ssl: ${ssl}
+ md5password: "$(echo -n "${systempassword}" | md5sum | cut -d' ' -f1)"
+
+defaults:
+ -
+ scope:
+ path: ""
+ type: "posts"
+ values:
+ layout: "post"
+
+plugins:
+ - jekyll-feed
+EOF
+jekyll build --source ${webroot} --destination ${webroot}/_site
+tar -cjf web.tar.bz2 --directory="${webroot}/_site" .
+rm -rf "${webroot}"
diff --git a/scripts/deploy_armagetron_advanced.sh b/scripts/deploy_armagetron_advanced.sh
new file mode 100755
index 0000000..27e5d04
--- /dev/null
+++ b/scripts/deploy_armagetron_advanced.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Collection of scripts to deploy a server hosting several open-source games
+# Copyright (C) 2022 Jarno van der Kolk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+set -e
+
+if [ -e /lib/systemd/system/armagetronad-dedicated.service ]; then
+ systemctl stop armagetronad-dedicated
+fi
+
+apt install --assume-yes armagetronad-dedicated
+
+# Override unit file to use console2web
+mkdir -p /etc/systemd/system/armagetronad-dedicated.service.d
+cat > /etc/systemd/system/armagetronad-dedicated.service.d/override.conf < /etc/armagetronad/server_info.cfg < to start!
+SERVER_NAME onFOSS-LAN
+EOF
+
+cat > /etc/armagetronad/settings_custom.cfg < /etc/nginx/gameserver.d/armagetron.conf <.
+
+set -e
+
+if [ -e /etc/systemd/system/bzflag.service ]; then
+ systemctl stop bzflag
+fi
+
+apt-get -y install build-essential pkg-config
+
+# Install BZFlag
+mkdir -p ${TMPDIR:-/tmp}/bzflag-build
+cd ${TMPDIR:-/tmp}/bzflag-build
+if [ -d bzflag ]; then
+ rm -rf bzflag
+fi
+git clone --branch ${bzflag_version} https://github.com/BZFlag-Dev/bzflag.git
+cd bzflag
+./autogen.sh
+./configure --disable-client --prefix=/opt/bzflag-${bzflag_version}
+make
+make install
+if ! [ -L /usr/games/bzfs ]; then
+ ln -s /opt/bzflag-${bzflag_version}/bin/bzfs /usr/games/
+fi
+if ! [ -L /usr/games/bzadmin ]; then
+ ln -s /opt/bzflag-${bzflag_version}/bin/bzadmin /usr/games/
+fi
+
+rm -rf ${TMPDIR:-/tmp}/bzflag-build
+
+# Create SystemD unit
+cat > /etc/systemd/system/bzflag.service < /etc/systemd/system/bzflag-monitor.service < /etc/nginx/gameserver.d/bzflag.conf <.
+
+set -e
+
+if [ -e /etc/systemd/system/cortexcommand.service ]; then
+ systemctl stop cortexcommand
+fi
+
+apt-get -y install build-essential libsdl2-dev libloadpng4-dev libflac++-dev luajit-5.1-dev liblua5.1-dev libminizip-dev liblz4-dev libpng++-dev libtbb-dev ninja-build xvfb
+
+# Install Cortex Command
+mkdir -p ${TMPDIR:-/tmp}/cortexcommand-build
+cd ${TMPDIR:-/tmp}/cortexcommand-build
+if [ -d cortexcommand ]; then
+ rm -rf cortexcommand
+fi
+git clone --depth=1 https://github.com/cortex-command-community/Cortex-Command-Community-Project-Source.git
+git clone --depth=1 https://github.com/cortex-command-community/Cortex-Command-Community-Project-Data.git
+cd Cortex-Command-Community-Project-Source
+
+virtualenv mesonenv
+pip install meson
+source mesonenv/bin/activate
+meson setup --prefix=/opt/cortexcommand --buildtype=debug build
+ninja -C build
+ninja install -C build
+deactivate
+cd ..
+rm -rf ${TMPDIR:-/tmp}/cortexcommand-build
+
+# Patch startup script to get rid of weird directories
+cd /opt/cortexcommand/bin
+patch -l < "\${user_data}/Metagames.rte/Index.ini"
+- fi
+-
+- if ! [[ -d "\${user_data}/Scenes.rte" ]]; then
+- mkdir -p "\${user_data}/Scenes.rte"
+- echo -e "DataModule\n\tModuleName = Saves" > "\${user_data}/Scenes.rte/Index.ini"
+- fi
+-
+ for directory in \${user_directories[@]}; do
+ if ! [[ -d "\${user_data}/\${directory}" ]]; then
+ mkdir -p "\${user_data}/\${directory}"
+EOF
+
+sudo -u ${systemuser} mkdir -p "${systemuserhome}/.local/share/Cortex Command"
+echo -e "ServerSleepWhenIdle = 1\nServerSimSleepWhenIdle = 1" | sudo -u ${systemuser} tee "${systemuserhome}/.local/share/Cortex Command/Settings.ini"
+
+# Create SystemD unit
+cat > /etc/systemd/system/cortexcommand.service < /etc/systemd/system/cortexcommand-fakex.service <.
+
+set -e
+
+apt install --assume-yes hedgewars
+
+if [ -e /etc/systemd/system/hedgewars.service ]; then
+ systemctl stop hedgewars
+fi
+
+# Hedgewars
+# Create SystemD unit
+cat > /etc/systemd/system/hedgewars.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/lix.service ]; then
+ systemctl stop lix
+fi
+
+if [ -z ${lix_version} ] || [ "${lix_version}" = "latest" ]; then
+ lix_version=$(curl -s https://api.github.com/repos/SimonN/LixD/releases/latest | jq -r '.["tag_name"]' | cut -c2-)
+fi
+
+# Install Lix
+mkdir -p ${TMPDIR:-/tmp}/lix-build
+cd ${TMPDIR:-/tmp}/lix-build
+if [ -d LixD ]; then
+ rm -rf LixD
+fi
+git clone --branch v${lix_version} https://github.com/SimonN/LixD.git
+cd LixD/src/server
+dub build
+mkdir -p /opt/lix-${lix_version}
+cp ../../bin/lixserv /opt/lix-${lix_version}
+rm -rf ${TMPDIR:-/tmp}/lix-build
+
+# Create SystemD unit
+cat > /etc/systemd/system/lix.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/mindustry.service ]; then
+ systemctl stop mindustry
+fi
+
+if [ -z ${mindustry_version} ] || [ "${mindustry_version}" = "latest" ]; then
+ mindustry_version=$(curl -s https://api.github.com/repos/Anuken/Mindustry/releases?per_page=1 | jq -r '.[0]["tag_name"]' | cut -c2-)
+fi
+
+# Mindustry
+mkdir -p /opt/mindustry-${mindustry_version}
+curl --location https://github.com/Anuken/Mindustry/releases/download/v${mindustry_version}/server-release.jar > /opt/mindustry-${mindustry_version}/mindustry.jar
+mkdir -p /var/lib/mindustry
+chown -R ${systemuser} /var/lib/mindustry
+
+cat > /etc/systemd/system/mindustry.service < /etc/nginx/gameserver.d/mindustry.conf <.
+
+set -e
+
+apt install --assume-yes libsqlite3-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev cmake
+
+if [ -e /etc/systemd/system/minetest.service ]; then
+ systemctl stop minetest
+fi
+
+if [ -z ${minetest_version} ] || [ "${minetest_version}" = "latest" ]; then
+ minetest_version=$(curl -s https://api.github.com/repos/minetest/minetest/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Install minetest
+mkdir -p ${TMPDIR:-/tmp}/minetest-build
+curl --location "https://github.com/minetest/minetest/archive/refs/tags/${minetest_version}.tar.gz" | tar --extract --gzip --no-same-owner --directory=${TMPDIR:-/tmp}/minetest-build
+mkdir -p ${TMPDIR:-/tmp}/minetest-build/minetest-${minetest_version}/build
+git clone --depth 1 https://github.com/minetest/minetest_game.git ${TMPDIR:-/tmp}/minetest-build/minetest-${minetest_version}/games/minetest_game
+git clone --depth 1 --branch "1.9.0mt10" https://github.com/minetest/irrlicht.git ${TMPDIR:-/tmp}/minetest-build/minetest-${minetest_version}/lib/irrlichtmt
+cd ${TMPDIR:-/tmp}/minetest-build/minetest-${minetest_version}/build
+cmake -DCMAKE_INSTALL_PREFIX=/opt/minetest-${minetest_version} -DBUILD_CLIENT=FALSE -DBUILD_SERVER=TRUE ..
+make
+make install
+cd -
+rm -rf ${TMPDIR:-/tmp}/minetest-build
+
+sudo -u ${systemuser} mkdir -p /home/${systemuser}/.minetest/games
+curl --location https://content.minetest.net/packages/MisterE/blockbomber/releases/11576/download/ > ${TMPDIR:-/tmp}/blockbomber.zip
+sudo -u ${systemuser} unzip -o -d /home/${systemuser}/.minetest/games "${TMPDIR:-/tmp}"/blockbomber.zip
+rm -f "${TMPDIR:-/tmp}/blockbomber.zip"
+
+cat > /etc/systemd/system/minetest.service < /etc/minetest.conf <.
+
+git clone https://github.com/DeathByDenim/d3-serverstats.git
+cd d3-serverstats
+cp serverstats.py /usr/bin/
+
+cat > /etc/systemd/system/serverstats.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/odamex.service ]; then
+ systemctl stop odamex
+fi
+
+if [ -z ${odamex_version} ] || [ "${odamex_version}" = "latest" ]; then
+ odamex_version=$(curl -s https://api.github.com/repos/odamex/odamex/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Install ODAMEX
+apt install --assume-yes libsdl2-dev libsdl2-mixer-dev cmake deutex freedoom libpng-dev
+mkdir -p ${TMPDIR:-/tmp}/odamex-build
+curl --location https://github.com/odamex/odamex/releases/download/${odamex_version}/odamex-src-${odamex_version}.tar.gz | tar --extract --gz --no-same-owner --directory="${TMPDIR:-/tmp}/odamex-build"
+mkdir ${TMPDIR:-/tmp}/odamex-build/odamex-src-${odamex_version}/build
+cd ${TMPDIR:-/tmp}/odamex-build/odamex-src-${odamex_version}/build
+cmake -DBUILD_CLIENT=OFF -DBUILD_SERVER=ON -DBUILD_LAUNCHER=OFF -DCMAKE_INSTALL_PREFIX=/opt/odamex-${odamex_version} ..
+make
+make install
+
+# Build AppImage
+mkdir -p AppDir
+cmake -DBUILD_CLIENT=ON -DBUILD_SERVER=OFF -DBUILD_LAUNCHER=OFF -DCMAKE_INSTALL_PREFIX=AppDir ..
+make
+make install
+curl -O --location 'https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage'
+curl -O --location 'https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage'
+chmod +x linuxdeploy-plugin-appimage-x86_64.AppImage linuxdeploy-x86_64.AppImage
+mkdir -p AppDir/usr/share/applications
+cat > AppDir/usr/share/applications/odamex.desktop < AppDir/AppRun < /home/${systemuser}/.odamex/odasrv.cfg < /etc/systemd/system/odamex.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/openhv.service ]; then
+ systemctl stop openhv
+fi
+
+if [ -z ${openhv_version} ] || [ "${openhv_version}" = "latest" ]; then
+ openhv_version=$(curl -s https://api.github.com/repos/OpenHV/OpenHV/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Install OpenHV
+mkdir -p /opt/openhv-${openhv_version}
+curl --location "https://github.com/OpenHV/OpenHV/releases/download/${openhv_version}/OpenHV-${openhv_version}-x86_64.AppImage" > /opt/openhv-${openhv_version}/OpenHV-x86_64.AppImage
+chmod +x /opt/openhv-${openhv_version}/OpenHV-x86_64.AppImage
+
+cat > /etc/systemd/system/openhv.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/opensoldat.service ]; then
+ systemctl stop opensoldat
+fi
+
+# Install dependencies
+sudo apt-get -y install build-essential g++ cmake git fpc libprotobuf-dev protobuf-compiler libssl-dev libsdl2-dev libopenal-dev libphysfs-dev libfreetype6
+
+# Install BZFlag
+builddir=${TMPDIR:-/tmp}/opensoldat-build
+mkdir -p ${builddir}
+cd ${builddir}
+if [ -d opensoldat ]; then
+ rm -rf opensoldat
+fi
+git clone https://github.com/opensoldat/opensoldat.git
+git clone https://github.com/opensoldat/base.git
+cd opensoldat
+mkdir build && cd build
+cmake -DCMAKE_INSTALL_PREFIX=/opt/opensoldat -DBUILD_CLIENT=False ..
+make
+make install
+mkdir -p /opt/opensoldat/bin/configs /opt/opensoldat/bin/logs
+cp -r ${builddir}/base/server/configs/bots /opt/opensoldat/bin/configs/bots
+
+if ! [ -L /usr/games/opensoldatserver ]; then
+ ln -s /opt/opensoldat/bin/opensoldatserver /usr/games/
+fi
+
+rm -rf ${builddir}
+
+cat > /opt/opensoldat/bin/configs/server_dm.cfg < /opt/opensoldat/bin/configs/server_ctf.cfg < /opt/opensoldat/bin/configs/mapslist.txt < /opt/opensoldat/bin/configs/mapslist_ctf.txt < /opt/opensoldat/bin/configs/mapslist_htf.txt < /opt/opensoldat/bin/configs/mapslist_inf.txt < /etc/systemd/system/opensoldat.service < /etc/systemd/system/opensoldat-monitor.service < /etc/nginx/gameserver.d/opensoldat.conf <.
+
+set -e
+
+if [ -e /etc/systemd/system/openspades.service ]; then
+ systemctl stop openspades
+fi
+
+# Smallish maps from https://github.com/kinvaris/openspades-maps
+## island
+## nuketown (broken)
+## pinpoint
+## Realistic Bridge
+## Rocket Island
+## Submarine
+
+# OpenSpades
+mkdir -p /opt/openspades
+if [ -d /opt/openspades/env ]; then
+ rm -rf /opt/openspades/env
+fi
+virtualenv -p python3 /opt/openspades/env
+source /opt/openspades/env/bin/activate
+pip install -U piqueserver
+pip install "twisted<21.0.0" # Twisted 22 removed getPage that piqueserver 1.0.0 depends on
+pip install "MarkupSafe==2.0.1" # MarkupSafe removed soft_unicode that piqueserver 1.0.0 depends on
+sudo -u ${systemuser} /opt/openspades/env/bin/piqueserver --copy-config
+sudo -u ${systemuser} sed -i ${systemuserhome}/.config/piqueserver/config.toml \
+ -e s/"piqueserver instance"/"onFOSS"/ \
+ -e s/"#admin = \[\"adminpass1\", \"adminpass2\"\]"/"admin = \[\"${systempassword}\"\]"/ \
+ -e s/"name = \"Blue\""/"name = \"Cyanide\""/ \
+ -e s/"color = \[ 0, 0, 255\]"/"color = [ 0, 255, 255]"/ \
+ -e s/"name = \"Green\""/"name = \"Pinkster\""/ \
+ -e s/"color = \[ 0, 255, 0\]"/"color = [ 255, 0, 255]"/ \
+ -e s/" \"classicgen\","/" \"smallrandomisland\",\n \"island\",\n \"pinpoint\",\n \"realisticbridge\",\n \"rocketisland\",\n \"submarine\","/ \
+ -e s/"default_time_limit = \"2hours\""/"default_time_limit = \"20minutes\""/
+deactivate
+
+cat > /etc/systemd/system/openspades.service < ${systemuserhome}/.config/piqueserver/maps/${map}.txt
+ curl "https://raw.githubusercontent.com/kinvaris/openspades-maps/master/${map}.vxl" > ${systemuserhome}/.config/piqueserver/maps/${map}.vxl
+done
+curl "https://raw.githubusercontent.com/DeathByDenim/openspades-maps/main/smallrandomisland.txt" > ${systemuserhome}/.config/piqueserver/maps/smallrandomisland.txt
+
+systemctl daemon-reload
+systemctl enable --now openspades.service
+
+firewall-cmd --zone=public --add-port=32886/tcp --permanent
+firewall-cmd --zone=public --add-port=32887/udp --permanent
diff --git a/scripts/deploy_shatteredparadise.sh b/scripts/deploy_shatteredparadise.sh
new file mode 100755
index 0000000..8e70f1c
--- /dev/null
+++ b/scripts/deploy_shatteredparadise.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Collection of scripts to deploy a server hosting several open-source games
+# Copyright (C) 2022 Jarno van der Kolk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+set -e
+
+if [ -e /etc/systemd/system/shatteredparadise.service ]; then
+ systemctl stop shatteredparadise
+fi
+
+if [ -z ${shatteredparadise_version} ] || [ "${shatteredparadise_version}" = "latest" ]; then
+ shatteredparadise_version=$(curl -s https://api.github.com/repos/ABrandau/Shattered-Paradise-SDK/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Install Shattered Paradise
+mkdir -p /opt/shatteredparadise-${shatteredparadise_version}
+curl --location "https://github.com/ABrandau/Shattered-Paradise-SDK/releases/download/${shatteredparadise_version}/ShatteredParadise-${shatteredparadise_version}-x86_64.AppImage" > /opt/shatteredparadise-${shatteredparadise_version}/ShatteredParadise-x86_64.AppImage
+chmod +x /opt/shatteredparadise-${shatteredparadise_version}/ShatteredParadise-x86_64.AppImage
+
+cat > /etc/systemd/system/shatteredparadise.service <.
+
+set -e
+
+echo "Installing SuperTuxKart ${stk_version}"
+
+if [ -e /etc/systemd/system/supertuxkart.service ]; then
+ systemctl stop supertuxkart
+fi
+
+if [ -z ${stk_version} ] || [ "${stk_version}" = "latest" ]; then
+ stk_version=$(curl -s https://api.github.com/repos/supertuxkart/stk-code/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Install SuperTuxKart
+stk_dir="/opt/SuperTuxKart-${stk_version}"
+mkdir -p ${stk_dir}
+curl --location "https://github.com/supertuxkart/stk-code/releases/download/${stk_version}/SuperTuxKart-${stk_version}-linux-x86_64.tar.xz" | tar --extract --xz --no-same-owner --strip-components=1 --directory=${stk_dir}
+ln -s ${stk_dir}/bin/supertuxkart /usr/games/supertuxkart
+
+# Configuration
+cp $(dirname $0)/../configs/supertuxkart.xml /etc/supertuxkart.xml
+
+# Create SystemD unit
+cat > /etc/systemd/system/supertuxkart.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/supertuxparty.service ]; then
+ systemctl stop supertuxparty
+fi
+
+# Install Lix
+mkdir -p /opt/supertuxparty
+curl 'https://supertux.party/download/latest/server.zip' > ${TMPDIR:-/tmp}/server.zip
+unzip -o -d /opt/supertuxparty ${TMPDIR:-/tmp}/server.zip
+rm ${TMPDIR:-/tmp}/server.zip
+
+# Create SystemD unit
+cat > /etc/systemd/system/supertuxparty.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/teeworlds-ddrace.service ]; then
+ systemctl stop teeworlds
+fi
+
+# Teeworlds
+teeworldsddrace_directory="/opt/teeworlds-ddrace-${teeworldsddrace_version}"
+mkdir -p "${teeworldsddrace_directory}"
+
+# Download is unreliable at times. Retry a few times before failing
+retry_count=3
+while [ $retry_count -gt 0 ]; do
+ curl --location "https://ddnet.tw/downloads/DDNet-${teeworldsddrace_version}-linux_x86_64.tar.xz" | tar --extract --xz --no-same-owner --strip-components=1 --directory="${teeworldsddrace_directory}"
+ if [ $? -eq 0 ]; then
+ break
+ fi
+ sleep 20
+ (( retry_count-- ))
+done
+if [ $retry_count -le 0 ]; then
+ exit 1
+fi
+
+retry_count=3
+while [ $retry_count -gt 0 ]; do
+ curl --location "https://maps.ddnet.tw/compilations/novice.zip" > ${TMPDIR:-/tmp}/novice.zip
+ if [ $? -eq 0 ]; then
+ break
+ fi
+ sleep 20
+ (( retry_count-- ))
+done
+if [ $retry_count -le 0 ]; then
+ exit 1
+fi
+
+unzip -o -d "${teeworldsddrace_directory}"/data/maps ${TMPDIR:-/tmp}/novice.zip
+for f in "${teeworldsddrace_directory}"/data/maps/novice/maps/*.map; do
+ if "${teeworldsddrace_directory}"/map_convert_07 "$f" "`echo "$f" | sed s/"maps\/novice\/maps"/"maps7"/g`"; then
+ cp "$f" "${teeworldsddrace_directory}"/data/maps
+ fi
+done
+rm -rf "${teeworldsddrace_directory}"/data/maps/novice
+
+cat > "${teeworldsddrace_directory}"/data/myServerconfig.cfg < /etc/systemd/system/teeworlds-ddrace.service <.
+
+set -e
+
+if [ -e /etc/systemd/system/teeworlds.service ]; then
+ systemctl stop teeworlds
+fi
+
+if [ -z ${teeworlds_version} ] || [ "${teeworlds_version}" = "latest" ]; then
+ teeworlds_version=$(curl -s https://api.github.com/repos/teeworlds/teeworlds/releases/latest | jq -r '.["tag_name"]')
+fi
+
+# Teeworlds
+teeworld_directory="/opt/teeworlds-${teeworlds_version}"
+mkdir -p ${teeworld_directory}
+curl --location "https://github.com/teeworlds/teeworlds/releases/download/${teeworlds_version}/teeworlds-${teeworlds_version}-linux_x86_64.tar.gz" | tar --extract --gzip --no-same-owner --strip-components=1 --directory="${teeworld_directory}"
+
+cat > /etc/teeworlds.cfg < /etc/teedm.cfg < /etc/teetdm.cfg < /etc/teectf.cfg < /etc/systemd/system/teeworlds.service < /etc/systemd/system/teeworlds-rcon.service < /etc/nginx/gameserver.d/teeworlds.conf <.
+
+set -e
+
+if [ -e /lib/systemd/system/ufoai-server.service ]; then
+ systemctl stop ufoai-server
+fi
+
+apt install --assume-yes ufoai-server
+
+# Bug fix for UFO:AI? WorkingDirectory needs to be set for server
+# to be able to read debian_server.cfg
+mkdir -p /etc/systemd/system/ufoai-server.service.d
+cat > /etc/systemd/system/ufoai-server.service.d/override.conf < /etc/ufoai-server/server.cfg <.
+
+set -e
+
+if [ -e /etc/systemd/system/unvanquished.service ]; then
+ systemctl stop unvanquished
+fi
+
+unvanquished_url="https://github.com/Unvanquished/Unvanquished/releases/download/v${unvanquished_version}/unvanquished_${unvanquished_version}.zip"
+if [ -z ${unvanquished_version} ] || [ "${unvanquished_version}" = "latest" ]; then
+ unvanquished_version=$(curl -s https://api.github.com/repos/Unvanquished/Unvanquished/releases/latest | jq -r '.["tag_name"]' | cut -c2-)
+ unvanquished_url=$(curl -s https://api.github.com/repos/Unvanquished/Unvanquished/releases/latest | jq -r '.assets | .[] | select(.size > 1000) | .browser_download_url')
+fi
+
+# Unvanquished
+unvanquished_directory="/opt/unvanquished-${unvanquished_version}"
+curl --location ${unvanquished_url} > ${TMPDIR:-/tmp}/unvanquished.zip
+unzip -o -d ${TMPDIR:-/tmp} ${TMPDIR:-/tmp}/unvanquished.zip
+mkdir -p ${unvanquished_directory}/bin ${unvanquished_directory}/share
+unzip -o -d ${unvanquished_directory}/bin ${TMPDIR:-/tmp}/unvanquished*/linux-amd64.zip
+if [ -d ${unvanquished_directory}/share/pkg ]; then
+ rm -rf ${unvanquished_directory}/share/pkg
+fi
+mv ${TMPDIR:-/tmp}/unvanquished*/pkg ${unvanquished_directory}/share
+rm -rf ${TMPDIR:-/tmp}/unvanquished*
+
+mkdir -p ${systemuserhome}/unvanquished_home/config
+cat > ${systemuserhome}/unvanquished_home/config/unvanquished.cfg < /etc/systemd/system/unvanquished.service < /etc/nginx/gameserver.d/unvanquished.conf <.
+
+set -e
+
+# Web dashboard
+systemctl enable --now nginx
+
+firewall-cmd --zone=public --add-service=http --permanent
+firewall-cmd --zone=public --add-service=https --permanent
+firewall-cmd --reload
+
+# Request SSL certificate. This assumes DNS has been set up already
+if [ x"$NOSSL" = "x" ] || [ $NOSSL -ne 1 ]; then
+ ssl="true"
+ s_for_https="s"
+ certbot -n --nginx -d ${DOMAINNAME} -d www.${DOMAINNAME} --agree-tos -m "${letsencryptemail}"
+else
+ s_for_https=""
+ ssl="false"
+fi
+
+# Generate the website and put in place
+curl --location https://github.com/twbs/bootstrap/archive/v5.2.3.zip > ${TMPDIR:-/tmp}/bootstrap.zip
+unzip -o -d ${TMPDIR:-/tmp}/bootstrap ${TMPDIR:-/tmp}/bootstrap.zip "bootstrap-5.2.3/scss/*"
+if [ -d "$(dirname "$0")"/../website/_sass/bootstrap ]; then
+ rm -r "$(dirname "$0")"/../website/_sass/bootstrap
+fi
+mv ${TMPDIR:-/tmp}/bootstrap/bootstrap-5.2.3/scss "$(dirname "$0")"/../website/_sass/bootstrap
+rm -r ${TMPDIR:-/tmp}/bootstrap.zip ${TMPDIR:-/tmp}/bootstrap
+cat > "$(dirname "$0")"/../website/_config.yml <
+ onFOSS-LAN is a online, "Free (as Freedom) and Open Source" LAN-Party hosted by ${HOSTEDBYNAME}. The goal is to get people together, enjoying the art of computer games and having a great time in these days. The FOSS community is a place of being open minded and acceptance to all different kinds of people with the focus of fully transparent systems and protecting individuals. So it does not matter if you are on Windows, Mac or Linux and it is also NOT necessary to have a PC MASTERRACE setup to run those games.
+url: http${s_for_https}://${DOMAINNAME}
+
+content:
+ hosted_by_name: "${HOSTEDBYNAME}"
+ domain_name: "${DOMAINNAME}"
+ offline: false
+ ssl: ${ssl}
+ md5password: "$(echo -n "${systempassword}" | md5sum | cut -d' ' -f1)"
+
+defaults:
+ -
+ scope:
+ path: ""
+ type: "posts"
+ values:
+ layout: "post"
+
+plugins:
+ - jekyll-feed
+EOF
+jekyll build --source "$(dirname "$0")"/../website --destination /var/www/html
+
+# Patch the NGINX configuration for the web sockets
+cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
+patch --ignore-whitespace --force /etc/nginx/sites-available/default < /etc/nginx/htpasswd
+echo -e "import bcrypt\nprint(bcrypt.hashpw('${systempassword}'.encode('utf8'),bcrypt.gensalt(rounds=10)).decode('utf8'))" | python3 >> /etc/nginx/htpasswd
+
+systemctl restart nginx
diff --git a/scripts/deploy_xonotic-br.sh b/scripts/deploy_xonotic-br.sh
new file mode 100755
index 0000000..fa0cf0e
--- /dev/null
+++ b/scripts/deploy_xonotic-br.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+# Collection of scripts to deploy a server hosting several open-source games
+# Copyright (C) 2022 Jarno van der Kolk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+set -e
+
+if [ -e /etc/systemd/system/xonotic-br.service ]; then
+ systemctl stop xonotic-br
+fi
+
+apt install --assume-yes autoconf automake build-essential curl git libtool \
+ libgmp-dev libjpeg62-turbo-dev libsdl2-dev libxpm-dev xserver-xorg-dev \
+ zlib1g-dev unzip zip
+
+# Xonotic Battle Royale branch
+xonotic_directory="/opt/xonotic-br"
+rm -rf ${xonotic_directory}
+git clone https://gitlab.com/xonotic/xonotic.git ${xonotic_directory}
+cd ${xonotic_directory}
+./all update -l best
+./all checkout Juhu/battle-royale
+./all compile -r dedicated
+
+mkdir -p ${systemuserhome}/xonotic-br/data
+chown -R ${systemuser}: ${systemuserhome}/xonotic-br
+
+cat > ${systemuserhome}/xonotic-br/data/server.cfg < /etc/systemd/system/xonotic-br.service < /etc/nginx/gameserver.d/xonotic.conf <.
+
+set -e
+
+if [ -e /etc/systemd/system/xonotic.service ]; then
+ systemctl stop xonotic
+fi
+
+# Xonotic
+xonotic_directory="/opt/xonotic-${xonotic_version}"
+curl --location https://dl.xonotic.org/xonotic-${xonotic_version}.zip > ${TMPDIR:-/tmp}/xonotic.zip
+mkdir -p "${xonotic_directory}"
+unzip -o -d ${xonotic_directory} ${TMPDIR:-/tmp}/xonotic.zip
+rm -f ${TMPDIR:-/tmp}/xonotic.zip
+
+mkdir -p ${systemuserhome}/xonotic/data
+chown -R ${systemuser}: ${systemuserhome}/xonotic
+
+cat > ${systemuserhome}/xonotic/data/server.cfg < /etc/systemd/system/xonotic.service < /etc/nginx/gameserver.d/xonotic.conf <
+ Additionally, there was a fundraiser to help the people suffering
+ from the war in Ukraine 🇺🇦. I matched your donation
+ (up to $500 total) and additionally, the government of Canada
+ 🇨🇦 will match mine until 18 March. So, that's triple
+ the value for any donation you make. It doesn't have to be to the
+ Canadian Red Cross, you probably have a local equivalent.
+
+
+ UPDATE (2022-03-08): Canada reached the $10M already so they are not
+ doubling anymore. I'll still double but this means your amount won't
+ count as triple anymore.
+
+
+ UPDATE (2022-03-13): Canada increased the limit to $30M, so
+ any donation you make is once again tripled.
+
+
+ UPDATE (2022-03-14): Oh, never mind, this goal has already
+ been reached. Anyway, I'll still match what you donate!
+
+
+ UPDATE (2022-03-19): Donations are closed. A total amount
+ of €40 was collected and the equivalent of CAD 55.64 was
+ donated to the Canadian Red Cross.
+
+
List of donations:
+
+
Anonymous: €40
+
+- date: 2022-02-12T15:00UTC
+ intro: "Session to test if it all works as intended"
+ games:
+ - title: "OpenSpades"
+ - title: "OpenHV"
+ - title: "Xonotic"
diff --git a/website/_data/games.yml b/website/_data/games.yml
new file mode 100644
index 0000000..c111e08
--- /dev/null
+++ b/website/_data/games.yml
@@ -0,0 +1,118 @@
+- name: armagetron
+ title: "Armagetron Advanced"
+ description: "Drive your lightcycle and leave a lightwall behind you. Survive as long as you can and try to make other run into walls."
+ download_link: "http://www.armagetronad.org/downloads.php"
+ has_console: true
+ console_output_coloring: "Terminal"
+ console_initial_command: "players"
+ console_help_link: "http://wiki.armagetronad.org/index.php?title=Console_Commands"
+ console_example_commands:
+ - ["players", "Show current players"]
+ - ["kick ", "Kick the player"]
+ - ["num_ais ", "Set the number of AIs for games with more than one player"]
+ - ["limit_rounds", "End the match after this number of rounds"]
+- name: bzflag
+ title: "Bzflag"
+ description: "Drive around in a tank that can jump, trying to shoot your opponents while dodging their bullets."
+ download_link: "https://www.bzflag.org/downloads/"
+ has_console: true
+ console_output_coloring: "Terminal"
+ console_initial_command: "/playerlist"
+ console_help_link: "https://wiki.bzflag.org/Slash_Commands"
+ console_example_commands:
+ - ["/playerlist", "Display list of players"]
+ - ["/kick ", "Kick the player"]
+ - ["/gameover", "end the current game"]
+- name: hedgewars
+ title: "Hedgewars"
+ description: "Worms-like game where your team of hedgehogs needs to destroy the other teams using the ludicrous arsenal at their disposal."
+ download_link: "https://www.hedgewars.org/download.html"
+- name: lix
+ title: "Lix"
+ description: "Lemmings-like game where you need to guide your little people to safety despite their best efforts of wandering into things that will kill them."
+ download_link: "https://github.com/SimonN/LixD#get-lix"
+- name: mindustry
+ title: "Mindustry"
+ description: "A building and tower defence game where you build up an industry and defences against ever larger waves of enemies."
+ download_link: "https://github.com/Anuken/Mindustry/releases"
+ has_console: true
+ console_output_coloring: "Terminal"
+ console_initial_command: "status"
+ console_help_link: "https://mindustrygame.github.io/wiki/servers/#dedicated-server-commands"
+ console_example_commands:
+ - ["status", "Display server status"]
+ - ["runwave", "Trigger the next wave"]
+ - ["kick ", "Kick a person by name"]
+- name: minetest
+ title: "Minetest (Blockbomber)"
+ description: "The classic Bomberman game in 3D as a mod for Minetest"
+ download_link: "https://www.minetest.net/downloads/"
+- name: odamex
+ title: "Odamex"
+ description: "Multiplayer-focused DOOM engine that allows deathmatch, coop, and capture the flag mode. Here we are using the Freedom assets so you don't need a copy of the original game to play."
+ download_link: "https://odamex.net/"
+- name: openhv
+ title: "OpenHV"
+ description: "Real-time strategy game where you mine resources and build units to attack and defend."
+ download_link: "https://github.com/OpenHV/OpenHV/releases"
+- name: openspades
+ title: "OpenSpades"
+ description: "Mix between a first person shooter and Minecraft. Build defence structures, dig many tunnels or go on the offensive."
+ warning: "uses potentially non-open assets. Fix is here."
+ download_link: "https://github.com/yvt/openspades/releases"
+- name: shatteredparadise
+ title: "Shattered Paradise"
+ description: "Real-time strategy game where you mine resources and build units to attack and defend."
+ download_link: "https://github.com/ABrandau/Shattered-Paradise-SDK/releases"
+- name: opensoldat
+ title: "OpenSoldat"
+ description: "Fast-paced 2D side-scrolling shooter game where you have a big gun and a jetpack."
+ download_link: "https://github.com/opensoldat/opensoldat/releases/"
+- name: supertuxkart
+ title: "SuperTuxKart"
+ description: "Kart racing game where you can use the various power-ups to give yourself a boost of hinder your opponents."
+ download_link: "https://supertuxkart.net/Download"
+- name: supertuxparty
+ title: "Super Tux Party"
+ description: "Turn-based party game where you challenge other player in real-time mini games."
+ download_link: "https://supertux.party/download/latest/"
+- name: teeworlds
+ title: "Teeworlds"
+ description: "Fast-paced 2D side-scrolling shooter game where you have a big gun and a grappling hook."
+ download_link: "https://www.teeworlds.com/?page=downloads"
+ has_console: true
+ console_output_coloring: "Terminal"
+ console_initial_command: "status"
+ console_help_link: "https://www.teeworlds.com/?page=docs&wiki=server_commands"
+ console_example_commands:
+ - ["status", "Display server status"]
+ - ["change_map ", "Switch to "]
+ - ["kick ", "Kick a person by id"]
+- name: ufoai
+ title: "UFO: Alien Invasion"
+ description: "Squad-based turn-based tactical strategy game in the tradition of the old X-COM PC games"
+ download_link: "https://ufoai.org/wiki/Download"
+- name: unvanquished
+ title: "Unvanquished"
+ description: "First-person shooter of aliens vs humans. There are several classes and it's possible to build structures."
+ download_link: "https://unvanquished.net/download/"
+ has_console: true
+ console_output_coloring: "Daemoned"
+ console_initial_command: "/status"
+ console_help_link: "https://wiki.unvanquished.net/wiki/Server/Running#Commands"
+ console_example_commands:
+ - ["/listplayers", "List current players in-game"]
+ - ["/kick ", "Kick the player"]
+ - ["/nextmap", "Go to the next map in the rotation"]
+- name: xonotic
+ title: "Xonotic"
+ description: "First-person shooter where players compete in a 3D world. It features Battle Royale mode."
+ download_link: "https://xonotic.org/download/"
+ has_console: true
+ console_output_coloring: "Daemoned"
+ console_initial_command: "who"
+ console_help_link: "https://gitlab.com/xonotic/xonotic/-/wikis/Basic-server-configuration"
+ console_example_commands:
+ - ["who", "List current players in-game"]
+ - ["kick ", "Kick the player"]
+ - ["gotomap ", "Go to the specified map"]
diff --git a/website/_includes/event.html b/website/_includes/event.html
new file mode 100644
index 0000000..170d2c0
--- /dev/null
+++ b/website/_includes/event.html
@@ -0,0 +1,24 @@
+
+
+ {% for game in event.games %}
+ {% assign time = game.time | split: ":"%}
+ {% if game.time %}
+