#!/bin/bash

#/**
# *
# *   Copyright © 2010-2018 by xhost.ch GmbH
# *
# *   All rights reserved.
# *
# **/

CFG_FILE="setup.config"

### Function definitions

function ask {
    if [ ! "`eval echo \\$$1`" = "" ]; then
        var="`eval echo \\$$1`"
        eval echo $4
        return
    fi
    def=$2
    if [ "$1" = "MC_DAEMON_PW" -o "$1" = "MC_DB_PASS" ]; then
        extra="s"
    else
	extra=""
    fi
    eval read -r$extra -p '"'$3' "'
    if [ "$REPLY" = "" ]; then
        export "$1"="$def"
    else
        export "$1"="$REPLY"
    fi
}

function askSave {
    read -p "Save entered settings? ([y]/n) "
    if [ "$REPLY" != "n" ]; then
        save
    fi
}

function save {
    echo -n "Saving settings to '$CFG_FILE'... "
    export | grep ' MC_'  > "$CFG_FILE"
    chmod o-rwx "$CFG_FILE"
    echo "done"
    echo "IMPORTANT: Make sure this file is not accessible by unauthorized users."
    echo
}

function quit {
    askSave
    exit
}

function sigQuit {
    echo
    quit
}

trap sigQuit SIGINT SIGTERM

INSTALL="bin/ jar/ launcher/ scripts/ ssl/ templates/ eula.txt multicraft.conf.dist default_server.conf.dist server_configs.conf.dist"

### Basic checks

for i in $INSTALL; do
    if [ ! -e "$i" ]; then
        echo "Error: Can't find '$i'! This script needs to be started from inside the Multicraft package directory."
        echo "Aborting setup."
        quit
    fi
done

### Begin

echo
echo "################################################################################"
echo "*** Welcome to Multicraft!"
echo "################################################################################"
echo
echo "This installer will help you get Multicraft up and running."
echo "No changes are made to the system until all of the required information has been collected."
echo
echo "NOTE: This script automates the installation as described on the Multicraft website. Use it at your own risk."
echo
echo

FILE_ARCH="64bit"
SYS_ARCH="64bit"
if [ "`uname -m | grep 'x86_64'`" = "" ]; then
    SYS_ARCH="32bit"
fi

if [ ! "$FILE_ARCH" = "$SYS_ARCH" ]; then
    echo
    echo "WARNING: It seems that the system architecture ($SYS_ARCH) does not match the package you've downloaded ($FILE_ARCH). Please download the correct version of Multicraft for your system."
    read -p "Press [Enter] to proceed anyway, Ctrl-C to abort."
fi


### Load cfg?
if [ -e "$CFG_FILE" ] ; then
    ask "LOAD_CFG" "y" "Found '$CFG_FILE', load settings from this file? [\$def]/n" "-"
    if [ "$LOAD_CFG" = "y" ]; then
        source "$CFG_FILE"
    fi
fi

### Collect basic information

ask "MC_MULTIUSER" "y" "Run each Minecraft server under its own user? (Multicraft will create system users): [\$def]/n" "Create system user for each Minecraft server: \$var"

if [ "$USER" = "root" ]; then
    def="minecraft"
else
    def="$USER"
fi
ask "MC_USER" "$def" "Run Multicraft under this user: [\$def]" "Multicraft will run as \$var"

if [ "`cat /etc/passwd | awk -F: '{ print $1 }' | grep $MC_USER`" = "" ]; then
    ask "MC_CREATE_USER" "y" "User not found. Create user '$MC_USER' on start of installation? [\$def]/n" "Create user '$MC_USER': \$var"
    if [ "$MC_CREATE_USER" != "y" ]; then
        echo "Won't create user, aborting."
        quit
    fi
    MC_USER_EXISTS="n"
else
    MC_USER_ESISTS="y"
fi

ask "MC_DIR" "/home/$MC_USER/multicraft" "Install Multicraft in: [\$def]" "Installation directory: \$var"
if [ -e "$MC_DIR" ]; then
    ask "MC_DIR_OVERWRITE" "y" "Warning: '$MC_DIR' exists! Continue installing in this directory? [\$def]/n" "Installing in existing directory: \$var"
    if [ "$MC_DIR_OVERWRITE" != "y" ]; then
        echo "Won't install in existing directory, aborting."
        quit
    fi
fi

ask "MC_KEY" "no" "If you have a license key you can enter it now: [\$def]" "License key: \$var"
ask "MC_DAEMON_ID" "1" "If you control multiple machines from one web panel you need to assign each daemon a unique number (requires a Dynamic or custom license). Daemon number? [\$def]" "Daemon number: \$var"
echo
echo

### Local installation?

ask "MC_LOCAL" "y" "Will the web panel run on this machine? [\$def]/n" "Local front end: \$var"

# Try to determine local IP address
IP="`ip a | grep 'inet ' | grep -v '127.0.0.1' | awk '{ print $2 }' | cut -d/ -f1 | head -n1`"
if [ "$IP" = "" ]; then
    # Failed, use localhost instead
    IP="127.0.0.1"
fi
if [ "$MC_LOCAL" != "y" ]; then
    export MC_DB_TYPE="mysql"

    ask "MC_DAEMON_IP" "$IP" "IP the daemon will bind to: [\$def]" "Daemon listening on IP: \$var"
    IP="$MC_DAEMON_IP"
    ask "MC_DAEMON_PORT" "25465" "Port the daemon to listen on: [\$def]" "Daemon port: \$var"
else
    W_USR="www-data"
    W_DIR="/var/www"
    if [ ! "`which yum 2>/dev/null`" = "" ]; then
        W_USR="apache"
        W_DIR="/var/www/html"
    elif [ -d "/var/www/html" ]; then
        W_DIR="/var/www/html"
    fi

    ask "MC_WEB_USER" "$W_USR" "User of the webserver: [\$def]" "Webserver user: \$var"
    ask "MC_WEB_DIR" "$W_DIR/multicraft" "Location of the web panel files: [\$def]" "Web panel directory: \$var"
    if [ -e "$MC_WEB_DIR" ]; then
        ask "MC_WEB_DIR_OVERWRITE" "y" "Warning: '$MC_WEB_DIR' exists! Continue installing the web panel in this directory? [\$def]/n" "Installing in existing web panel directory: \$var"
        if [ "$MC_WEB_DIR_OVERWRITE" != "y" ]; then
            echo "Won't install in existing web panel directory, aborting."
            quit
        fi
    fi
fi
ask "MC_DAEMON_PW" "none" "Please enter a new daemon password (use the same password in the last step of the panel installer)  [\$def]" "Daemon connection password: \$var"

echo
echo

### FTP Server

ask "MC_FTP_SERVER" "y" "Enable builtin FTP server? [\$def]/n" "Enable builtin FTP server: \$var"

if [ "$MC_FTP_SERVER" = "y" ]; then
    # No sensible FTP server address, listen on all interfaces
    if [ "$IP" = "127.0.0.1" -o "$IP" = "" ]; then
        IP="0.0.0.0"
    fi

    ask "MC_FTP_IP" "$IP" "IP the FTP server will listen on (0.0.0.0 for all IPs): [\$def]" "FTP server IP: \$var"
    if [ "$MC_FTP_IP" = "0.0.0.0" ]; then
        # Try determining our external IP address
        EXT_IP="`curl -L http://www.multicraft.org/ip 2> /dev/null`"
        ask "MC_FTP_EXTERNAL_IP" "$EXT_IP" "IP to use to connect to the FTP server (external IP): [\$def]" "FTP server external IP: \$var"

        if [ "$MC_FTP_EXTERNAL_IP" = "" -o "$MC_FTP_EXTERNAL_IP" = "0.0.0.0" ]; then
            # No valid FTP IP configuration, use defaults
            MC_FTP_EXTERNAL_IP=""
            MC_FTP_IP=""
        fi
    fi
    ask "MC_FTP_PORT" "21" "FTP server port: [\$def]" "FTP server port: \$var"

    ask "MC_PLUGINS" "n" "Block FTP upload of .jar files and other executables (potentially dangerous plugins)? [\$def]/y" "Block .jar and executable upload: \$var"
    echo
