Skip to content

Instantly share code, notes, and snippets.

@maxpowa
Last active September 16, 2017 15:08
Show Gist options
  • Save maxpowa/76f6ce3b2d42603dc118 to your computer and use it in GitHub Desktop.
Save maxpowa/76f6ce3b2d42603dc118 to your computer and use it in GitHub Desktop.
Factorio initialization script
#!/bin/bash
# Modified version of https://github.com/Bisa/factorio-init
# Check/load defaults for backwards compatible config options
if [ -z "${PACKAGE_DIR_NAME}" ]; then
PACKAGE_DIR_NAME=factorio
fi
if [ -z "${USERNAME}" ]; then
USERNAME=`whoami`
fi
if [ -z "${USERGROUP}" ]; then
USERGROUP=`whoami`
fi
FACTORIO_PATH=/factorio
BINARY=/factorio/bin/x64/factorio
PIDFILE=/factorio/factorio.pid
SCREEN_NAME=factorio-screen
INVOCATION="${BINARY} --start-server ${SAVE_NAME} --autosave-interval ${AUTOSAVE_INTERVAL} --autosave-slots ${AUTOSAVE_SLOTS} --latency-ms ${LATENCY} ${EXTRA_BINARGS}"
debug(){
if [ ${DEBUG} -gt 0 ]; then
echo "DEBUG LOG: $@" >&2
fi
}
usage(){
echo "Usage: $0 COMMAND"
echo
echo "Available commands:"
echo -e " start \t\t Starts the server"
echo -e " stop \t\t Stops the server"
echo -e " restart \t\t Restarts the server"
echo -e " status \t\t Displays server status"
echo -e " load-save name \t Stops the server and loads the specified save"
echo -e " refresh-save \t\t Stops the server and loads the last modified save"
echo -e " screen \t\t Shows the server screen"
echo -e " install tarball \t Installs the server with specified tarball"
}
ME=`whoami`
as_user() {
if [ $ME == $USERNAME ]; then
bash -c "$1"
else
su $USERNAME -s /bin/bash -c "$1"
fi
}
refresh_save(){
savedir="${FACTORIO_PATH}/saves"
# Check to see if save dir actually exists
if ! [ -e ${savedir} ]; then
echo "Error! Save directory missing: ${savedir}"
exit 1
fi
# Find the last modified save file
lastsave=$(as_user "ls -t ${savedir}/*.zip" 2> /dev/null | head -1)
# Sanity check, did we even find any save files?
if [ -z "${lastsave}" ]; then
echo "Error! Unable to find any saves in ${savedir}"
exit 1
fi
debug "last modified save: ${lastsave}"
# If the last modified save is our own, keep using it
if [ "${lastsave}" == "${savedir}/${SAVE_NAME}.zip" ]; then
debug "using existing ${SAVE_NAME}.zip"
return 0
fi
# Else we copy the latest save to our own save file
debug "using refreshed save"
if ! as_user "cp ${lastsave} ${savedir}/${SAVE_NAME}.zip"; then
echo "Error! Failed to refresh saves"
exit 1
fi
}
find_pid(){
pid=$(ps ax | grep -v grep | grep "${BINARY} --start-server ${SAVE_NAME}" | grep -v "${SCREEN_NAME}" | awk '{ print $1}')
if [ "$pid" == "" ]; then
echo "-1"
debug "could not find a pid for binary: \"${BINARY}\""
elif [ `echo ${pid} | wc -l` -gt 1 ]; then
echo "-2"
debug "found multiple pids"
else
echo ${pid}
debug "found pid: $pid"
fi
}
is_running() {
pid=$(find_pid)
if [ ${pid} -gt 0 ]; then
return 0
elif [ ${pid} == -2 ]; then
echo "Found multiple pids, aborting!"
exit 1
else
return 1
fi
}
start_service() {
if [ ! -f "$BINARY" ]; then
echo "Failed to start: Can't find the specified binary $BINARY. Please check your config!"
exit 1
fi
check_permissions
refresh_save
as_user "cd $FACTORIO_PATH && screen -dmS $SCREEN_NAME $INVOCATION"
if [ $? -eq 0 ]; then
#
# Waiting for the server to start
#
seconds=0
until is_running; do
sleep 1
seconds=$seconds+1
if [[ $seconds -eq 2 ]]; then
echo "Still not running, waiting a while longer..."
fi
if [[ $seconds -ge 10 ]]; then
echo "Failed to start, aborting."
exit 1
fi
done
echo "Factorio is running."
else
echo "Failed to start, ensure SCREEN is installed"
fi
}
stop_service() {
#
# Stops the server
#
pid=$(find_pid)
as_user "kill -s 2 ${pid}"
sleep 0.5
#
# Waiting for the server to shut down
#
seconds=0
while is_running; do
sleep 1
seconds=$seconds+1
if [[ $seconds -eq 2 ]]; then
echo "Still not shut down, waiting a while longer..."
fi
if [[ $seconds -ge 10 ]];
then
echo "Failed to shut down, aborting!"
exit 1
fi
done
echo "Factorio is now shut down."
}
check_permissions() {
as_user "touch $PIDFILE"
if ! as_user "test -w '$PIDFILE'" ; then
echo "Check Permissions. Cannot write to $PIDFILE. Correct the permissions and then excute: $0 status"
return 1
fi
return 0
}
test_deps(){
return 0 # TODO: Implement ldd check on $BINARY
}
install(){
tarball=$1
if ! [ -f "${tarball}" ]; then
echo "Install package does not exist! ${tarball}"
exit 1
fi
target="`dirname ${FACTORIO_PATH}`"
if ! test -w "${target}"; then
echo "Failed to write, aborting install!"
echo "Install needs to be run as a user with write permissions to ${target}"
exit 1
fi
echo "Installing ${tarball} ..."
if ! tar -xzvf "${tarball}" --directory "${target}"; then
echo "Install failed!"
exit 1
fi
echo "Applying file ownership ..."
if ! chown -R ${USERNAME}:${USERGROUP} ${FACTORIO_PATH}; then
echo "Failed to apply ownership ${USERNAME}:${USERGROUP} for ${FACTORIO_PATH}"
exit 1
fi
if test_deps; then
if ! as_user "$BINARY --create ${SAVE_NAME}"; then
echo "Installation complete..."
echo
echo "but failed to create initial save game."
echo "Ensure you use: load-save [save-name] before starting the server for the first time."
else
echo "Install successfull!"
fi
else
echo "Installation complete..."
echo
echo "but $BINARY is missing required dependencies."
echo "Install the missing deps and ensure you use: load-save [save-name] before starting the server for the first time."
fi
}
case "$1" in
start)
# Starts the server
if is_running; then
echo "Server already running."
else
start_service
fi
;;
stop)
# Stops the server
if is_running; then
stop_service
else
echo "No running server."
fi
;;
restart)
# Restarts the server
if is_running; then
stop_service
else
echo "No running server, starting it..."
fi
start_service
;;
status)
# Shows server status
if is_running; then
echo "Factorio is running."
else
echo "Factorio is not running."
exit 1
fi
;;
load-save)
# Ensure we get a new save file name
newsave=${FACTORIO_PATH}/saves/$2.zip
if [ ! -f "${newsave}" ]; then
echo "Save \"${newsave}\" does not exist, aborting action!"
exit 1
fi
# Since stopping the server causes a save we have to stop the server to do this
if is_running; then
stop_service
fi
# Touch the new save file
as_user "touch ${newsave}"
;;
refresh-save)
if is_running; then
stop_service
fi
refresh_save
;;
screen)
if is_running; then
as_user "script /dev/null -q -c \"screen -rx $SCREEN_NAME\""
else
echo -n "Server is not running. Do you want to start it? [n]: "
read START_SERVER
case "$START_SERVER" in
[Yy])
start_service
as_user "script /dev/null -q -c \"screen -rx $SCREEN_NAME\""
;;
*)
clear
echo "Aborting startup!"
exit 1
;;
esac
fi
;;
install)
install "$2"
;;
help|--help|-h)
usage
;;
*)
echo "No such command!"
echo
usage
exit 1
;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment