residentsleeper/parser.go

114 lines
3.5 KiB
Go

package main
import (
"github.com/acarl005/stripansi"
"github.com/hpcloud/tail"
log "github.com/sirupsen/logrus"
"meow.tf/residentsleeper/events"
"meow.tf/residentsleeper/rcon"
"os"
"regexp"
"strings"
)
const (
timeThreadRegexp = "^\\[.*?\\]\\s\\[.*?\\/INFO\\]:\\s"
)
var (
messageRegexp = regexp.MustCompile(timeThreadRegexp + "<(.*?)>\\s(.*)")
joinedRegexp = regexp.MustCompile(timeThreadRegexp + "(.*?) joined the game$")
leftRegexp = regexp.MustCompile(timeThreadRegexp + "(.*?) left the game$")
stoppingRegexp = regexp.MustCompile(timeThreadRegexp + "Stopping server")
rconRegexp = regexp.MustCompile(timeThreadRegexp + "RCON running on")
loggedInRegexp = regexp.MustCompile(timeThreadRegexp + "(.*?)\\[(.*?)\\] logged in with entity id \\d+ at \\((.*?)\\)")
startedRegexp = regexp.MustCompile(timeThreadRegexp + "Done \\(.*?\\)! For help, type \"help\"")
authenticatedRegexp = regexp.MustCompile(timeThreadRegexp + "UUID of player (.*?) is (.*?)$")
opRegexp = regexp.MustCompile("Made (.*?) a server operator")
deopRegexp = regexp.MustCompile("Made (.*?) no longer a server operator")
sourceRegexp = regexp.MustCompile(timeThreadRegexp + "\\[(.*?): (.*?)\\]")
sleepRegexp = regexp.MustCompile("^z{3,}$")
timeRegexp = regexp.MustCompile("(\\d+)$")
)
func logParser(logPath string) {
log.WithField("path", logPath).Info("Watching log path")
stat, err := os.Stat(logPath)
if err != nil {
log.WithError(err).Fatalln("Unable to stat log file")
}
seek := &tail.SeekInfo{
Offset: stat.Size(),
}
// Start parsing file
t, err := tail.TailFile(logPath, tail.Config{Location: seek, Follow: true, ReOpen: true})
if err != nil {
log.WithError(err).Fatalln("Unable to open log file")
}
var m []string
for line := range t.Lines {
line.Text = stripansi.Strip(strings.TrimSpace(line.Text))
if debug {
log.Println("Parsing line", line.Text)
log.Println("Bytes:", []byte(line.Text))
}
if m = messageRegexp.FindStringSubmatch(line.Text); m != nil {
go events.Call(events.Message, m[1], m[2])
} else if m = loggedInRegexp.FindStringSubmatch(line.Text); m != nil {
position, err := rcon.SliceToFloats(strings.Split(m[3], ", "))
if err != nil {
position = []float64{0, 0, 0}
}
go events.Call(events.LoggedIn, m[1], m[2], position[0], position[1], position[2])
} else if m = authenticatedRegexp.FindStringSubmatch(line.Text); m != nil {
go events.Call(events.Authenticated, m[1], m[2])
} else if m = joinedRegexp.FindStringSubmatch(line.Text); m != nil {
go events.Call(events.Join, m[1])
} else if m = leftRegexp.FindStringSubmatch(line.Text); m != nil {
go events.Call(events.Leave, m[1])
} else if m = opRegexp.FindStringSubmatch(line.Text); m != nil {
source := "Server"
subM := sourceRegexp.FindStringSubmatch(line.Text)
if subM != nil {
source = subM[1]
}
go events.Call(events.Op, m[1], source)
} else if m = deopRegexp.FindStringSubmatch(line.Text); m != nil {
source := "Server"
subM := sourceRegexp.FindStringSubmatch(line.Text)
if subM != nil {
source = subM[1]
}
go events.Call(events.Deop, m[1], source)
} else if stoppingRegexp.MatchString(line.Text) {
go func() {
events.Call(events.ServerClosing)
client.Disconnect()
}()
} else if startedRegexp.MatchString(line.Text) {
go events.Call(events.ServerStarted)
} else if rconRegexp.MatchString(line.Text) {
go events.Call(events.Init)
}
}
}