fi

echo
echo

### DB settings
echo "MySQL is the recommended database type but it requires you to have a MySQL server available."
echo "SQLite is more light weight and it will work fine for small installations up to 10 servers."
echo "For multiple daemons on a single panel MySQL is required."
echo
ask "MC_DB_TYPE" "sqlite" "What kind of database do you want to use? [\$def]/mysql" "Database type: \$var"

if [ "$MC_DB_TYPE" = "mysql" ]; then
    echo
    echo "NOTE: This is for the daemon config, the front end has an installation routine for database configuration and initialization."
    ask "MC_DB_HOST" "127.0.0.1" "Database host: [\$def]" "Database host: \$var"
    ask "MC_DB_NAME" "multicraft_daemon" "Database name: [\$def]" "Database name: \$var"
    ask "MC_DB_USER" "root" "Database user: [\$def]" "Database user: \$var"
    ask "MC_DB_PASS" "" "Database password: [\$def]" "Database password: \$var"
    echo
elif [ "$MC_DB_TYPE" = "sqlite" ]; then
    echo
    echo "The database will be located at: '$MC_DIR/data/data.db'"
else
    echo "Unsupported database type '$MC_DB_TYPE'!"
    echo "Aborting."
    quit
fi
echo "***"
echo "*** Please use the web panel to initialize the database."
echo "***"

echo

### Check user/group create/delete utilities

MC_JAVA="`which java`"
MC_ZIP="`which zip`"
MC_UNZIP="`which unzip`"
if [ "$MC_JAVA" = "" ]; then
    ask "MC_JAVA" "/usr/bin/java" "Path to java program: [\$def]" "Path to java: \$var"
fi
if [ "$MC_ZIP" = "" ]; then
    ask "MC_ZIP" "/usr/bin/zip" "Path to zip program: [\$def]" "Path to zip: \$var"
fi
if [ "$MC_UNZIP" = "" ]; then
    ask "MC_UNZIP" "/usr/bin/unzip" "Path to unzip program: [\$def]" "Path to unzip: \$var"
fi
if [ "$MC_MULTIUSER" = "y" -o "$MC_CREATE_USER" = "y" ]; then
    MC_USERADD="`which useradd`"
    MC_GROUPADD="`which groupadd`"
    MC_USERDEL="`which userdel`"
    MC_GROUPDEL="`which groupdel`"
    if [ "$MC_USERADD" = "" ]; then
        ask "MC_USERADD" "/usr/sbin/useradd" "Path to useradd program: [\$def]" "Path to useradd program: \$var"
    fi
    if [ "$MC_GROUPADD" = "" ]; then
        ask "MC_GROUPADD" "/usr/sbin/groupadd" "Path to groupadd program: [\$def]" "Path to groupadd program: \$var"
    fi
    if [ "$MC_USERDEL" = "" ]; then
        ask "MC_USERDEL" "/usr/sbin/userdel" "Path to userdel program: [\$def]" "Path to userdel program: \$var"
    fi
    if [ "$MC_GROUPDEL" = "" ]; then
        ask "MC_GROUPDEL" "/usr/sbin/groupdel" "Path to groupdel program: [\$def]" "Path to groupdel program: \$var"
    fi
fi

### Installation

echo
echo "NOTE: Any running daemon will be stopped!"
ask "START_INSTALL" "y" "Ready to install Multicraft. Start installation? [\$def]/n" "-"
if [ "$START_INSTALL" != "y" ]; then
    echo "Not installing."
    quit
