Skip to content

Commit bd7c3c1

Browse files
authored
Merge pull request #67 from Bisa/develop
Develop
2 parents 646d127 + a94d23c commit bd7c3c1

File tree

4 files changed

+165
-102
lines changed

4 files changed

+165
-102
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
config
22
factorio.service
3+
factorio-env.service
4+
systemd.env

README.md

+31-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ A simple factorio init script for linux
33

44
# Debugging
55
If you find yourself wondering why stuff is not working the way you expect:
6-
- Enable debugging in the config
7-
and/or
6+
- Check the logs, I suggest you `tail -f /opt/factorio/factorio-current.log` in a separate session
7+
- Enable debugging in the config and/or:
88
- Try running the same commands as the factorio user
99

1010
```bash
@@ -23,6 +23,24 @@ A simple factorio init script for linux
2323
```
2424
- Rename config.example to config and modify the values within according to your setup.
2525

26+
## Systemd
27+
- Copy the example service, adjust & reload
28+
29+
```bash
30+
$ cp /opt/factorio-init/factorio.service.example /etc/systemd/system/factorio.service
31+
# Edit the service file to suit your environment then reload systemd
32+
$ systemctl daemon-reload
33+
```
34+
35+
- Verify that the server starts
36+
37+
```bash
38+
$ systemctl start factorio
39+
$ systemctl status -l factorio
40+
# Remember to enable the service at startup if you want that:
41+
$ systemctl enable factorio
42+
```
43+
2644
## SysvInit
2745
- Symlink the init script:
2846

