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 %} +
  • {{ game.time }}UTC {{ game.title }}{%if game.tournament %} Tournament{% endif %}
  • + {% else %} +
  • {{ game.title }}{%if game.tournament %} Tournament{% endif %}
  • + {% endif %} + {% if game.extras %} +
      + {% for extra in game.extras %} +
    • {{ extra }}
    • + {% endfor %} +
    + {% endif %} + {% endfor %} +
+ {{ event.content }} diff --git a/website/_includes/nav.html b/website/_includes/nav.html new file mode 100644 index 0000000..94a8daa --- /dev/null +++ b/website/_includes/nav.html @@ -0,0 +1,28 @@ + diff --git a/website/_includes/offline.html b/website/_includes/offline.html new file mode 100644 index 0000000..a162d25 --- /dev/null +++ b/website/_includes/offline.html @@ -0,0 +1,2 @@ +
OFFLINE
+
OFFLINE
diff --git a/website/_includes/online.html b/website/_includes/online.html new file mode 100644 index 0000000..f5ec7f5 --- /dev/null +++ b/website/_includes/online.html @@ -0,0 +1,21 @@ + +
CPU
+
+ + + +
+
Memory
+
+ + + +
+ diff --git a/website/_layouts/default.html b/website/_layouts/default.html new file mode 100644 index 0000000..f506945 --- /dev/null +++ b/website/_layouts/default.html @@ -0,0 +1,32 @@ + + + + + onFOSS - Event page + + + + + + + + {% include nav.html %} + +
+
+
+ {{ content }} +
+
+
Live stats
+ {% if site.content.offline %} + {% include offline.html %} + {% else %} + {% include online.html %} + {% endif %} +
+
+
+ + + diff --git a/website/_layouts/help.html b/website/_layouts/help.html new file mode 100644 index 0000000..aebf7c6 --- /dev/null +++ b/website/_layouts/help.html @@ -0,0 +1,13 @@ +--- +layout: default +nav_pill: help +--- + + {% assign game = site.data.games | where_exp: "item", "item.name == page.game" | first %} +

{{ game.title }}

+

{{ game.description }}

+ Screenshot of {{ game.title }} +

Getting the game

+ + {{ content }} +

diff --git a/website/_layouts/post.html b/website/_layouts/post.html new file mode 100644 index 0000000..3123215 --- /dev/null +++ b/website/_layouts/post.html @@ -0,0 +1,8 @@ +--- +layout: default +nav_pill: news +--- +

{{ page.title }}

+

{{ page.date | date_to_string }} - {{ page.author }}

