summaryrefslogtreecommitdiff
path: root/scheduled/scheduled.go
diff options
context:
space:
mode:
Diffstat (limited to 'scheduled/scheduled.go')
-rw-r--r--scheduled/scheduled.go86
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)
+ }
+}