fi

echo
echo "################################################################################"
echo "*** INSTALLING"
echo "################################################################################"
echo

if [ -e "$MC_DIR/bin/multicraft" ]; then
    echo "Stopping daemon if running:"
    "$MC_DIR/bin/multicraft" stop
    "$MC_DIR/bin/multicraft" stop_ftp
    sleep 1
fi

### Multicraft user & directory setup

if [ "$MC_USER_EXISTS" = "n" ]; then
    echo
    echo -n "Creating user '$MC_USER'... "
    "$MC_GROUPADD" "$MC_USER"
    if [ ! "$?" = "0" ]; then
        echo "Error: Can't create group '$MC_USER'! Please create this group manually and re-run the setup script."
    fi

    "$MC_USERADD" "$MC_USER" -g "$MC_USER" -s /bin/false
    if [ ! "$?" = "0" ]; then
        echo "Error: Can't create user '$MC_USER'! Please create this user manually and re-run the setup script."
    fi
    echo "done"
fi

echo
echo -n "Creating directory '$MC_DIR'... "
mkdir -p "$MC_DIR"
echo "done"

echo
echo -n "Ensuring the home directory exists and is owned and writable by the user... "
MC_HOME="`grep "^$MC_USER:" /etc/passwd | awk -F":" '{print $6}'`"
mkdir -p "$MC_HOME"
chown "$MC_USER":"$MC_USER" "$MC_HOME"
chmod u+rwx "$MC_HOME"
chmod go+x "$MC_HOME"
echo "done"

echo
if [ -e "$MC_DIR/bin" -a "$( cd "bin/" && pwd )" != "$( cd "$MC_DIR/bin" 2>/dev/null && pwd )" ]; then
    echo -n "Backing up existing 'bin' directory... "
    mv "$MC_DIR/bin" "$MC_DIR/bin.bak"
    echo "done"
fi
for i in $INSTALL; do
    echo -n "Installing '$i' to '$MC_DIR/'... "
    cp -a "$i" "$MC_DIR/"
    echo "done"
done
echo -n "Cleaning up files... "
rm -f "$MC_DIR/bin/_weakref.so"
rm -f "$MC_DIR/bin/collections.so"
rm -f "$MC_DIR/bin/libpython2.5.so.1.0"
rm -f "$MC_DIR/bin/"*-py2.5*.egg
echo "done"

if [ "$MC_KEY" != "no" ]; then
    echo
    echo -n "Installing license key... "
    echo "$MC_KEY" > "$MC_DIR/multicraft.key"
    echo "done"
fi


### Generate config

echo
CFG="$MC_DIR/multicraft.conf"
if [ -e "$CFG" ]; then
    ask "OVERWRITE_CONF" "n" "The 'multicraft.conf' file already exists, overwrite? y/[\$def]" "-"
fi

if [ "$MC_DB_TYPE" = "mysql" ]; then
    DB_STR="mysql:host=$MC_DB_HOST;dbname=$MC_DB_NAME"
fi

