From fd5fc21b1241e8a3920af1c61ee9c55ab3c786a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Holly?= Date: Sun, 6 Dec 2020 14:53:06 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + Build.md | 19 + Dockerfile | 94 ++++ Readme.md | 105 ++++ docker-assets/backup-eressea.patch | 25 + docker-assets/check-orders.sh.patch | 19 + docker-assets/create-orders.patch | 16 + docker-assets/lua-scripts/modifymap.lua | 15 + docker-assets/lua-scripts/newgame.lua | 30 ++ docker-assets/run-eressea.sh | 62 +++ docker-assets/start.sh | 559 ++++++++++++++++++++++ docker-assets/template-config/fetchmailrc | 18 + docker-assets/template-config/logrotate | 9 + docker-assets/template-config/muttrc | 47 ++ docker-assets/template-config/procmailrc | 25 + 15 files changed, 1044 insertions(+) create mode 100644 .gitignore create mode 100644 Build.md create mode 100644 Dockerfile create mode 100644 Readme.md create mode 100644 docker-assets/backup-eressea.patch create mode 100644 docker-assets/check-orders.sh.patch create mode 100644 docker-assets/create-orders.patch create mode 100644 docker-assets/lua-scripts/modifymap.lua create mode 100644 docker-assets/lua-scripts/newgame.lua create mode 100755 docker-assets/run-eressea.sh create mode 100755 docker-assets/start.sh create mode 100644 docker-assets/template-config/fetchmailrc create mode 100644 docker-assets/template-config/logrotate create mode 100644 docker-assets/template-config/muttrc create mode 100644 docker-assets/template-config/procmailrc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/Build.md b/Build.md new file mode 100644 index 0000000..d004ed4 --- /dev/null +++ b/Build.md @@ -0,0 +1,19 @@ +# Eressea Docker +To build the Docker Image call next command in the folder where `Dockerfile` is located: +``` +docker build \ + -t jacsid/eressea \ + --build-arg eressea_branch=develop \ + --build-arg echeck_branch=develop \ + . +``` +You can choose to build the image with [Eressea](https://github.com/eressea/server) **master** or **develop** branch. + +`EChecker` is currently under development. In the [GitHub Repository](https://github.com/eressea/echeck) only the master branch is available. Because this is the one, which is in active development, the Docker image uses the branch name **develop**. +The older versions are available as Debian [package](https://packagecloud.io/enno/eressea). If you choose `echeck_branch=`**master** the image uses version 4.4.9 + +***But note: This version does not run with Debian. It fails with segmentation fault.*** + +Hence you should bild the image with one of these options: +* --build-arg eressea_branch=develop --build-arg echeck_branch=develop +* --build-arg eressea_branch=master --build-arg echeck_branch=develop \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fd799f5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,94 @@ +# develop, master +ARG echeck_branch=master +ARG eressea_branch=develop + +#------------------------------------------------------------------------------- +FROM debian:buster-slim as builder +RUN apt-get update && \ + apt-get install -y git gcc make gettext + +#------------------------------------------------------------------------------- +# version 4.4.9 will not work in buster (segmentation fault) +FROM builder as echeck-master +RUN apt-get install -y curl && \ + curl -s https://packagecloud.io/install/repositories/enno/eressea/script.deb.sh | bash && \ + apt-get install echeck=4.4.9 && \ + mkdir -p /usr/share/locale/de/LC_MESSAGES + +#------------------------------------------------------------------------------- +FROM builder as echeck-develop +RUN git clone -b master https://github.com/eressea/echeck.git git.echeck && \ + cd git.echeck && \ + mkdir -p /usr/share/locale/de/LC_MESSAGES && \ + make install + +#------------------------------------------------------------------------------- +FROM echeck-${echeck_branch} as eressea-base +COPY docker-assets/check-orders.sh.patch /eressea/ +RUN mkdir -p /eressea/server && \ + cd /eressea && \ + git clone -b master https://github.com/eressea/orders-php.git git.orders-php && \ + cd /eressea/git.orders-php && \ + patch check-orders.sh < /eressea/check-orders.sh.patch && \ + make install + +#------------------------------------------------------------------------------- +FROM eressea-base as eressea +ARG eressea_branch +COPY docker-assets/backup-eressea.patch /eressea/ +COPY docker-assets/create-orders.patch /eressea/ +RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y \ + cmake luarocks libxml2-dev liblua5.2-dev libtolua-dev libncurses5-dev libsqlite3-dev \ + libexpat1-dev && \ + cd /eressea && \ + git clone -b $eressea_branch https://github.com/eressea/server.git git.eressea && \ + cd git.eressea && \ + git submodule update --init && \ + patch process/backup-eressea < /eressea/backup-eressea.patch && \ + patch process/create-orders < /eressea/create-orders.patch && \ + s/cmake-init && \ + s/build && \ + ln -sf conf/eressea.ini && \ + s/install -f + +#------------------------------------------------------------------------------- +FROM debian:buster-slim as final-image +ARG echeck_branch +ARG eressea_branch + +LABEL version="eressea-${eressea_branch}.echeck-${echeck_branch}" +LABEL maintainer="juergen.holly@jacs.at" +LABEL description="Pbem Eressea" + +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 +ENV ERESSEA=/data +ENV PATH="${PATH}:/usr/games" + +RUN apt-get update && \ + apt-get install -y liblua5.2-0 libsqlite3-0 libncurses5 libreadline7 libexpat1 python python-pip mutt nano \ + logrotate pwgen zip luarocks fetchmail procmail php7.3 gettext php7.3-sqlite && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + pip install bcrypt j2cli && \ + apt-get autoremove -y && \ + sed --in-place '/en_US.UTF-8/s/^# //' /etc/locale.gen && \ + sed --in-place '/de_DE.UTF-8/s/^# //' /etc/locale.gen && \ + locale-gen + +COPY docker-assets/template-config/ /eressea/template-config/ +COPY docker-assets/lua-scripts/ /eressea/lua-scripts/ +COPY docker-assets/run-eressea.sh /eressea/run-eressea.sh +COPY docker-assets/start.sh /eressea/start.sh +COPY --from=eressea /eressea/server/ /eressea/server/ +COPY --from=eressea /eressea/git.eressea/scripts/tools /eressea/server/scripts/tools +COPY --from=eressea /eressea/git.eressea/s/preview /eressea/server/bin/ +COPY --from=eressea /usr/games/echeck /usr/games/echeck +COPY --from=eressea /usr/share/locale/de/LC_MESSAGES/ /usr/share/locale/de/LC_MESSAGES/ +COPY --from=eressea /usr/share/games/echeck/ /usr/share/games/echeck/ +COPY --from=eressea /eressea/git.orders-php/ /eressea/orders-php/ + +VOLUME ["/data"] +WORKDIR /data +ENTRYPOINT ["/eressea/start.sh"] +CMD ["help"] diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..3bc65ff --- /dev/null +++ b/Readme.md @@ -0,0 +1,105 @@ +# Eressea Docker +This Docker image will provide a full [Eressea](https://wiki.eressea.de/index.php/Hauptseite) installation to host an own game. +More details about Eressea find on +- their [homepage](https://www.eressea.de/) +- in [wiki](https://wiki.eressea.de/index.php/Hauptseite) you find the game rules and a lot of other information +- and finally the source code, which is hosted on [GitHub](https://github.com/eressea) + +## Volumes +By default, the image expects a single volume, located at `/data`. It will hold +* configuration files +* log files +* e-mail +* game data +* game data backups + +## General +This image provides a command line interface. To see all possible commands, run the `help` command: + +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea help +``` + +## Initial setup + +### Initiailze volume +The empty `/data` volume needs to be initialzed. Without this step, none of the provided commands will work. + +First, it is necessary to create the ini files: +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea generate -i \ + --game_name=MyOwnEressea \ + --rules=e3 \ + --from=gameserver@myhoster.com \ + --realname="MyOwnEressea\ Game\ Server" \ + --imap_server=imap.myhoster.com \ + --imap_user=imapuser \ + --imap_pass=imappwd \ + --imap_port=993 \ + --smtp_server=smtp.myhoster.com \ + --smtp_user=smtpuser \ + --smtp_pass=smtppwd \ + --smtp_port=587 +``` +To get further details, call `generate` command with option `-h` + +Afterwards, create the relevant game folders: +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea generate -g +``` + +It is possible to combine both steps into one call by combining options `-i` and `-g`. + +### Initialize game +Now in `/data/game-1` a file called `newfactions` is available. Enter all players who will join the game. Each player goes into a seperate line: +``` +test.player@hotmail.com elf de +seppl@gmx.at orc en +[...] +``` +The entries, separated by one white space character, are email, race, and language. The language is either "de" for German or "en" for English. This file is read automatically when the game editor starts (see also [GM-Guide](https://github.com/eressea/server/wiki/GM-Guide#adding-players) on Eressea [GitHub](https://github.com/eressea/server) wiki). + +Now create the game map and seed the new players. +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea map -n -w 50 -e 50 -s +``` +This command will create a new 50x50 map (option `-n`, `-w`, `-e`). In general, the `map` command opens the game map editor. With the option `-s` it will automatically be saved, when you exit the editor with key `Q`. +On the game map, seed all new players via key `s`. To see where other players are located, press `h` followed by `p`. + +### Send first game reports +After players were seeded to the map, run the first game turn which sends the intial reports to the players. + +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea run +``` + +## Day by day use +The players send their turn commands via email (see [initialize](#initiailze-volume) chapter above). Use the command `mail` to process incoming e-mails. + +Please note, that only Eressea mails are processed, **all other e-mails are deleted from server**! + +You maybe want to fetch e-mails (option `-f`) during the day and once a night you check the new game orders (option `-c`). But it is also possible to combine the options in one call. Use e.g. `cron` to automatize the calls. + +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea mail -f -c +``` + +And somewhen the next game turn is processed with command `run`: + +``` +docker run -it --rm \ + -v /path/to/my/local/eressea/folder:/data \ + jacsid/eressea run +``` diff --git a/docker-assets/backup-eressea.patch b/docker-assets/backup-eressea.patch new file mode 100644 index 0000000..030d23b --- /dev/null +++ b/docker-assets/backup-eressea.patch @@ -0,0 +1,25 @@ +--- backup-eressea.org 2020-12-03 19:01:33.947594665 +0000 ++++ backup-eressea 2020-12-03 19:39:46.489607175 +0000 +@@ -3,12 +3,21 @@ + ERESSEA=$HOME/eressea + echo "The ERESSEA environment variable is not set. Assuming $ERESSEA." + fi ++ + GAME=$1 + ++# script can have 3 parameters ++# $1 = game number ++# $2 = turn ++# $3 = upload url ++# the upload url and hence the upload it only done, if all three parameter are given ++[ -n $3 ] && UPLOAD_WEBDAV_URL=$3 ++ + upload() { ++ [ -z $UPLOAD_WEBDAV_URL ] && return + SRC="$1" + DST=$(basename "$SRC") +- echo put "$SRC" "$DST" | cadaver "https://dav.box.com/dav/Eressea/game-$GAME/" ++ echo put "$SRC" "$DST" | cadaver "$UPLOAD_WEBDAV_URL" + } + + if [ ! -d $ERESSEA/game-$GAME ]; then diff --git a/docker-assets/check-orders.sh.patch b/docker-assets/check-orders.sh.patch new file mode 100644 index 0000000..c9223b5 --- /dev/null +++ b/docker-assets/check-orders.sh.patch @@ -0,0 +1,19 @@ +--- check-orders.sh.bak 2020-12-05 17:24:17.709599000 +0000 ++++ check-orders.sh 2020-12-05 17:25:04.054911000 +0000 +@@ -4,6 +4,7 @@ + #set -x + + GAME="$1" ++RULES="$2" + WARNINGS=0 + + if [ -z "$ERESSEA" ] ; then +@@ -40,7 +41,7 @@ + check() { + LANGUAGE="$1" + FILENAME="$2" +- "echeck" -w0 -x -R "e$GAME" -L "$LANGUAGE" "$FILENAME" ++ "echeck" -w0 -x -R "$RULES" -L "$LANGUAGE" "$FILENAME" + } + + orders() { diff --git a/docker-assets/create-orders.patch b/docker-assets/create-orders.patch new file mode 100644 index 0000000..8c153e7 --- /dev/null +++ b/docker-assets/create-orders.patch @@ -0,0 +1,16 @@ +--- create-orders.org 2020-12-03 20:21:23.379383000 +0000 ++++ create-orders 2020-12-03 20:22:20.290087000 +0000 +@@ -10,12 +10,12 @@ + + cd "$ERESSEA/game-$GAME" || exit + +-lockfile -r3 -l120 orders.queue.lock + if [ -d "orders.dir.$TURN" ]; then + echo "orders.dir.$TURN already exists" + exit + fi + rm -f "orders.$TURN" ++lockfile -r3 -l120 orders.queue.lock + + cd orders.dir || exit + diff --git a/docker-assets/lua-scripts/modifymap.lua b/docker-assets/lua-scripts/modifymap.lua new file mode 100644 index 0000000..a28e4f5 --- /dev/null +++ b/docker-assets/lua-scripts/modifymap.lua @@ -0,0 +1,15 @@ +local path = 'scripts' +if config.install then + path = config.install .. '/' .. path +end +package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua' +require 'eressea.path' +require 'eressea' +require 'eressea.xmlconf' + +eressea.read_game(get_turn() .. ".dat") +gmtool.editor() +eressea.write_game(get_turn() .. ".dat") +write_database() +write_passwords() + diff --git a/docker-assets/lua-scripts/newgame.lua b/docker-assets/lua-scripts/newgame.lua new file mode 100644 index 0000000..36f2b2c --- /dev/null +++ b/docker-assets/lua-scripts/newgame.lua @@ -0,0 +1,30 @@ +require("config") +require("eressea") +require("tools/build-e3") + +-- script build-e3 calls functions in module eressea; but without module name +-- don't how to solve this; but is fully operational +free_game = eressea.free_game + +-- first we have to create an empty game data file +-- reason: only when a game is loaded, the random seed is initialized correctly +eressea.free_game() +eressea.write_game(get_turn() .. ".dat") + +-- load game data in order to seed initialized +eressea.free_game() +eressea.read_game(get_turn() .. ".dat") +local w = os.getenv("ERESSEA_MAP_WIDTH") +if not w then + w = 80 +end +local h = os.getenv("ERESSEA_MAP_HEIGHT") +if not h then + h = 40 +end +local pl = plane.create(0, -w/2, -h/2, w+1, h+1) +build(pl) +fill(pl, w, h) + +-- save new world +eressea.write_game(get_turn() .. ".dat") diff --git a/docker-assets/run-eressea.sh b/docker-assets/run-eressea.sh new file mode 100755 index 0000000..c33e309 --- /dev/null +++ b/docker-assets/run-eressea.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# this script is based on run-eressea.cron +# differences to original +# it is possible to run a turn with empty orders + +eval "$(luarocks path)" +GAME=$1 +ENABLE_EMPTY_ORDERS=$2 +( +[ "$ENABLED" == "no" ] && exit +[ -z "$ERESSEA" ] && ERESSEA="$HOME/eressea" + +export ERESSEA +BIN="$ERESSEA/server/bin" +TURN=$(cat "$ERESSEA/game-$GAME/turn") +if [ ! -e "$ERESSEA/game-$GAME/data/$TURN.dat" ]; then + echo "data file $TURN is missing, cannot run turn for game $GAME" + exit 1 +fi +REPORTS="$ERESSEA/game-$GAME/reports" +if [ -d "$REPORTS" ]; then + rm -rf "$REPORTS" +fi +mkdir "$REPORTS" + +cd "$ERESSEA/game-$GAME" || exit + +if [ -d test ]; then + touch test/execute.lock +fi + +"$BIN/create-orders" "$GAME" "$TURN" +if [ ! -s "$ERESSEA/game-$GAME/orders.$TURN" ]; then + if [ "$ENABLE_EMPTY_ORDERS" != "yes"]; then + echo "server did not create orders for turn $TURN in game $GAME" + exit 2 + fi +fi + +"$BIN/backup-eressea" "$GAME" "$TURN" +rm -f execute.lock +"$BIN/run-turn" "$GAME" "$TURN" +touch execute.lock + +if [ ! -s "$REPORTS/reports.txt" ]; then + echo "server did not create reports.txt in game $GAME" + exit 4 +fi +"$BIN/backup-eressea" "$GAME" "$TURN" +let TURN=$TURN+1 +if [ ! -s "$ERESSEA/game-$GAME/data/$TURN.dat" ]; then + echo "server did not create data for turn $TURN in game $GAME" + exit 3 +fi +echo "sending reports for game $GAME, turn $TURN" +"$BIN/compress.sh" "$GAME" "$TURN" +"$BIN/sendreports.sh" "$GAME" +"$BIN/backup-eressea" "$GAME" "$TURN" +rm -f test/execute.lock +) | tee -a "$HOME/log/eressea.cron.log" + diff --git a/docker-assets/start.sh b/docker-assets/start.sh new file mode 100755 index 0000000..fbea1c8 --- /dev/null +++ b/docker-assets/start.sh @@ -0,0 +1,559 @@ +#!/bin/bash +base_dir="$(dirname "$0")" + +# ------------------- +# -- Helper functions + +function ini_sec() { + /eressea/server/bin/inifile /data/game-1/eressea.ini add $1 +} + +function ini_add() { + /eressea/server/bin/inifile /data/game-1/eressea.ini add $1:$2 $3 +} + +function ini_get() { + /eressea/server/bin/inifile /data/game-1/eressea.ini get $1:$2 +} + +function get_turn() { + turn=0 + [ -e /data/game-1/turn ] && turn=$(cat /data/game-1/turn) + [ -z $turn ] && turn=0 +} + +# ----------------- +# -- Main-commands + +cmd_help() { + usage() { + echo "" + echo "Usage: $0 COMMAND [-h] [arguments]" + echo "" + echo "supported COMMANDs:" + echo " addpwd adds password in newfactions" + echo " bash start a bash shell" + echo " generate generate eressea.ini and all relevant files" + echo " help show this help" + echo " mail process incoming e-mail" + echo " map generate/edit game map" + echo " run execute Eressea game turn" + echo " shutdown remove temporaray Eressea environment" + echo " startup create temporaray Eressea environment which is necessary for scripts" + echo "" + echo "arguments:" + echo "-h ... show more details of command" + exit 2 + } + usage +} + +cmd_bash() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Starts an interactive bash shell." + echo "Usage: $0 bash [-h] [-n]" + echo "-h ... show this help" + echo "-n ... start a 'naked' bash, which means eressea is not setup" + echo " can be done later by invoking '/eressea/start.sh startup'" + echo " before you exit the shell, call '/eressea/start.sh shutdown'" + exit 2 + } + + args=$(getopt --name shutdown -o hn -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + naked=0 + while :; do + case "$1" in + -h) usage ; shift ;; + -n) naked=1; shift ;; + --) shift ; break ;; + esac + done + + [ ${naked} == 0 ] && cmd_startup || echo "started bash without any Eressea environment setup" + /bin/bash + [ ${naked} == 0 ] && cmd_shutdown +} + +cmd_startup() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Setup an environment which enables Eressea to find a runtime environment where all scripts are functional." + echo "Usage: $0 startup [-h]" + echo "-h ... show this help" + exit 2 + } + + args=$(getopt --name shutdown -o h -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + while :; do + case "$1" in + -h) usage ; shift ;; + --) shift ; break ;; + esac + done + + mkdir -p /data/config + mkdir -p /data/log + + ln -sf /data/config/muttrc ~/.muttrc + ln -sf /data/config/fetchmailrc ~/.fetchmailrc + ln -sf /data/config/procmailrc ~/.procmailrc + + ln -sf /eressea/server /data/server + ln -sf /eressea/orders-php /data/orders-php + + mkdir -p /data/game-1 + mkdir -p /data/game-1/backup + ln -sf /data/server/scripts/config.lua /data/game-1/config.lua + ln -sf /data/server/bin/eressea /data/game-1/eressea + ln -sf /data/server/scripts/reports.lua /data/game-1/reports.lua + ln -sf /data/server/scripts/run-turn.lua /data/game-1/run-turn.lua + + cd /data/game-1 + echo "Eressea environment setup complete" +} + +cmd_shutdown() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Removes temporary Eressea environment from mapped /data folder." + echo "Usage: $0 shutdown [-h]" + echo "-h ... show this help" + exit 2 + } + + args=$(getopt --name shutdown -o h -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + while :; do + case "$1" in + -h) usage ; shift ;; + --) shift ; break ;; + esac + done + + [ -e /data/game-1/config.lua ] && rm /data/game-1/config.lua + [ -e /data/game-1/eressea ] && rm /data/game-1/eressea + [ -e /data/game-1/reports.lua ] && rm /data/game-1/reports.lua + [ -e /data/game-1/run-turn.lua ] && rm /data/game-1/run-turn.lua + + [ -e /data/server ] && rm /data/server + [ -e /data/orders-php ] && rm /data/orders-php + + [ -e ~/.muttrc ] && rm -f ~/.muttrc + [ -e ~/.fetchmailrc ] && rm -f ~/.fetchmailrc + [ -e ~/.procmailrc ] && rm -f ~/.procmailrc + + [ -e /data/config/logrotate ] && logrotate /data/config/logrotate + + echo "Eressea environment successfully removed" +} + +cmd_generate() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Generates eressea.ini file and all other necessary files/folders needed by this Docker container." + echo "Usage: $0 generate [options]" + echo "" + echo "General option:" + echo "-f force generating of files - delete will be done without prompt!" + echo "-g generate all other necessary files and folders (values are defined by eressea.ini and mail.ini)" + echo "-h show this help" + echo "-i generate eressea.ini and mail.ini file" + echo "" + echo "If eressea.ini is not available, option -i is mandatory. All of the following options are also necessray:" + echo " --from e-mail address Eressea postbox" + echo " --imap_server IMAP server address. If not provided, value of smtp_server is used." + echo " --imap_user user for IMAP server. If not provided, value of smtp_user is used." + echo " --imap_pass password of IMAP user. If not provided, value of smtp_pass is used." + echo " --smtp_server SMTP server address. If not provided, value of imap_server is used." + echo " --smtp_user user for SMTP server. If not provided, value of imap_user is used." + echo " --smtp_pass password of SMTP user. If not provided, value of imap_pass is used." + echo "" + echo " Optional:" + echo " --game_name name of self hosted Eressea game. Default=MyEressea" + echo " --realname name> real name used for e-Mails. Default=Game Server " + echo " --smtp_port port of SMTP server, Default=587" + echo " --imap_port port of IMAP server, Default=993" + echo " --rules ruleset, Defaule=e3" + exit 2 + } + + args=$(getopt --name generate -o fghi --long game_name:,from:,realname:,smtp_server:,smtp_port:,smtp_user:,smtp_pass:,imap_server:,imap_port:,imap_user:,imap_pass:,rules: -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + force=0 + do_gen=0 + do_ini=0 + game_name="MyEressea" + imap_port=993 + smtp_port=587 + rules="e3" + + while :; do + case "$1" in + -f) force=1 ; shift ;; + -g) do_gen=1 ; shift ;; + -h) usage ; shift ;; + -i) do_ini=1 ; shift ;; + --game_name) game_name="$2" ; shift 2 ;; + --from) from="$2" ; shift 2 ;; + --realname) realname="$2" ; shift 2 ;; + --smtp_server) smtp_server="$2" ; shift 2 ;; + --smtp_port) smtp_port="$2" ; shift 2 ;; + --smtp_user) smtp_user="$2" ; shift 2 ;; + --smtp_pass) smtp_pass="$2" ; shift 2 ;; + --imap_server) imap_server="$2" ; shift 2 ;; + --imap_port) imap_port="$2" ; shift 2 ;; + --imap_user) imap_user="$2" ; shift 2 ;; + --imap_pass) imap_pass="$2" ; shift 2 ;; + --rules) rules="$2" ; shift 2 ;; + --) shift ; break ;; + esac + done + + if [ $do_ini == 1 ]; then + mkdir -p /data/game-1 + [ -e /data/game-1/eressea.ini ] && [ $force == 0 ] && usage "eressea.ini already exists. Add option -f" + + [ -z "$imap_server" ] && [ -n "$smtp_server" ] && imap_server=$smtp_server + [ -z "$imap_user" ] && [ -n "$smtp_user" ] && imap_user=$smtp_user + [ -z "$imap_pass" ] && [ -n "$smtp_pass" ] && imap_pass=$smtp_pass + + [ -z "$smtp_server" ] && [ -n "$imap_server" ] && smtp_server=$imap_server + [ -z "$smtp_user" ] && [ -n "$imap_user" ] && smtp_user=$imap_user + [ -z "$smtp_pass" ] && [ -n "$imap_pass" ] && smtp_pass=$imap_pass + + [ -z "$realname" ] && realname="Game Server ${game_name}" + + [ -z "$game_name" ] || [ -z "$from" ] || [ -z "$realname" ] || [ -z "$rules" ] || \ + [ -z "$smtp_server" ] || [ -z "$smtp_port" ] || [ -z "$smtp_user" ] || [ -z "$smtp_pass" ] || \ + [ -z "$imap_server" ] || [ -z "$imap_port" ] || [ -z "$imap_user" ] || [ -z "$imap_pass" ] && \ + usage "not all options relevant for eressea.ini were provided" + + [ -e /data/game-1/eressea.ini ] && rm -f /data/game-1/eressea.ini + touch /data/game-1/eressea.ini + + ini_sec game + ini_add game locales de,en + ini_add game id 1 + ini_add game start 0 + ini_add game email $from + ini_add game name $game_name + ini_add game seed `shuf -i 0-9999 -n1` + ini_add game dbname eressea.db + ini_add game dbswap :memory: + ini_add game mailcmd `echo "print '$game_name'.upper()" | python` + ini_sec lua + ini_add lua install /data/server + ini_add lua paths /data/server/scripts:/data/server/lunit + ini_add lua rules $rules + echo "eressea.ini generated" + + [ -e /data/config/mail.ini ] && rm -f /data/config/mail.ini + mkdir -p /data/config + echo "[smtp]" > /data/config/mail.ini + echo "server = $smtp_server" >> /data/config/mail.ini + echo "port = $smtp_port" >> /data/config/mail.ini + echo "user = $smtp_user" >> /data/config/mail.ini + echo "pass = $smtp_pass" >> /data/config/mail.ini + echo "[imap]" >> /data/config/mail.ini + echo "server = $imap_server" >> /data/config/mail.ini + echo "port = $imap_port" >> /data/config/mail.ini + echo "user = $imap_user" >> /data/config/mail.ini + echo "pass = $imap_pass" >> /data/config/mail.ini + echo "[general]" >> /data/config/mail.ini + echo "realname = $realname" >> /data/config/mail.ini + echo "mail.ini generated" + fi + + if [ $do_gen == 1 ]; then + [ ! -e /data/game-1/eressea.ini ] && usage "eressea.ini missing. Use option -i" + + if [ $force == 1 ]; then + echo "existing game data deleted" + for node in /data/game-1/* + do + [ $node == "/data/game-1/eressea.ini" ] && continue + [ -d $node ] && rm -rf $node || rm -f $node + done; + else + echo "existing game data is not touched. Missing files are recreated" + fi + + mkdir -p /data/config + tmpfile=$(mktemp ini.XXX) + cat /data/game-1/eressea.ini > $tmpfile + cat /data/config/mail.ini >> $tmpfile + + [ -e /data/config/fetchmailrc ] && [ $force == 0 ] && rm -f /data/config/fetchmailrc + [ ! -e /data/config/fetchmailrc ] && j2 -f ini /eressea/template-config/fetchmailrc $tmpfile > /data/config/fetchmailrc + chmod 700 /data/config/fetchmailrc + + [ -e /data/config/procmailrc ] && [ $force == 0 ] && rm -f /data/config/procmailrc + [ ! -e /data/config/procmailrc ] && j2 -f ini /eressea/template-config/procmailrc $tmpfile > /data/config/procmailrc + + [ -e /data/config/muttrc ] && [ $force == 0 ] && rm -f /data/config/muttrc + [ ! -e /data/config/muttrc ] && j2 -f ini /eressea/template-config/muttrc $tmpfile > /data/config/muttrc + + [ -e /data/config/logrotate ] && [ $force == 0 ] && rm -f /data/config/logrotate + [ ! -e /data/config/logrotate ] && cp /eressea/template-config/logrotate /data/config/logrotate + + rm -f $tmpfile + + mkdir -p /data/mail/cache + mkdir -p /data/mail/postbox/inbox/{cur,new,tmp} + mkdir -p /data/mail/postbox/sent/{cur,new,tmp} + mkdir -p /data/mail/postbox/draft/{cur,new,tmp} + mkdir -p /data/mail/certificates + + mkdir -p /data/game-1/data + mkdir -p /data/game-1/reports + mkdir -p /data/game-1/backup + [ ! -e /data/game-1/newfactions ] && touch /data/game-1/newfactions + [ ! -e /data/game-1/turn ] && echo 0 > /data/game-1/turn + + echo "all basic game files generated" + echo "next step would be to create a new game file / map; therefore use '$0 map -h'" + fi + + [ $do_gen == 0 ] && [ $do_ini == 0 ] && usage "nothing to generate. Use option -i or -g" +} + +cmd_map() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Generate or edit Eressea map." + echo "Usage: $0 map [options]" + echo "-h ... show this help" + echo "-n ... generate new map. If map already exists, it will be overwritten!" + echo "-w ... width of new map - only relevant together with -n" + echo "-e ... height of new map - only relevant together with -n" + echo "-t ... turn" + echo "-s ... save map when editor is closed" + exit 2 + } + + args=$(getopt --name shutdown -o hnw:e:t:s -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + create_new=0 + export ERESSEA_MAP_WIDTH=60 + export ERESSEA_MAP_HEIGHT=40 + get_turn + save=0 + + while :; do + case "$1" in + -h) usage ; shift ;; + -n) create_new=1 ; shift ;; + -w) ERESSEA_MAP_WIDTH=$2 ; shift 2 ;; + -e) ERESSEA_MAP_HEIGHT=$2; shift 2 ;; + -t) turn=$2 ; shift 2 ;; + -s) save=1 ; shift ;; + --) shift ; break ;; + esac + done + + cmd_startup + + if [ $create_new == 1 ]; then + ini_sec game + ini_add game seed `shuf -i 0-9999 -n1` + + ./eressea -v 0 -t $turn /eressea/lua-scripts/newgame.lua + echo "created new game map with size ${ERESSEA_MAP_WIDTH}x${ERESSEA_MAP_HEIGHT}" + fi + + if [ $save == 1 ]; then + ./eressea -v 0 -t $turn /eressea/lua-scripts/modifymap.lua + else + ./eressea -v 0 -t $turn /data/server/scripts/map.lua + fi + + cmd_shutdown +} + +cmd_addpwd() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "In file 'newfactions' on lines without password a secure one is generated and inserted." + echo "Usage: $0 addpwd [options]" + echo "-f ... force usage of new password" + echo "-h ... show this help" + exit 2 + } + + args=$(getopt --name shutdown -o hf -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + force=0 + while :; do + case "$1" in + -h) usage ; shift ;; + -f) force=1; shift ;; + --) shift ; break ;; + esac + done + + [ ! -e "/data/game-1/newfactions" ] && echo "file newfactions does not exist" && exit + + tmpfile=$(mktemp newfactions.XXX) + touch $tmpfile + + while IFS=" " read -r email race language pass alliance + do + [ -z "$email" ] && continue + echo "found player $email ($race), language $language`[ -n "$alliance" ] && echo " in alliance with $alliance"`" + if [ -z "$pass" ] || [ $force == 1 ]; then + new_pass="`pwgen -c -n -y 8 1`" + echo " new password $new_pass`[ -n "$pass" ] && echo " replaces former password $pass"`" + else + new_pass=$pass + echo " uses password $pass" + fi + echo "$email $race $language $new_pass`[ -n "$alliance" ] && echo " $alliance"`" >> $tmpfile + done < /data/game-1/newfactions + + rm -f /data/game-1/newfactions + mv $tmpfile /data/game-1/newfactions +} + +cmd_mail() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Process incoming e-mails" + echo "Usage: $0 mail [options]" + echo "-c ... check orders and send email to player" + echo "-f ... fetch mail from server and pre-process them" + echo "-h ... show this help" + exit 2 + } + + args=$(getopt --name shutdown -o hcf -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + fetch=0 + check=0 + while :; do + case "$1" in + -f) fetch=1; shift ;; + -c) check=1; shift ;; + -h) usage ; shift ;; + --) shift ; break ;; + esac + done + + [ $(expr $fetch + $check) == 0 ] && usage "either option -f or -c is necessary" + + cmd_startup + + if [ $fetch == 1 ]; then + touch /data/log/fetchmail.log + fetchmail >> /data/log/fetchmail.log 2>&1 + fi + + if [ $check == 1 ]; then + mkdir -p /data/game-1/orders.dir + rules="$(ini_get lua rules)" + /data/orders-php/check-orders.sh 1 $rules + fi + + cmd_shutdown +} + +cmd_run() { + usage() { + [ -n "$1" ] && echo -e "\n$1" + echo "" + echo "Execute next game turn" + echo "Usage: $0 rung [options]" + echo "-h ... show this help" + exit 2 + } + + args=$(getopt --name shutdown -o h -- "$@") + + if [ $? != 0 ]; then + usage + exit + fi + eval set -- "$args" + + while :; do + case "$1" in + -h) usage ; shift ;; + --) shift ; break ;; + esac + done + + cmd_startup + mkdir -p $HOME/log + mkdir -p /data/game-1/orders.dir + touch /data/log/eressea.cron.log + ln -sf /data/log/eressea.cron.log $HOME/log/eressea.cron.log + + get_turn + enable_empty_orders="no" + [ "$turn" == "0" ] && enable_empty_orders="yes" + /eressea/run-eressea.sh 1 + + cmd_shutdown +} + +# ---------------- +# -- Main function + +COMMAND="$1" +shift + +case $COMMAND in + "help" | "startup" | "shutdown" | "bash" | "generate" | "map" | "addpwd" | "mail" | "run") eval cmd_$COMMAND "$@" ;; + *) cmd_help ;; +esac diff --git a/docker-assets/template-config/fetchmailrc b/docker-assets/template-config/fetchmailrc new file mode 100644 index 0000000..3cc4482 --- /dev/null +++ b/docker-assets/template-config/fetchmailrc @@ -0,0 +1,18 @@ +################################## +## UPDATE EVERYTHING FROM HERE >>> + +# set correct mail server and its credentials +# note: mails are removed from IMAP server and copied in local mailbox +poll {{imap.server}} proto IMAP + with port {{imap.port}} + user "{{imap.user}}" + pass "{{imap.pass}}" + ssl + fetchall + #keep + +## <<< UPDATE EVERYTHING TO HERE +################################ + +mda "/usr/bin/procmail -d %T" +set no bouncemail diff --git a/docker-assets/template-config/logrotate b/docker-assets/template-config/logrotate new file mode 100644 index 0000000..bc2d373 --- /dev/null +++ b/docker-assets/template-config/logrotate @@ -0,0 +1,9 @@ +/data/log/*.log { + + weekly + create 0644 root root + rotate 2 + compress + + delaycompress +} diff --git a/docker-assets/template-config/muttrc b/docker-assets/template-config/muttrc new file mode 100644 index 0000000..c2a20df --- /dev/null +++ b/docker-assets/template-config/muttrc @@ -0,0 +1,47 @@ +################################## +## UPDATE EVERYTHING FROM HERE >>> + +# name of the sender for eressea mails +set from = "{{game.email}}" +set realname = "{{general.realname}}" + +# credentials for smtp access +set smtp_url = "smtp://{{smtp.user}}@{{smtp.server}}:{{smtp.port}}" +set smtp_pass = "{{smtp.pass}}" + +# from time to time change this value from no to yes. +# It will clean the mail caches. But it can be slow in big mailboxes +set message_cache_clean = no + +## <<< UPDATE EVERYTHING TO HERE +################################ + +# caches +set header_cache = "/data/mail/cache/headers" +set message_cachedir = "/data/mail/cache/bodies" +set certificate_file = "/data/mail/certificates" + +# mailbox +set mbox_type="maildir" +set folder="/data/mail/postbox" +set spoolfile="+inbox" +set record="+sent" +set postponed="+draft" +set move=no + +mailboxes `echo -n "+ "; find /data/mail/postbox -maxdepth 1 -type d -name "*" -printf "+'%f' "` +macro index c "?" "open a different folder" +macro pager c "?" "open a different folder" +macro index C "?" "copy a message to a mailbox" +macro index M "?" "move a message to a mailbox" +macro compose A "?" "attach message(s) to this message" + +# various options +set mail_check = 30 +set sort = "threads" +set sort_aux = "reverse-last-date-received" +set auto_tag = yes +hdr_order Date From To Cc +alternative_order text/plain text/html * +auto_view text/html +set editor = "nano" diff --git a/docker-assets/template-config/procmailrc b/docker-assets/template-config/procmailrc new file mode 100644 index 0000000..f0bf723 --- /dev/null +++ b/docker-assets/template-config/procmailrc @@ -0,0 +1,25 @@ +SHELL=/bin/bash +PATH=/usr/sbin:/usr/bin:/bin +MAILDIR=/data/mail/postbox +DEFAULT=$MAILDIR +LOGFILE=/data/log/procmail.log +LOG="" +VERBOSE=yes +FROM=`formail -cx From:` +ERESSEA=/data + +:0:server.lock +* ^Subject:.*{{game.mailcmd}} REPORT \/.* +* !From: {{game.email}} +| tr -d '^Z' | /data/server/bin/sendreport.sh 1 "$FROM" $MATCH + +:0:server.lock +* ^Subject:.*{{game.mailcmd}} BEFEHLE +| grep -v '>From' | /data/server/bin/orders-accept 1 de + +:0:server.lock +* ^Subject:.*{{game.mailcmd}} ORDERS +| grep -v '>From' | /data/server/bin/orders-accept 1 en + +:0: +$MAILDIR/inbox/