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) } }