function repl {
    LINE="$SETTING = `echo $1 | sed "s/['\\&,]/\\\\&/g"`"
}
if [ ! -e "$CFG" -o "$OVERWRITE_CONF" = "y" ]; then

    if [ -e "$CFG" ]; then
        echo -n "Multicraft.conf exists, backing up... "
        cp -a "$CFG" "$CFG.bak"
        echo "done"
    fi

    echo -n "Generating 'multicraft.conf'... "
    > "$CFG"

    SECTION=""
    cat "$CFG.dist" | while IFS="" read -r LINE
    do
        if [ "`echo $LINE | grep "^ *\[\w\+\] *$"`" ]; then
            SECTION="$LINE"
            SETTING=""
        else
            SETTING="`echo $LINE | sed -n 's/^ *\#\? *\([^ ]\+\) *=.*/\1/p'`"
        fi
        case "$SECTION" in
        "[multicraft]")
            case "$SETTING" in
            "user")         repl "$MC_USER" ;;
            "ip")           if [ "$MC_LOCAL" != "y" ]; then repl "$MC_DAEMON_IP";       fi ;;
            "port")         if [ "$MC_LOCAL" != "y" ]; then repl "$MC_DAEMON_PORT";     fi ;;
            "password")     repl "$MC_DAEMON_PW" ;;
            "id")           repl "$MC_DAEMON_ID" ;;
            "database")     if [ "$MC_DB_TYPE" = "mysql" ]; then repl "$DB_STR";        fi ;;
            "dbUser")       if [ "$MC_DB_TYPE" = "mysql" ]; then repl "$MC_DB_USER";    fi ;;
            "dbPassword")   if [ "$MC_DB_TYPE" = "mysql" ]; then repl "$MC_DB_PASS";    fi ;;
            "webUser")      if [ "$MC_DB_TYPE" = "mysql" ]; then repl "";               else repl "$MC_WEB_USER"; fi ;;
            "baseDir")      repl "$MC_DIR" ;;
            esac
        ;;
        "[ftp]")
            case "$SETTING" in
            "enabled")          if [ "$MC_FTP_SERVER" = "y" ]; then repl "true";    else repl "false"; fi ;;
            "ftpIp")            if [ ! "$MC_FTP_IP" = "" ]; then repl "$MC_FTP_IP"; fi ;;
            "ftpExternalIp")    if [ ! "$MC_FTP_EXTERNAL_IP" = "" ]; then repl "$MC_FTP_EXTERNAL_IP"; fi ;;
            "ftpPort")          repl "$MC_FTP_PORT" ;;
            "forbiddenFiles")   if [ "$MC_PLUGINS" = "n" ]; then repl "";           fi ;;
            esac
        ;;
        "[minecraft]")
            case "$SETTING" in
            "java") repl "$MC_JAVA" ;;
            esac
        ;;
        "[system]")
            case "$SETTING" in
            "unpackCmd")    repl "$MC_UNZIP"' -quo "{FILE}"' ;;
            "packCmd")      repl "$MC_ZIP"' -qr "{FILE}" .' ;;
            esac
            if [ "$MC_MULTIUSER" = "y" ]; then
                case "$SETTING" in
                "multiuser")    repl "true" ;;
                "addUser")      repl "$MC_USERADD"' -c "Multicraft Server {ID}" -d "{DIR}" -g "{GROUP}" -s /bin/false "{USER}"' ;;
                "addGroup")     repl "$MC_GROUPADD"' "{GROUP}"' ;;
                "delUser")      repl "$MC_USERDEL"' "{USER}"' ;;
                "delGroup")     repl "$MC_GROUPDEL"' "{GROUP}"' ;;
                esac
            fi
        ;;
        "[backup]")
            case "$SETTING" in
            "command")  repl "$MC_ZIP"' -qr "{WORLD}-tmp.zip" . -i "{WORLD}"*/*' ;;
            esac
        ;;
        esac
        echo "$LINE" >> "$CFG"
    done
    echo "done"
fi

echo
echo -n "Setting owner of '$MC_DIR' to '$MC_USER'... "
chown "$MC_USER":"$MC_USER" "$MC_DIR"
echo "done"
echo -n "Setting special daemon permissions... "
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/bin"
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/launcher"
chmod 555 "$MC_DIR/launcher/launcher"
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/jar"
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/scripts"
chmod 555 "$MC_DIR/scripts/getquota.sh"
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/ssl"
chown -R "$MC_USER":"$MC_USER" "$MC_DIR/templates"
chown "$MC_USER":"$MC_USER" "$MC_DIR/default_server.conf.dist"
chown "$MC_USER":"$MC_USER" "$MC_DIR/server_configs.conf.dist"

