From fb653292612eddca5b088ed88466c546d1597107 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Sat, 20 Jun 2026 09:40:07 -0700 Subject: Initial commit --- scheduled/scheduled.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 scheduled/scheduled.go (limited to 'scheduled/scheduled.go') 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) + } +} -- cgit v1.3