@@ -40,5 +58,14 @@ A simple factorio init script for linux
4058
$ service factorio help
4159
```
4260

43-
# License
44-
This code is realeased with the MIT license, see the LICENSE file.
61+
# Thank You
62+
- To all who find this script useful in one way or the other
63+
- A big thank you to [Wube](https://www.factorio.com/team) for making [Factorio](https://www.factorio.com/)
64+
- A special thanks to NoPantsMcDance, Oxyd, HanziQ, TheFactorioCube and all other frequent users of the [#factorio](irc://irc.esper.net/#factorio) channel @ esper.net
65+
- Thank you to Salzig for pointing me in the right direction when it comes to input redirection
66+
- At last, but not least; Thank you to all [contributors](https://github.com/Bisa/factorio-init/graphs/contributors) and users posting [issues](https://github.com/Bisa/factorio-init/issues) in my [github](https://github.com/Bisa/factorio-init/) project or on the [factorio forums](https://forums.factorio.com/viewtopic.php?f=133&t=13874)
67+
68+
You are all a great source of motivation, thank you.
69+
70+
# License
71+
This code is realeased with the MIT license, see the LICENSE file.

factorio

+110-98
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ if ! [ $1 == "install" ]; then
6767
WRITE_DIR=$(dirname "$(echo `grep "^write-data=" "$FCONF"` |cut -d'=' -f2 |sed -e 's#__PATH__executable__#'$(dirname "$BINARY")/..'#g')")
6868
fi
6969
debug "write path: $WRITE_DIR"
70+
71+
PIDFILE="${WRITE_DIR}/server.pid"
72+
73+
if [ -z "${FIFO}" ];then
74+
FIFO="${WRITE_DIR}/server.fifo"
75+
fi
76+
7077
fi
7178

7279
usage(){
@@ -77,10 +84,10 @@ usage(){
7784
echo -e " stop \t\t Stops the server"
7885
echo -e " restart \t\t Restarts the server"
7986
echo -e " status \t\t Displays server status"
87+
echo -e " cmd command/message \t Send command/chat"
8088
echo -e " new-game \t\t Stops the server and creates a new game"
8189
echo -e " save-game name \t Stops the server and saves game to specified save"
8290
echo -e " load-save name \t Stops the server and loads the specified save"
83-
echo -e " screen \t\t Shows the server screen"
8491
echo -e " install tarball \t Installs the server with specified tarball"
8592
echo -e " update [--dry-run] \t Updates the server"
8693
}
@@ -94,101 +101,120 @@ as_user() {
94101
fi
95102
}
96103

97-
find_pid(){
98-
pid=$(ps ax | grep -v grep | grep "$(echo -e "${INVOCATION}" | sed -e 's/[[:space:]]*$//')" | grep -v " SCREEN " | awk '{ print $1}')
99-
debug "assessing pid: $pid"
100-
101-
if [ "$pid" == "" ]; then
102-
echo "-1"
103-
debug "could not find a pid for binary: \"${BINARY}\""
104-
elif [ `echo "${pid}" | wc -l` -gt 1 ]; then
105-
echo "-2"
106-
debug "found multiple pids"
107-
else
108-
echo ${pid}
109-
fi
110-
}
111-
112104
is_running() {
113-
pid=$(find_pid)
114-
if [ ${pid} -gt 0 ]; then
115-
return 0
116-
elif [ ${pid} == -2 ]; then
117-
echo "Found multiple pids, aborting! (ensure only one instance of $SERVICE_NAME is running)"
118-
exit 1
119-
else
120-
return 1
105+
if [ -e ${PIDFILE} ]; then
106+
if kill -0 $(cat ${PIDFILE}) 2> /dev/null; then
107+
debug "${SERVICE_NAME} is running with pid $(cat ${PIDFILE})"
108+
return 0
109+
else
110+
debug "Found ${PIDFILE}, but the server is not running. It's possible that your server has crashed"
111+
debug "Check the log for details"
112+
rm ${PIDFILE} 2> /dev/null
113+
return 2
114+
fi
121115
fi
116+
return 1
122117
}
123118

124119
start_service() {
125-
if [ ! -f "$BINARY" ]; then
126-
echo "Failed to start: Can't find the specified binary $BINARY. Please check your config!"
127-
return 1
120+
if [ -e ${PIDFILE} ]; then
121+
ps -p $(cat ${PIDFILE}) > /dev/null 2>&1
122+
if [ "$?" -eq "0" ]; then
123+
echo "${SERVICE_NAME} is already running!"
124+
return 1
125+
fi
126+
debug "Found rogue pid file, server might have crashed"
127+
rm ${PIDFILE} 2> /dev/null
128128
fi
129129

130130
if ! check_permissions; then
131-
echo "Error! Incorrect permissions, unable to write to dir \"$WRITE_DIR\""
131+
echo "Error! Incorrect permissions, unable to write to ${WRITE_DIR}"
132132
return 1
133133
fi
134134

135-
as_user "screen -dmS $SERVICE_NAME $INVOCATION"
136-
if [ $? -eq 0 ]; then
137-
#
138-
# Waiting for the server to start
139-
#
140-
seconds=0
141-
until is_running; do
142-
sleep 1
143-
seconds=$seconds+1
144-
if [[ $seconds -eq 2 ]]; then
145-
echo "Still not running, waiting a while longer..."
146-
fi
147-
if [[ $seconds -ge 10 ]]; then
148-
echo "$SERVICE_NAME failed to start within 10 seconds, giving up"
149-
return 1
150-
fi
151-
done
152-
echo "$SERVICE_NAME is running."
153-
else
154-
echo "Failed to start, ensure SCREEN is installed"
135+
as_user "tail -f ${FIFO} |${INVOCATION} > /dev/null 2>&1 & echo \$! > ${PIDFILE}"
136+
137+
ps -p $(cat ${PIDFILE}) > /dev/null 2>&1
138+
if [ "$?" -ne "0" ]; then
139+
echo "Unable to start ${SERVICE_NAME}"
155140
return 1
141+
else
142+
echo "Started ${SERVICE_NAME}, please see log for details"
156143
fi
157144
}
158145

159146
stop_service() {
147+
if [ -e ${PIDFILE} ]; then
148+
echo -n "Stopping ${SERVICE_NAME}: "
149+
if kill -TERM $(cat ${PIDFILE}) 2> /dev/null; then
150+
sec=1
151+
while [ "$sec" -le 15 ]; do
152+
if [ -e ${PIDFILE} ]; then
153+
if kill -0 $(cat ${PIDFILE}) 2> /dev/null; then
154+
echo -n ". "
155+
sleep 1
156+
else
157+
break
158+
fi
159+
else
160+
break
161+
fi
162+
sec=$(($sec+1))
163+
done
164+
fi
160165

161-
#
162-
# Stops the server
163-
#
164-
pid=$(find_pid)
165-
as_user "kill -s 2 ${pid}"
166-
sleep 0.5
167-
168-
#
169-
# Waiting for the server to shut down
170-
#
171-
seconds=0
172-
while is_running; do
173-
sleep 1
174-
seconds=$seconds+1
175-
if [[ $seconds -eq 2 ]]; then
176-
echo "Still not shut down, waiting a while longer..."
166+
if kill -0 $(cat ${PIDFILE}) 2> /dev/null; then
167+
echo "Unable to shut down nicely, killing the process!"
168+
kill -KILL $(cat ${PIDFILE}) 2> /dev/null
169+
else
170+
echo "complete!"
177171
fi
178-
if [[ $seconds -ge 10 ]];
179-
then
180-
echo "$SERVICE_NAME failed to stop within 10 seconds, giving up"
172+
173+
rm ${PIDFILE} 2> /dev/null
174+
return 0 # we've either shut down gracefully or killed the process
175+
else
176+
echo "${SERVICE_NAME} is not running (${PIDFILE} does not exist)"
177+
return 1
178+
fi
179+
}
180+
181+
send_cmd(){
182+
if is_running; then
183+
if [ -p ${FIFO} ]; then
184+
echo $@
185+
echo $@ > ${FIFO}
186+
sleep 1
187+
else
188+
echo "${FIFO} is not a pipe!"
181189
return 1
182190
fi
183-
done
184-
185-
echo "$SERVICE_NAME is now shut down."
191+
else
192+
echo "Unable to send cmd to a stopped server!"
193+
return 1
194+
fi
186195
}
187196

188-
check_permissions() {
189-
if ! as_user "test -w '$WRITE_DIR'" ; then
190-
debug "Check Permissions. Cannot write to $WRITE_DIR"
191-
return 1
197+
check_permissions(){
198+
if [ ! -e "${BINARY}" ]; then
199+
echo "Can't find ${BINARY}. Please check your config!"
200+
exit 1
201+
fi
202+
203+
if ! as_user "test -w ${WRITE_DIR}" ; then
204+
echo "Check Permissions. Cannot write to ${WRITE_DIR}"
205+
exit 1
206+
fi
207+
208+
if ! as_user "touch ${PIDFILE}" ; then
209+
echo "Check Permissions. Cannot touch pidfile ${PIDFILE}"
210+
exit 1
211+
fi
212+
213+
if ! [ -p ${FIFO} ]; then
214+
if ! as_user "mkfifo ${FIFO}"; then
215+
echo "Failed to create pipe for stdin, if applicable, remove ${FIFO} and try again"
216+
exit 1
217+
fi
192218
fi
193219
}
194220

@@ -258,6 +284,7 @@ install(){
258284
get_bin_version(){
259285
echo `as_user "$BINARY --version |egrep '^Version: [0-9\.]+' |egrep -o '[0-9\.]+' |head -n 1"`
260286
}
287+
261288
get_bin_arch(){
262289
echo `as_user "$BINARY --version |egrep '^Binary version: ' |egrep -o '[0-9]{2}'"`
263290
}
@@ -347,6 +374,7 @@ update(){
347374

348375
# Stop the server if it is running.
349376
if is_running; then
377+
send_cmd "Updating to new Factorio version, be right back"
350378
stop_service
351379
fi
352380

@@ -385,6 +413,7 @@ case "$1" in
385413
stop)
386414
# Stops the server
387415
if is_running; then
416+
send_cmd "Server is being shut down on request"
388417
if ! stop_service; then
389418
echo "Could not stop $SERVICE_NAME"
390419
exit 1
@@ -398,6 +427,7 @@ case "$1" in
398427
restart)
399428
# Restarts the server
400429
if is_running; then
430+
send_cmd "Server is being restarted on request, be right back!"
401431
if stop_service; then
402432
if ! start_service; then
403433
echo "Could not start $SERVICE_NAME after restart!"
@@ -425,10 +455,13 @@ case "$1" in
425455
exit 1
426456
fi
427457
;;
428-
458+
cmd)
459+
send_cmd "${@:2}"
460+
;;
429461
new-game)
430462
# Stop Service
431463
if is_running; then
464+
send_cmd "Generating new save, please stand by"
432465
if ! stop_service; then
433466
echo "Failed to stop server, unable to create new save"
434467
exit 1
@@ -448,6 +481,7 @@ case "$1" in
448481

449482
# Stop Service
450483
if is_running; then
484+
send_cmd "Stopping server to save game"
451485
if ! stop_service; then
452486
echo "Failed to stop server, unable to save as \"$2\""
453487
exit 1
@@ -470,6 +504,7 @@ case "$1" in
470504

471505
# Since stopping the server causes a save we have to stop the server to do this
472506
if is_running; then
507+
send_cmd "Stopping server to load a saved game"
473508
if ! stop_service; then
474509
echo "Aborting, unable to stop $SERVICE_NAME"
475510
exit 1
@@ -479,29 +514,6 @@ case "$1" in
479514
# Touch the new save file
480515
as_user "touch ${newsave}"
481516
;;
482-
483-
screen)
484-
if is_running; then
485-
as_user "script /dev/null -q -c \"screen -rx $SERVICE_NAME\""
486-
else
487-
echo -n "Server is not running. Do you want to start it? [n]: "
488-
read START_SERVER
489-
case "$START_SERVER" in
490-
[Yy])
491-
if ! start_service; then
492-
echo "Unable to start $SERVICE_NAME"
493-
exit 1
494-
fi
495-
as_user "script /dev/null -q -c \"screen -rx $SERVICE_NAME\""
496-
;;
497-
*)
498-
clear
499-
echo "Aborting startup!"
500-
exit 1
501-
;;
502-
esac
503-
fi
504-
;;
505517
install)
506518
install "$2"
507519
;;

factorio.service.example

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[Unit]
2+
Description=Factorio Server
3+
After=network.target
4+
5+
[Service]
6+
User=factorio
7+
Group=factorio
8+
9+
# We will store a pid file in your ${WRITE_DIR}/server.pid
10+
# Adjust if you change the write dir of your server
11+
PIDFile=/opt/factorio/server.pid
12+
13+
Type=forking
14+
TimeoutStartSec=20
15+
ExecStart=/opt/factorio-init/factorio start
16+
TimeoutStopSec=20
17+
ExecStop=/opt/factorio-init/factorio stop
18+
RestartSec=20
19+
Restart=on-failure
20+
21+
[Install]
22+
WantedBy=multi-user.target

0 commit comments

Comments
 (0)