diff options
Diffstat (limited to 'scheduled/scheduled.go')
| -rw-r--r-- | scheduled/scheduled.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/scheduled/scheduled.go b/scheduled/scheduled.go new file mode 100644 index 0000000..6eb83e4 --- /dev/null +++ b/scheduled/scheduled.go @@ -0,0 +1,86 @@ +package scheduled + +import ( + "database/sql" + "encoding/json" + "log" + "time" + + "github.com/go-co-op/gocron" + + "penguins.lan/adapters/arp" + "penguins.lan/adapters/netscan" + "penguins.lan/api/minecraft" + "penguins.lan/args" + "penguins.lan/database" +) + +const sweepTimeout = 1 * time.Second + +func StartScheduler(argv *args.Arguments, dbConn *sql.DB) { + scheduler := gocron.NewScheduler(time.Local) + + scheduler.Every(1).Seconds().Do(func() { + if err := refreshArp(dbConn, arp.SystemProvider{}); err != nil { + log.Println("arp refresh failed:", err) + } + }) + + if argv.LanSubnet != "" { + go sweep(argv.LanSubnet) + scheduler.Every(30).Seconds().Do(func() { sweep(argv.LanSubnet) }) + } + + if argv.RconAddress != "" { + go refreshMinecraft(dbConn, argv.RconAddress, argv.RconPassword) + scheduler.Every(10).Seconds().Do(func() { + refreshMinecraft(dbConn, argv.RconAddress, argv.RconPassword) + }) + } + + scheduler.Every(500).Seconds().Do(func() { + if err := database.DeleteExpiredSessions(dbConn); err != nil { + log.Println("session cleanup failed:", err) + } + }) + + scheduler.StartAsync() +} + +func refreshArp(dbConn *sql.DB, provider arp.TableProvider) error { + table, err := provider.Fetch() + if err != nil { + return err + } + + ipToMac := make(map[string]string, len(table.AddrToMac)) + for ip, mac := range table.AddrToMac { + ipToMac[ip.Format()] = mac.Format() + } + + return database.RefreshConnections(dbConn, ipToMac) +} + +func sweep(subnet string) { + if err := netscan.Sweep(subnet, sweepTimeout); err != nil { + log.Println("lan sweep failed:", err) + } +} + +func refreshMinecraft(dbConn *sql.DB, address, password string) { + status, err := minecraft.Query(address, password) + if err != nil { + log.Println("minecraft query failed:", err) + status = minecraft.Status{Online: false} + } + + blob, err := json.Marshal(status) + if err != nil { + log.Println("minecraft marshal failed:", err) + return + } + + if err := database.SaveMinecraftStatus(dbConn, string(blob)); err != nil { + log.Println("minecraft save failed:", err) + } +} |