+ +{{ content }} diff --git a/website/_posts/2023-05-06-more-bananas.md b/website/_posts/2023-05-06-more-bananas.md new file mode 100644 index 0000000..70341c6 --- /dev/null +++ b/website/_posts/2023-05-06-more-bananas.md @@ -0,0 +1,6 @@ +--- +author: DeathByDenim +--- +Hello world! + +How are you doing today? diff --git a/website/_posts/2023-05-08-bananas.md b/website/_posts/2023-05-08-bananas.md new file mode 100644 index 0000000..70341c6 --- /dev/null +++ b/website/_posts/2023-05-08-bananas.md @@ -0,0 +1,6 @@ +--- +author: DeathByDenim +--- +Hello world! + +How are you doing today? diff --git a/website/_sass/base.scss b/website/_sass/base.scss new file mode 100644 index 0000000..cde9996 --- /dev/null +++ b/website/_sass/base.scss @@ -0,0 +1,71 @@ +// Custom style matching https://onfoss.libregaming.org/ + +//$primary: darkorange; +//$secondary: red; +//$body-bg: black; +//$body-color: orange; +//$warning: yellow; +//$font-family-base: Ubuntu Mono, monospace; +//$link-color: #4FBAD5; +//$dark: darkorange; +//$nav-pills-link-active-color: darkblue; +//$nav-pills-link-active-bg: darkorange; + + +// If you want to provide the Ubuntu font, place those font files in assets/css/font + +///* ubuntu-mono-regular - latin */ +//@font-face { + //font-family: 'Ubuntu Mono'; + //font-style: normal; + //font-weight: 400; + //src: url('font/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */ + //src: local(''), + //url('font/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + //url('font/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + //url('font/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */ +//} + +///* ubuntu-mono-italic - latin */ +//@font-face { + //font-family: 'Ubuntu Mono'; + //font-style: italic; + //font-weight: 400; + //src: url('font/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */ + //src: local(''), + //url('font/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + //url('font/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */ + //url('font/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */ +//} + +///* ubuntu-mono-700 - latin */ +//@font-face { + //font-family: 'Ubuntu Mono'; + //font-style: normal; + //font-weight: 700; + //src: url('font/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */ + //src: local(''), + //url('font/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + //url('font/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */ + //url('font/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */ +//} + +///* ubuntu-mono-700italic - latin */ +//@font-face { + //font-family: 'Ubuntu Mono'; + //font-style: italic; + //font-weight: 700; + //src: url('font/ubuntu-mono-v14-latin-700italic.eot'); /* IE9 Compat Modes */ + //src: local(''), + //url('font/ubuntu-mono-v14-latin-700italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + //url('font/ubuntu-mono-v14-latin-700italic.woff2') format('woff2'), /* Super Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-700italic.woff') format('woff'), /* Modern Browsers */ + //url('font/ubuntu-mono-v14-latin-700italic.ttf') format('truetype'), /* Safari, Android, iOS */ + //url('font/ubuntu-mono-v14-latin-700italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */ +//} diff --git a/website/admin.html b/website/admin.html new file mode 100644 index 0000000..da466f6 --- /dev/null +++ b/website/admin.html @@ -0,0 +1,10 @@ +--- +layout: default +nav_pill: admin +--- + + + +
+ +
diff --git a/website/assets/css/help.css b/website/assets/css/help.css new file mode 100644 index 0000000..d06d838 --- /dev/null +++ b/website/assets/css/help.css @@ -0,0 +1,15 @@ +.download { + margin-top: 2em; + margin-bottom: 2em; +} + +.download a { + color: #222; + font-weight: bold; + text-decoration: none; + border: solid 3px #bbb; + border-radius: 30px; + padding: 1em; + margin: 1em; + background-color: #eee; +} diff --git a/website/assets/css/main.scss b/website/assets/css/main.scss new file mode 100644 index 0000000..ce73310 --- /dev/null +++ b/website/assets/css/main.scss @@ -0,0 +1,5 @@ +--- +--- +@import "base"; +@import "bootstrap/bootstrap"; + diff --git a/website/assets/css/serverstats.css b/website/assets/css/serverstats.css new file mode 100644 index 0000000..b2a954c --- /dev/null +++ b/website/assets/css/serverstats.css @@ -0,0 +1,39 @@ +.cpu { + stroke: hotpink; + stroke-width: 3px; +} +.mem { + stroke: darkgreen; + stroke-width: 3px; +} +.graph { +} +.graphframe { + stroke: black; + fill: none; +} +.offline { + color: red; + font-size: 300%; + font-weight: bold; +} +.offline-blur { + position: absolute; + color: red; + font-size: 300%; + font-weight: bold; + animation-name: glow; + animation-duration: 4s; + animation-iteration-count: infinite; +} +@keyframes glow { + from { + filter: blur(.05em); + } + 50% { + filter: blur(.1em); + } + to { + filter: blur(.05em); + } +} diff --git a/website/assets/css/terminal.css b/website/assets/css/terminal.css new file mode 100644 index 0000000..6a43bb3 --- /dev/null +++ b/website/assets/css/terminal.css @@ -0,0 +1,121 @@ +:root { + --terminal-color-0: rgb(30,34,41); + --terminal-color-1: rgb(237,21,21); + --terminal-color-2: rgb(68,133,58); + --terminal-color-3: rgb(246,116,192); + --terminal-color-4: rgb(29,153,243); + --terminal-color-5: rgb(155,89,182); + --terminal-color-6: rgb(=26,188,156); + --terminal-color-7: rgb(252,252,252); + + --terminal-color-0-intense: rgb(127,140,141); + --terminal-color-1-intense: rgb(192,57,43); + --terminal-color-2-intense: rgb(50,100,44); + --terminal-color-3-intense: rgb(253,188,75); + --terminal-color-4-intense: rgb(61,174,233); + --terminal-color-5-intense: rgb(142,68,173); + --terminal-color-6-intense: rgb(22,160,133); + --terminal-color-7-intense: rgb(255,255,255); + + --terminal-color-default: rgb(23,168,139); + --terminal-color-background: rgb(30,34,41); +} + +.console_output { + border: solid grey; + background-color: var(--terminal-color-background); + width: min(95%, 1024px); + height: 30em; + overflow-x: hidden; + overflow-y: auto; + display: flex; + flex-direction: column-reverse; +} + +.console_output p { + margin: 0; + padding: 0; + font-family: monospace; + white-space: pre-wrap; + color: var(--terminal-color-default); + display: inline-block; +} + +.user_input::before { + content: '$ '; + color: var(--terminal-color-7-intense); +} + +.console_command { + width: calc(min(95%, 1024px) - 8em); +} + +.console_submit { + width: 6em; + padding: 0; + margin: 0; + border-radius: 0; + text-shadow: 0; +} + +.console_help { + width: 2em; + padding: 0; + margin: 0; + border-radius: 0; + text-shadow: 0; +} + +.TERM_FOREGROUND_0 { + color: var(--terminal-color-0); +} +.TERM_FOREGROUND_1 { + color: var(--terminal-color-1); +} +.TERM_FOREGROUND_2 { + color: var(--terminal-color-2); +} +.TERM_FOREGROUND_3 { + color: var(--terminal-color-3); +} +.TERM_FOREGROUND_4 { + color: var(--terminal-color-4); +} +.TERM_FOREGROUND_5 { + color: var(--terminal-color-5); +} +.TERM_FOREGROUND_6 { + color: var(--terminal-color-6); +} +.TERM_FOREGROUND_7 { + color: var(--terminal-color-7); +} + +.TERM_FOREGROUND_0_INTENSE { + color: var(--terminal-color-0-intense); +} +.TERM_FOREGROUND_1_INTENSE { + color: var(--terminal-color-1-intense); +} +.TERM_FOREGROUND_2_INTENSE { + color: var(--terminal-color-2-intense); +} +.TERM_FOREGROUND_3_INTENSE { + color: var(--terminal-color-3-intense); +} +.TERM_FOREGROUND_4_INTENSE { + color: var(--terminal-color-4-intense); +} +.TERM_FOREGROUND_5_INTENSE { + color: var(--terminal-color-5-intense); +} +.TERM_FOREGROUND_6_INTENSE { + color: var(--terminal-color-6-intense); +} +.TERM_FOREGROUND_7_INTENSE { + color: var(--terminal-color-7-intense); +} + +.TERM_FOREGROUND_BOLD { + font-weight: bold; +} diff --git a/website/assets/img/armagetron.png b/website/assets/img/armagetron.png new file mode 100644 index 0000000..0da5be6 Binary files /dev/null and b/website/assets/img/armagetron.png differ diff --git a/website/assets/img/bzflag.png b/website/assets/img/bzflag.png new file mode 100644 index 0000000..5d98b41 Binary files /dev/null and b/website/assets/img/bzflag.png differ diff --git a/website/assets/img/element_interface.png b/website/assets/img/element_interface.png new file mode 100644 index 0000000..3ed2add Binary files /dev/null and b/website/assets/img/element_interface.png differ diff --git a/website/assets/img/hedgewars.png b/website/assets/img/hedgewars.png new file mode 100644 index 0000000..d2beece Binary files /dev/null and b/website/assets/img/hedgewars.png differ diff --git a/website/assets/img/help_bzflag.png b/website/assets/img/help_bzflag.png new file mode 100644 index 0000000..7be88d5 Binary files /dev/null and b/website/assets/img/help_bzflag.png differ diff --git a/website/assets/img/help_hedgewars.png b/website/assets/img/help_hedgewars.png new file mode 100644 index 0000000..91d7460 Binary files /dev/null and b/website/assets/img/help_hedgewars.png differ diff --git a/website/assets/img/help_mindustry.png b/website/assets/img/help_mindustry.png new file mode 100644 index 0000000..87999e7 Binary files /dev/null and b/website/assets/img/help_mindustry.png differ diff --git a/website/assets/img/help_minetest.png b/website/assets/img/help_minetest.png new file mode 100644 index 0000000..1a41413 Binary files /dev/null and b/website/assets/img/help_minetest.png differ diff --git a/website/assets/img/help_openhv.png b/website/assets/img/help_openhv.png new file mode 100644 index 0000000..221b0a7 Binary files /dev/null and b/website/assets/img/help_openhv.png differ diff --git a/website/assets/img/help_openspades.png b/website/assets/img/help_openspades.png new file mode 100644 index 0000000..48dd4d5 Binary files /dev/null and b/website/assets/img/help_openspades.png differ diff --git a/website/assets/img/help_shatteredparadise.png b/website/assets/img/help_shatteredparadise.png new file mode 100644 index 0000000..885aaf2 Binary files /dev/null and b/website/assets/img/help_shatteredparadise.png differ diff --git a/website/assets/img/help_supertuxkart.png b/website/assets/img/help_supertuxkart.png new file mode 100644 index 0000000..3f78b94 Binary files /dev/null and b/website/assets/img/help_supertuxkart.png differ diff --git a/website/assets/img/help_teeworlds_name.png b/website/assets/img/help_teeworlds_name.png new file mode 100644 index 0000000..ddff25a Binary files /dev/null and b/website/assets/img/help_teeworlds_name.png differ diff --git a/website/assets/img/help_teeworlds_server.png b/website/assets/img/help_teeworlds_server.png new file mode 100644 index 0000000..ca96298 Binary files /dev/null and b/website/assets/img/help_teeworlds_server.png differ diff --git a/website/assets/img/help_ufoai.png b/website/assets/img/help_ufoai.png new file mode 100644 index 0000000..2fd5cce Binary files /dev/null and b/website/assets/img/help_ufoai.png differ diff --git a/website/assets/img/help_ufoai_connect.png b/website/assets/img/help_ufoai_connect.png new file mode 100644 index 0000000..45552b8 Binary files /dev/null and b/website/assets/img/help_ufoai_connect.png differ diff --git a/website/assets/img/help_unvanquished.png b/website/assets/img/help_unvanquished.png new file mode 100644 index 0000000..dfb4bc5 Binary files /dev/null and b/website/assets/img/help_unvanquished.png differ diff --git a/website/assets/img/help_xonotic.png b/website/assets/img/help_xonotic.png new file mode 100644 index 0000000..c0f1997 Binary files /dev/null and b/website/assets/img/help_xonotic.png differ diff --git a/website/assets/img/icon.svg b/website/assets/img/icon.svg new file mode 100644 index 0000000..cb3c564 --- /dev/null +++ b/website/assets/img/icon.svg @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/assets/img/lix.png b/website/assets/img/lix.png new file mode 100644 index 0000000..ada7391 Binary files /dev/null and b/website/assets/img/lix.png differ diff --git a/website/assets/img/mindustry.png b/website/assets/img/mindustry.png new file mode 100644 index 0000000..e79fa86 Binary files /dev/null and b/website/assets/img/mindustry.png differ diff --git a/website/assets/img/minetest.png b/website/assets/img/minetest.png new file mode 100644 index 0000000..5d2e436 Binary files /dev/null and b/website/assets/img/minetest.png differ diff --git a/website/assets/img/movim_interface.png b/website/assets/img/movim_interface.png new file mode 100644 index 0000000..561ca7e Binary files /dev/null and b/website/assets/img/movim_interface.png differ diff --git a/website/assets/img/movim_interface2.png b/website/assets/img/movim_interface2.png new file mode 100644 index 0000000..ed02587 Binary files /dev/null and b/website/assets/img/movim_interface2.png differ diff --git a/website/assets/img/mumble_interface.png b/website/assets/img/mumble_interface.png new file mode 100644 index 0000000..d471d5b Binary files /dev/null and b/website/assets/img/mumble_interface.png differ diff --git a/website/assets/img/odamex.png b/website/assets/img/odamex.png new file mode 100644 index 0000000..5ce2c1a Binary files /dev/null and b/website/assets/img/odamex.png differ diff --git a/website/assets/img/openhv.png b/website/assets/img/openhv.png new file mode 100644 index 0000000..601430d Binary files /dev/null and b/website/assets/img/openhv.png differ diff --git a/website/assets/img/opensoldat.png b/website/assets/img/opensoldat.png new file mode 100644 index 0000000..4e1e1c8 Binary files /dev/null and b/website/assets/img/opensoldat.png differ diff --git a/website/assets/img/openspades.png b/website/assets/img/openspades.png new file mode 100644 index 0000000..092909e Binary files /dev/null and b/website/assets/img/openspades.png differ diff --git a/website/assets/img/shatteredparadise.png b/website/assets/img/shatteredparadise.png new file mode 100644 index 0000000..2d71f74 Binary files /dev/null and b/website/assets/img/shatteredparadise.png differ diff --git a/website/assets/img/supertuxkart.png b/website/assets/img/supertuxkart.png new file mode 100644 index 0000000..147a11e Binary files /dev/null and b/website/assets/img/supertuxkart.png differ diff --git a/website/assets/img/supertuxparty.png b/website/assets/img/supertuxparty.png new file mode 100644 index 0000000..076fa15 Binary files /dev/null and b/website/assets/img/supertuxparty.png differ diff --git a/website/assets/img/teeworlds.png b/website/assets/img/teeworlds.png new file mode 100644 index 0000000..8e87ff3 Binary files /dev/null and b/website/assets/img/teeworlds.png differ diff --git a/website/assets/img/ufoai.png b/website/assets/img/ufoai.png new file mode 100644 index 0000000..2fd45fe Binary files /dev/null and b/website/assets/img/ufoai.png differ diff --git a/website/assets/img/unvanquished.png b/website/assets/img/unvanquished.png new file mode 100644 index 0000000..c773ec6 Binary files /dev/null and b/website/assets/img/unvanquished.png differ diff --git a/website/assets/img/xonotic.png b/website/assets/img/xonotic.png new file mode 100644 index 0000000..ec65c3c Binary files /dev/null and b/website/assets/img/xonotic.png differ diff --git a/website/assets/js/terminalcolors.js b/website/assets/js/terminalcolors.js new file mode 100644 index 0000000..715968b --- /dev/null +++ b/website/assets/js/terminalcolors.js @@ -0,0 +1,117 @@ +// 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 . + +// Shell command can have control codes. Some of these mean colours. +function convertTerminalCodeToHtml(line) { + let htmlline = ""; + let open_spans = 0; + for(let i = 0; i < line.length; i++) { + if(line[i] == '\033') { + let code = line[++i] + if(code == '[') { + // This means it's a colour + while(i < line.length && line[i] != 'm') { + let colour_code = ""; + for(i++; i < line.length && line[i] != 'm' && line[i] != ';'; i++) { + colour_code += line[i]; + } + colour_code = parseInt(colour_code); + if(colour_code === 0) { + for(let i = 0; i < open_spans; i++) { + htmlline += ""; + } + open_spans = 0; + } + if(colour_code === 1) { + htmlline += ''; + open_spans++; + } + else if(colour_code >= 30 && colour_code <= 37) { + htmlline += ''; + open_spans++; + } + else if(colour_code >= 90 && colour_code <= 97) { + htmlline += ''; + open_spans++; + } + } + } + } + else if(line[i] == '<') { + htmlline += "<" + } + else if(line[i] == '>') { + htmlline += ">" + } + else if(line[i] == '&') { + htmlline += "&" + } + else { + htmlline += line[i]; + } + } + + for(let i = 0; i < open_spans; i++) { + htmlline += ""; + } + + return htmlline +} + +// Shell command can have control codes. Some of these mean colours. +function convertDaemonedCodeToHtml(line) { + let htmlline = ""; + let open_spans = 0; + for(let i = 0; i < line.length; i++) { + if(line[i] == '^') { + let code = line[++i] + for(let i = 0; i < open_spans; i++) { + htmlline += ""; + } + open_spans = 0; + + if(code == 'N') { + htmlline += ''; + open_spans++; + } + else { + let colour_code = parseInt(code); + if(colour_code >= 0) { + htmlline += ''; + open_spans++; + } + } + } + else if(line[i] == '<') { + htmlline += "<" + } + else if(line[i] == '>') { + htmlline += ">" + } + else if(line[i] == '&') { + htmlline += "&" + } + else { + htmlline += line[i]; + } + } + + for(let i = 0; i < open_spans; i++) { + htmlline += ""; + } + + return htmlline +} diff --git a/website/help.html b/website/help.html new file mode 100644 index 0000000..67f1df6 --- /dev/null +++ b/website/help.html @@ -0,0 +1,12 @@ +--- +layout: default +nav_pill: help +--- +

Help

+

Each game has their own separate help page

+
    + {% assign sorted_games = site.data.games | sort: "title" %} + {% for game in sorted_games %} +
  • {{ game.title }}
  • + {% endfor %} +
diff --git a/website/help_armagetron.html b/website/help_armagetron.html new file mode 100644 index 0000000..7fcf0a0 --- /dev/null +++ b/website/help_armagetron.html @@ -0,0 +1,19 @@ +--- +layout: help +game: armagetron +--- +

Tips

+
    +
  • Press the down arrow key to brake
  • +
  • Drive as close as you can to a wall to get a speed boost
  • +
+

Connecting

+

+ Use the arrow keys to nagivate to Play Game and press <Enter>. + Then go to Multiplayer and then to Custom Connect. +

+

+ Enter {{ site.content.domain_name }} in the Address field and keep the port number at 4534. + Navigate down to Connect to Server to join. +

+

You should now be connected.

diff --git a/website/help_bzflag.html b/website/help_bzflag.html new file mode 100644 index 0000000..f729933 --- /dev/null +++ b/website/help_bzflag.html @@ -0,0 +1,18 @@ +--- +layout: help +game: bzflag +--- +

Tips

+
    +
  • Jump using the <Tab> key
  • +
  • Shoot using the <Enter> key
  • +
  • You stay still by placing the mouse cursor on the centre of the screen. Placing it slightly above will slowly move forward and all the way at the top means maximum speed. The same for turning left or right or reversing.
  • +
+

Connecting

+

Use the arrow keys to nagivate to Join Game and press <Enter>.

+

+ Move down to Server and type {{ site.content.domain_name }} and keep the port number at 5154. + You can also set your Callsign here. This is how other players will see + your name. Then move up to Connect and press <Enter>.

+ Server join screen for Bzflag +

You should now be connected.

diff --git a/website/help_hedgewars.html b/website/help_hedgewars.html new file mode 100644 index 0000000..0cc2a1d --- /dev/null +++ b/website/help_hedgewars.html @@ -0,0 +1,34 @@ +--- +layout: help +game: hedgewars +--- +

Tips

+
    +
  • Use the right mouse button to open the weapons menu.
  • +
  • + Use the arrow keys to move around. You can jump with <Enter> + or do a long jump <Backspace>. +
  • +
  • + Hold down <Space> to shoot. The longer you keep it pressed, + the further you will shoot. +
  • +
+

Connecting

+

+ To set your in-game name, click on the wrench icon at the bottom-right. + You can set your name under the Network tab. A password is not necessary. +

+

+ Go back to the main menu by clicking on the red arrow at the bottom + left of the screen and click the globe on the right and choose + "Play local network game". A new screen will open up. +

+

+ At the bottom, there is a button called "Specify addres". + Fill in {{ site.content.domain_name }} for the host and leave the port number at 46631. +

+ Connection settings for Hedgewars +

+ You should now see a list of rooms. There should be one room you can join. +

diff --git a/website/help_lix.html b/website/help_lix.html new file mode 100644 index 0000000..67ca4a4 --- /dev/null +++ b/website/help_lix.html @@ -0,0 +1,17 @@ +--- +layout: help +game: lix +--- +

Tips

+
    +
  • You can only control the Lix that are the colour you chose
  • +
  • You only get points for Lix going into the exits that are in your colour
  • +
  • You also get points if other coloured Lix go into your exits
  • +
  • The baseball bat is a great way to get rid of enemy blockers
  • +
+

Connecting

+

Click on "Options". Then under the "General" tab, you can input your player name. Click on "Okay" to confirm.

+

Click on "Network Game".

+

Under address, fill out {{ site.content.domain_name }} and keep the port set to 22934. Then click on "Okay" to connect.

+

You should see a room on the upper right. Click on that to join.

+

Choose your colour and then click "Okay"

diff --git a/website/help_mindustry.html b/website/help_mindustry.html new file mode 100644 index 0000000..e8c4cff --- /dev/null +++ b/website/help_mindustry.html @@ -0,0 +1,22 @@ +--- +layout: help +game: mindustry +--- +

Tips

+
    +
  • + There is lots of stuff to build, so at first things will be + daunting, but worry not, the mode is co-op so you are all + working together. +
  • +
  • Move around with the WASD keys.
  • +
  • Use the left mouse button to shoot or build. It will build if you select something from the menu in the bottom right, otherwise it will shoot.
  • +
+

Connecting

+

+ From the main menu choose "Play" and then "Join + Game". You will be able to set you in-game name here. +

+

To join the server, click on "Add Server" and type in {{ site.content.domain_name }}. When you press Ok, it will be added under "Remote Servers".

+ The join screen in Mindustry with the server added +

You can then click on the server name to join.

diff --git a/website/help_minetest.html b/website/help_minetest.html new file mode 100644 index 0000000..4dadfa6 --- /dev/null +++ b/website/help_minetest.html @@ -0,0 +1,19 @@ +--- +layout: help +game: minetest +--- +

Tips

+
    +
  • Movement: A, S, W, D
  • +
  • Drop bomb: Left Shift (sneak)(
  • +
  • Throw a bomb that you are standing in: Space (jump) (if player has Spring)
  • +
  • Punch bomb: Left mouse button (punch) (with Fist)
  • +
+

Connecting

+

+ Under address fill in {{ site.content.domain_name }} and keep the port at + 30000. Click on Register to set your in-game name. You can leave the password blank + since this server will disappear after the event anyway. +

+ The register screen in the Minetest client +

You will be placed in the lobby with the other players

diff --git a/website/help_odamex.html b/website/help_odamex.html new file mode 100644 index 0000000..d334e10 --- /dev/null +++ b/website/help_odamex.html @@ -0,0 +1,17 @@ +--- +layout: help +game: odamex +download_link: https://odamex.net/ +--- +

An AppImage for Linux was automatically generated: {% if site.content.offline %}Odamex-x86_64.AppImage (only available when game servers are online){% else %}Odamex-x86_64.AppImage{% endif %}

+

Tips

+
    +
  • Use <SPACE> to jump
  • +
  • Use E to open doors or to respawn if dead
  • +
+

Connecting

+

While Odamex does have a launcher, if requires that you have DOOM assets available locally. It won't launch the game without it, which means you either need the original game data of open assets such as Freedoom.

+

However, if you connect to the game server directly, odamex will download the required assets automatically from the server.

+

From the terminal, type:

+

odamex -connect {{ site.content.domain_name }} +set cl_name "YourName"

+

Of course, substitute "YourName" with the in-game name you want.

diff --git a/website/help_openhv.html b/website/help_openhv.html new file mode 100644 index 0000000..2fc9902 --- /dev/null +++ b/website/help_openhv.html @@ -0,0 +1,30 @@ +--- +layout: help +game: openhv +--- +

You will have to expand "Assets" to see the download links.

+

Tips

+
    +
  • + The menu on the right lets you build buildings and units. The first + things you need to build are a Power Plant (gives you power), a + Module (builds units) and Storage (harvests resources). +
  • +
  • + When you build your Storage, there will be a Miner that comes with + it. Use this to harvest resources. Resources will look like a couple + of ingots. +
  • +
+

Connecting

+

+ To set your in-game name, click on "Settings". You'll be + able to set your name under "Player Name". +

+

+ From the main menu, click on "Multiplayer" and then click + on "Direct IP". Fill in {{ site.content.domain_name }} and keep the port at + 1234. Then click on "Join" +

+ The join screen in OpenHV +

You will be placed in the lobby with the other players

diff --git a/website/help_opensoldat.html b/website/help_opensoldat.html new file mode 100644 index 0000000..f9ba1be --- /dev/null +++ b/website/help_opensoldat.html @@ -0,0 +1,20 @@ +--- +layout: help +game: opensoldat +--- +

The game does not have a GUI yet. You need to start it from the terminal/command prompt. When you do so, it will create a configs directory with a client.cfg file. You can add your settings to that.

+

The AppImage for Linux creates the config file in ~/.config/share/Soldat/Soldat instead.

+

Things you might like to set:

+
    +
  • cl_player_name YourNameGoesHere
  • +
  • r_fullscreen 1
  • +
+

Tips

+
    +
  • Use the right mouse button to use your jetpack.
  • +
  • Press Q to switch to your secondary weapon and E to throw grenades.
  • +
+

Connecting

+

Start Soldat by typing:

+

./soldat -join {{ site.content.domain_name }}

+

You should now be connected. If it doesn't work. Try to connect by IP address instead of domain name.

diff --git a/website/help_openspades.html b/website/help_openspades.html new file mode 100644 index 0000000..c7435f0 --- /dev/null +++ b/website/help_openspades.html @@ -0,0 +1,53 @@ +--- +layout: help +game: openspades +--- +

Tips

+
    +
  • + On joining, you will be asked to choose a team and a weapon. If + you change your mind during play, press L to get back to that + selection screen. +
  • +
  • + Use the scroll wheel to cycle between your weapons, the shovel + and the block. The shovel can destroy blocks, the block can build + walls +
  • +
  • + If you want to see a bigger map, press N. Press N again to make + the map go away again. +
  • +
+

Non-free assets

+

+ OpenSpades contains non-free assets that were copied from the original + Ace of Spades games. The creators of OpenSpades were unabled to contact + the authors, so these assets were never released under an open licence. +

+

+ Fortunately, there is a drop-in replacement for these assets available. + All models have been recreated under a CC0 licence and the sound effects + have been replaced by mostly CC0 equivalents with a few exceptions that + are CC-BY. +

+

Installation

+
    +
  • Download the libre assets: pak001-Free.pak
  • +
  • Find the location of pak000-Nonfree.pak for your OpenSpades installation. For example /usr/share/openspades/Resources/
  • +
  • Copy the downloaded pak001-Free.pak to the same location.
  • +
  • Optionally, delete pak000-Nonfree.pak. It it no longer needed because pak001-Free.pak will overrule all of the content in pak000-Nonfree.pak.
  • +
+

Connecting

+

+ When you start the game you will immediately enter the server + browser. If you click on "Setup" at the bottom of the + screen, you can set your in-game name. Click on "Back" + to return to the server browser. +

+

+ To connect to the server, type {{ site.content.domain_name }} in the input field at the + top and click on the "Connect" button to the right. +

+ The join screen in OpenSpades +

diff --git a/website/help_shatteredparadise.html b/website/help_shatteredparadise.html new file mode 100644 index 0000000..98738ba --- /dev/null +++ b/website/help_shatteredparadise.html @@ -0,0 +1,30 @@ +--- +layout: help +game: shatteredparadise +--- +

You will have to expand "Assets" to see the download links.

+

Tips

+
    +
  • + The menu on the right lets you build buildings and units. The first + things you need to build are a Power Plant (gives you power), a + Infantry building (builds units) and Storage (harvests resources). +
  • +
  • + When you build your Storage, there will be a Miner that comes with + it. Use this to harvest resources. Resources will look like a forest. + You can build more harvester from the vehicle building. +
  • +
+

Connecting

+

+ To set your in-game name, click on "Settings". You'll be + able to set your name under "Player Name". +

+

+ From the main menu, click on "Multiplayer" and then click + on "Direct IP". Fill in {{ site.content.domain_name }} and set the port at + 12340. The standard port is 1234, but is already taken. Then click on "Join" +

+ The join screen in Shattered Paradise +

You will be placed in the lobby with the other players

diff --git a/website/help_supertuxkart.html b/website/help_supertuxkart.html new file mode 100644 index 0000000..371e581 --- /dev/null +++ b/website/help_supertuxkart.html @@ -0,0 +1,28 @@ +--- +layout: help +game: supertuxkart +--- +

Tips

+
    +
  • Use the arrow keys to accelerate, brake, and steer.
  • +
  • Pick up presents to get items to use. Use <Space*gt; to activate.
  • +
  • The blue bottle give you turbo. Use N to activate.
  • +
  • + Use V to grind in the corners and keep it pressed. Yellow sparks + will give you a speed boost. Red ones even more. +
  • +
+

Connecting

+

+ Click on the globe labelled "Online". At the top, just + below the title, you can click the yellow button to set your in-game + name. You don't have to set a password. +

+

+ To connect to our server, click on "Enter server address". + Then type in {{ site.content.domain_name }} and click on "OK". +

+ Entering the server address +

+ You will then be placed in the lobby of our game server and ready to go! +

diff --git a/website/help_supertuxparty.html b/website/help_supertuxparty.html new file mode 100644 index 0000000..f5ab9e9 --- /dev/null +++ b/website/help_supertuxparty.html @@ -0,0 +1,4 @@ +--- +layout: help +game: supertuxparty +--- diff --git a/website/help_teeworlds.html b/website/help_teeworlds.html new file mode 100644 index 0000000..be824bf --- /dev/null +++ b/website/help_teeworlds.html @@ -0,0 +1,17 @@ +--- +layout: help +game: teeworlds +--- +

Click the name of your OS on the left of the most recent version. Extract the file wherever you like and start playing.

+

Tips

+
    +
  • You can double jump by pressing <Space> a second time.
  • +
  • Use your grappling hook by using the right-mouse button.
  • +
+

Connecting

+

Click on Settings and choose the Player tab. You can fill in your name so we can recognize you when you join the server. The Tee tab will also let you customize your appearance.

+ Teeworlds setting for player name +

To connect to the server, got back to the main menu and click Play.

+

At the bottom of the screen you can fill in the name of the server in the Host address field. Type {{ site.content.domain_name }} and press <Enter> or click Connect.

+ Joining the Teeworlds server +

You should now be connected.

diff --git a/website/help_ufoai.html b/website/help_ufoai.html new file mode 100644 index 0000000..786e18c --- /dev/null +++ b/website/help_ufoai.html @@ -0,0 +1,25 @@ +--- +layout: help +game: ufoai +--- +

The download page only has binaries for Linux and Windows. We compiled the macOS version ourselves. Download: ufoai-macos.tar.bz2

+

Then open the Terminal and type the following:

+
+tar xf ufoai-macos.tar.bz2
+cd dist
+./ufo
+          
+

To get rid of the graphical glitches disable "GLSL Shaders" under Options → Video → Advanced → OpenGL Setting

+

Tips

+
    +
  • Click on a squad member and then click where you want them to move. The target box will be green if you can make it in that turn. Walking is aborted if an enemy is spotted.
  • +
  • To shoot, click on the target button at the bottom left, choose what weapon mode you want to use and then click on your target.
  • +
  • Everything costs TUI. Actions will be greyed out of you don't have enough left for the current turn.
  • +
+

Connecting

+

Click on Multiplayer. You'll need to create a team before you can do anything, so click on Team and then Generate New Team and choose the type you want.

+ Generating a new team +

Click no the done button at the very bottom right if you are happy with it. You'll return to the multiplayer menu

+

Click on Join and type {{ site.content.domain_name }} in the field for Connect to IP and click Connect.

+ Joining the UFO:AI server +

You'll see a summary of the server. Click on Connect to connect.

diff --git a/website/help_unvanquished.html b/website/help_unvanquished.html new file mode 100644 index 0000000..f08b802 --- /dev/null +++ b/website/help_unvanquished.html @@ -0,0 +1,20 @@ +--- +layout: help +game: unvanquished +--- +

Tips

+
    +
  • + As humans you can buy upgraded weapons at the armory. Get close + and press Q to activate. You can also become an engineer and build + defences or repair stuff. +
  • +
  • + As aliens you can evolve anywhere by pressing Q. They also have an + engineer class that can build structures. +
  • +
+

Connecting

+

Set your in-game name by clicking on "Player" under "Options".

+

To connect to the server, press ~ to open the console and type "connect {{ site.content.domain_name }}"

+ In-game terminal connecting to the game server diff --git a/website/help_xonotic.html b/website/help_xonotic.html new file mode 100644 index 0000000..5d53cf0 --- /dev/null +++ b/website/help_xonotic.html @@ -0,0 +1,28 @@ +--- +layout: help +game: xonotic +--- +

Note that the download has the executable for all OS inside of it.

+

Tips

+
    +
  • + Always keep moving and jumping to make yourself harder to hit. +
  • +
  • + Weapons often has a secondary action. Use the right-mouse button to use it. +
  • +
  • + Gather as much health and armour as you can. +
  • +
+

Connecting

+

+ Go to "Multiplayer" and click on the "Profile" + button to set your in-game name. +

+

+ To connect to the game server, click on the "Servers" + button. At the bottom of the screen you can fill in {{ site.content.domain_name }} in + the Address field. Then press Join. +

+ Server name input in Xonotic diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..bbcd11f --- /dev/null +++ b/website/index.html @@ -0,0 +1,45 @@ +--- +layout: default +nav_pill: home +--- +

About onFOSS

+

+ onFOSS-LAN is a online, "Free (as Freedom) and Open Source" LAN-Party. +

+

+ See the main onfoss.org website for more information. + You will find our communication channels there as well. +

+

Event

+ {% assign sitetime = site.time | date: "%FT%T" %} + {% assign event = site.data.events | where_exp: "item", "item.date >= sitetime" | last %} + {% if event %} +

Start at {{ event.date | date: "%A %e %B %Y, %R" }} UTC +

+

Hosted by {{ site.content.hosted_by_name }}

+

Schedule

+ {% include event.html %} + {% else %} +

No event planned

+ {% endif %} +

Games

+

There are a few game servers running. To connect, simply start the game and connect to this domain. See also the Help section for more information.

+ + + {% assign sorted_games = site.data.games | sort: "title" %} + {% for game in sorted_games %} + + + + + + + {% endfor %} + +
Tiny screenshot of {{ game.title }}{{ game.title }} + {{ game.description }} + {% if game.warning %} +
Warning: {{ game.warning }} + {% endif %} +
More info
+

Enjoy!

diff --git a/website/js/consoles.js b/website/js/consoles.js new file mode 100644 index 0000000..cd74f0d --- /dev/null +++ b/website/js/consoles.js @@ -0,0 +1,150 @@ +--- +--- +// 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 . + +function createConsole(root, game_name, game_title, text_colour_function, initial_command, help_url, tooltip) { + const div_card = document.createElement('div'); + const div_card_header = document.createElement('div'); + const h5 = document.createElement('h5'); + const card_button = document.createElement('button'); + const div_collapse = document.createElement('div'); + const div_card_body = document.createElement('div'); + const header = document.createElement('h4'); + const output = document.createElement('div'); + const output_text = document.createElement('p'); + const input = document.createElement('form'); + const input_text = document.createElement('input'); + const input_submit = document.createElement('button'); + const input_help = document.createElement('button'); + + div_card.className = "card"; + div_card_header.className = "card-header"; + h5.className = "mb-0"; + card_button.className = "btn btn-link"; + card_button.innerText = game_title; + div_collapse.className = "collapse"; + div_card_body.className = "card-body"; + + output.id = game_name + "_output"; + output.className = "console_output"; + output_text.innerText = game_name + " console"; + input.id = game_name + "_form"; + input.className = "console_form"; + input_text.id = game_name + "_command"; + input_text.className = "console_command"; + input_text.size = 80; + input_text.autocomplete = "off"; + if(tooltip) { + input_text.title = tooltip; + } + input_submit.id = game_name + "_submit"; + input_submit.className = "console_submit"; + input_submit.innerText = "Enter"; + input_help.id = game_name + "_submit"; + input_help.className = "console_help"; + input_help.innerText = "?"; + + + + root.appendChild(div_card); + div_card.appendChild(div_card_header); + div_card_header.appendChild(h5); + h5.appendChild(card_button); + div_card.appendChild(div_collapse); + div_collapse.appendChild(div_card_body); + + output.appendChild(output_text); + div_card_body.appendChild(output); + input.appendChild(input_text); + input.appendChild(input_submit); + input.appendChild(input_help); + div_card_body.appendChild(input); + + input_help.addEventListener('click', function(e) { + e.preventDefault(); + window.open(help_url, '_blank'); + }); + + input.addEventListener('submit', function(e){ + e.preventDefault(); + let line = document.createElement('p') + line.innerText = input_text.value; + line.className = "user_input"; + output.prepend(line); + socket.send(input_text.value); + input_text.value = ""; + }); + + // Create WebSocket connection. + const socket = new WebSocket("ws{% if site.content.ssl %}s{% endif %}://{{ site.content.domain_name }}/" + game_name) + + // Connection opened + socket.addEventListener('open', function (event) { + socket.send(initial_command); + }); + + socket.addEventListener('error', function (event) { + console.error(event); + }); + + // Listen for messages + socket.addEventListener('message', function (event) { + const output = document.getElementById(game_name + '_output'); + let line = document.createElement('p') + line.innerHTML = text_colour_function(event.data); + output.prepend(line); + }); +} + +function consoles_init() { + document.cookie = 'token={{ site.content.md5password }}; SameSite=Strict'; + const root = document.getElementById('console-div'); + {% assign games_with_consoles = site.data.games | where_exp: "item", "item.has_console" | sort: "name" %} + {% for game in games_with_consoles %} + createConsole( + root, + '{{ game.name }}', + '{{ game.title }}', + convert{{ game.console_output_coloring }}CodeToHtml, + '{{ game.console_initial_command }}', + '{{ game.console_help_link }}', + "Helpful commands:\n{% for command in game.console_example_commands %}• {{ command[0] }}\t{{ command[1] }}\n{% endfor %}" + ); + {% endfor %} + + collapse_init(); +} + +function collapse_init() { + const bars = document.getElementsByClassName('card-header'); + for(let bar of bars) { + bar.addEventListener('click', function(e) { + const bartexts = document.getElementsByClassName('collapse'); + for(let bartext of bartexts) { + bartext.classList.remove("show"); + } + this.parentElement.children[1].classList.add("show"); + }) + } + document.getElementsByClassName('collapse')[0].classList.add("show"); +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', consoles_init); +} else { + consoles_init(); +} diff --git a/website/js/serverstats.js b/website/js/serverstats.js new file mode 100644 index 0000000..8973912 --- /dev/null +++ b/website/js/serverstats.js @@ -0,0 +1,60 @@ +--- +--- +// 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 . + +let heightScale = d3.scaleLinear() + .domain([0,100]) + .range([100,0]); +let timeScale = d3.scaleLinear() + .domain([0,60]) + .range([5,305]); + +function updateGraph(data, svgid, property_class, property) { + d3.select(svgid) + .selectAll('line') + .data(data, function(d) {return d.t}) + .join( + function(enter) { + return enter + .append('line') + .attr('x1', function(d,i){return timeScale(i)}) + .attr('x2', function(d,i){return timeScale(i)}) + .attr('y1', function(d,i){return heightScale(0)}) + .attr('y2', 100) + .attr('class', property_class); + }, + function(update) { + return update + }, + function(exit) { + return exit.remove(); + } + ) + .transition() + .ease(d3.easeLinear) + .duration(5000) + .attr('x1', function(d,i){return timeScale(i-1)}) + .attr('x2', function(d,i){return timeScale(i-1)}) + .attr('y1', function(d,i){return heightScale(d[property])}) +} + +function update() { + d3.json('http{% if site.content.ssl %}s{% endif %}://{{ site.content.domain_name }}/monitoring/all').then(function(data){ + updateGraph(data, '#memgraph', 'mem', 'm'); + updateGraph(data, '#cpugraph', 'cpu', 'c'); + }); +} diff --git a/website/js/xonscore.js b/website/js/xonscore.js new file mode 100644 index 0000000..cd12fb3 --- /dev/null +++ b/website/js/xonscore.js @@ -0,0 +1,137 @@ +// Parse the Xonotic score log format and return a JSON +// The returned data contains data for the individual +// rounds as well as totals +async function xonoticGetScores() { + const data = await fetch("xonscore.txt"); + const text = await data.text(); + + let stats = { + rounds: [], + totals: [] + }; + let map_name = "[unknown]"; + let duration_in_seconds = 0; + let labels = []; + let round_stats = []; + text.split("\n").forEach((row) => { + const fields = row.split(":"); + if(fields.length > 1) { + const verb = fields[1] + switch(verb) { + case "scores": + map_name = fields[2]; + duration_in_seconds = fields[3]; + break; + case "labels": + if(fields[2] === "player") { + labels = fields[3].split(","); + } + break; + case "player": + if(fields[2] === "see-labels") { + if(fields[5] === "spectator") { + break; + } + const split_fields = fields[3].split(","); + + // Filter out the custom colours in names + const player_name = fields[6] + .replace(/\^x.../g, "") + .replace(/\^\d/g, ""); + let player_stats = {name: player_name}; + for(let i = 0; i < labels.length; i++) { + if(labels[i] != "") { + player_stats[labels[i]] = split_fields[i] + } + } + round_stats.push(player_stats); + } + break; + case "end": + if(round_stats.length > 0) { + round_stats = round_stats.sort((a,b) => +a["score!!"] < +b["score!!"]); + stats.rounds.push({ + map_name: map_name, + duration_in_seconds: duration_in_seconds, + stats: round_stats + }) + } + round_stats = []; + labels = []; + duration_in_seconds = 0; + map_name = ""; + break; + } + } + }) + + let final = {}; + stats.rounds.forEach((map) => { + map.stats.forEach((stat) => { + if(stat.name in final) { + final[stat.name] += +stat["score!!"] + } + else { + final[stat.name] = +stat["score!!"] + } + }); + }); + + Object.keys(final).forEach(name => { + stats.totals.push({ + name: name, + score: final[name] + }) + }); + stats.totals = stats.totals.sort((a,b) => a.score < b.score); + + return stats; +} + +function xonoticScoreUpdate() { + xonoticGetScores().then((data) => { + d3.select("#xonotic-ranking") + .selectAll("li") + .data(data.totals) + .join("li") + .text(d => d.name + " (" + d.score + ")"); + + let tables = d3.select("#xonotic-results") + .selectAll("table") + .data(data.rounds) + .join( + (enter) => { + let table = enter.append("table"); + let thead = table.append("thead"); + thead.append("tr") + .append("th") + .attr("colspan", 5) + .text((d) => "Map name: " + d.map_name); + let headerrows = thead.append("tr"); + + ["Name", "Score", "Kills", "Deaths", "Suicides"].forEach((col) => { + headerrows.append("th").text(col); + }) + + table.append("tbody"); + return table; + }, + (update) => { + let u = update; + u.select("th").text((d) => "Map name: " + d.map_name); + return u; + }, + (exit) => exit.remove() + ) + .classed("table", true); + + let tbodies = tables.select('tbody'); + tbodies.selectAll("tr") + .data((d) => d.stats) + .join("tr") + .selectAll("td") + .data((d) => ["name", "score!!", "kills", "deaths<", "suicides<"].map((col) => d[col])) + .join("td") + .text((d) => d); + }); +} diff --git a/website/schedule.html b/website/schedule.html new file mode 100644 index 0000000..f7f828a --- /dev/null +++ b/website/schedule.html @@ -0,0 +1,18 @@ +--- +layout: default +nav_pill: schedule +--- +

Schedule

+ {% assign sitetime = site.time | date: "%FT%T" %} + {% assign past = site.data.events | where_exp: "item", "item.date < sitetime" %} + {% assign upcoming = site.data.events | where_exp: "item", "item.date >= sitetime" %} +

Upcoming

+ {% for event in upcoming %} + {% include event.html %} + {% else %} +

No upcoming events scheduled

+ {% endfor %} +

Past

+ {% for event in past %} + {% include event.html %} + {% endfor %} diff --git a/website/tournament.html b/website/tournament.html new file mode 100644 index 0000000..5d8677d --- /dev/null +++ b/website/tournament.html @@ -0,0 +1,52 @@ +--- +layout: default +nav_pill: tournament +--- + +

Tournament

+ {% assign sitetime = site.time | date: "%FT%T" %} + {% assign nextevent = site.data.events | where_exp: "item", "item.date >= sitetime" | last %} + {% assign tournaments = nextevent.games | where_exp: "item", "item.tournament" %} + {% if tournaments and tournaments.size != 0 %} + +

There will be a tournament for the next event on {{ nextevent.date | date: "%a, %b %d, %Y" }}

+
    + {% for game in tournaments %} + {% assign time = game.time | split: ":"%} + {% if game.time %} +
  • {{ game.time }}UTC {{ game.title }}
  • + {% else %} +
  • {{ game.title }}
  • + {% endif %} + {% endfor %} +
+

Ranking

+
    +

    Rounds

    +
    + + + {% else %} +

    No tournaments have been planned for the next event.

    + {% endif %} +

    Rules

    +

    By joining the tournament you accept following rules:

    +

    MOST IMPORTANT!

    +

    The most important rule is: HAVE FUN! Surely, the tournament is competitive, however, don't forget why we are all here - to have fun playing games together!

    +

    NO CHEATING!

    +

    If you cheat you will get banned from this and all upcoming tournaments! Cheating is: manipulating the game for your advantage. So any third-party tool that helps you is not allowed! Due to the blessing that FOSS games can be modified, modifications that give you an advantage are also considered cheating! So use the official binaries to play the tournament! If no binaries are available and you have to compile it on your own you are not allowed to modify the source. If there is any confusion contact us in advance and we will find a solution.

    +

    NO GRIEFING!

    +

    Griefers are going to be kicked immediately and if it happens frequently you will get banned from upcoming tournaments. We are all human beings and hopefully capable of being nice to each other! So respect each other and there will not be any problems!

    +

    Leaving the tournament while it is still ongoing while you still have rounds to play is also not very nice.