1
0
Fork 0
mirror of https://github.com/Luzifer/terraria-docker.git synced 2024-12-22 13:31:16 +00:00

Change start method, add "player left" hook

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2018-07-06 18:21:50 +02:00
parent a2110af59a
commit 11337506b6
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E

64
main.go
View file

@ -5,9 +5,10 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"os/exec"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
"time"
"github.com/Luzifer/rconfig" "github.com/Luzifer/rconfig"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -20,8 +21,6 @@ var (
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"` VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
}{} }{}
done = make(chan struct{}, 1)
version = "dev" version = "dev"
) )
@ -48,38 +47,59 @@ func main() {
} }
defer os.Remove(cfg.FiFoFile) defer os.Remove(cfg.FiFoFile)
cmd := exec.Command(rconfig.Args()[1], rconfig.Args()[1:]...)
stdin, err := cmd.StdinPipe()
if err != nil {
log.WithError(err).Fatal("Unable to create stdin pipe")
}
// StdIN processing to send commands to Terraria
sigs := make(chan os.Signal, 1) sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go handleSignal(sigs) go handleSignal(sigs, stdin)
go inputLoop() go inputLoop(stdin)
for { // StdOUT processing to react on log output
select { stdoutRead, stdoutWrite := io.Pipe()
case <-done: cmd.Stdout = stdoutWrite
log.Info("Waiting 5s until quit") cmd.Stderr = stdoutWrite
<-time.After(5 * time.Second) // Allow some time for terraria to quit gracefully
return go outputLoop(stdoutRead, stdin)
cmd.Run()
}
func outputLoop(in io.Reader, out io.Writer) {
scanner := bufio.NewScanner(in)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
log.Info(line)
if strings.Contains(line, "has left.") {
// A player left the server and after the last player
// left the server will not save anymore so we'll do
// that whenever a player leaves...
fmt.Fprintln(out, "save")
} }
} }
} }
func inputLoop() { func inputLoop(comm io.Writer) {
for { for {
f, err := os.Open(cfg.FiFoFile) f, err := os.Open(cfg.FiFoFile)
if err != nil { if err != nil {
log.WithError(err).Error("Unable to (re)open fifo, quitting now") log.WithError(err).Error("Unable to (re)open fifo, quitting now")
done <- struct{}{} fmt.Fprintln(comm, "exit")
continue break
} }
defer f.Close() defer f.Close()
scanner := bufio.NewScanner(f) scanner := bufio.NewScanner(f)
for scanner.Scan() { for scanner.Scan() {
fmt.Println(scanner.Text()) fmt.Fprintln(comm, scanner.Text())
if scanner.Text() == "exit" {
done <- struct{}{}
}
} }
switch scanner.Err() { switch scanner.Err() {
@ -89,15 +109,13 @@ func inputLoop() {
// This is fine // This is fine
default: default:
log.WithError(err).Error("Unable to read from fifo") log.WithError(err).Error("Unable to read from fifo")
fmt.Println("exit") fmt.Fprintln(comm, "exit")
done <- struct{}{}
} }
} }
} }
func handleSignal(sigs chan os.Signal) { func handleSignal(sigs chan os.Signal, comm io.Writer) {
sig := <-sigs sig := <-sigs
log.WithField("signal", sig).Info("Received terminating singal") log.WithField("signal", sig).Info("Received terminating singal")
fmt.Println("exit") fmt.Fprintln(comm, "exit")
done <- struct{}{}
} }