if [ "$MC_MULTIUSER" = "y" ]; then
    chown 0:"$MC_USER" "$MC_DIR/bin/useragent"
    chmod 4550 "$MC_DIR/bin/useragent"
fi
chmod 755 "$MC_DIR/jar/"*.jar 2> /dev/null
echo "done"
echo

### Install PHP frontend

if [ "$MC_LOCAL" = "y" ]; then
    echo

    if [ -e "$MC_WEB_DIR" -a -e "$MC_WEB_DIR/protected/data/data.db" ]; then
        echo -n "Web directory exists, backing up 'protected/data/data.db'... "
        cp -a "$MC_WEB_DIR/protected/data/data.db" "$MC_WEB_DIR/protected/data/data.db.bak"
        echo "done"
    fi

    echo -n "Creating directory '$MC_WEB_DIR'... "
    mkdir -p "$MC_WEB_DIR"
    echo "done"

    echo -n "Installing web panel files from 'panel/' to '$MC_WEB_DIR'... "
    cp -a panel/* "$MC_WEB_DIR"
    cp -a panel/.ht* "$MC_WEB_DIR"
    echo "done"

    echo -n "Setting owner of '$MC_WEB_DIR' to '$MC_WEB_USER'... "
    chown -R "$MC_WEB_USER":"$MC_WEB_USER" "$MC_WEB_DIR"
    echo "done"
    echo -n "Setting permissions of '$MC_WEB_DIR'... "
    chmod -R o-rwx "$MC_WEB_DIR"
    echo "done"

    echo
    # SELinux related settings
    CHCON="`which chcon 2>/dev/null`"
    RESTORECON="`which restorecon 2>/dev/null`"
    SETSEBOOL="`which setsebool 2>/dev/null`"
    if [ ! "$CHCON" = "" -a ! "$RESTORECON" = "" -a ! "$SETSEBOOL" = "" ]; then
        echo -n "Applying SELinux contexts... "
        {
        $RESTORECON -R "$MC_WEB_DIR"
        $CHCON -R --type=httpd_sys_rw_content_t "$MC_WEB_DIR/assets"
        $CHCON -R --type=httpd_sys_rw_content_t "$MC_WEB_DIR/protected/config"
        $CHCON -R --type=httpd_sys_rw_content_t "$MC_WEB_DIR/protected/data"
        $CHCON -R --type=httpd_sys_rw_content_t "$MC_WEB_DIR/protected/runtime"
        if [ "$MC_DB_TYPE" = "sqlite" ]; then
            $CHCON -R --reference="$MC_WEB_DIR/assets" "$MC_DIR/data/data.db"
        fi
        $SETSEBOOL -P httpd_can_network_connect 1
        } 2>/dev/null
        echo "done"
    fi

else
    ### PHP frontend not on local machine
    echo
    echo "* NOTE: The web panel will not be installed on this machine. Please put the contents of the directory 'panel/' in a web accessible directory of the machine you want to run the web panel on and run the installer (install.php)."
fi
echo

echo "Temporarily starting daemon to set DB permissions:"
"$MC_DIR/bin/multicraft" set_permissions

echo
echo
echo "################################################################################"
echo "*** Installation complete!"
echo "################################################################################"
echo
echo "PLEASE READ:"
echo
echo "1) Before starting the daemon you need to run the web panel installer to initialize your database. (example: http://your.address/multicraft/install.php)"
echo
echo "2) After running the web panel installer you can start the daemon using the following command:"
echo "   $MC_DIR/bin/multicraft start"
echo
echo
echo "For troubleshooting please see:"
echo "- Daemon log file:    $MC_DIR/multicraft.log"
echo "- Panel log file:     $MC_WEB_DIR/protected/runtime/application.log"
echo "- Multicraft Website: http://www.multicraft.org/site/docs/troubleshooting"
echo
echo
read -p "Press [Enter] to continue."
echo
echo
echo "In case you want to rerun this script you can save the entered settings."
quit



