package services import ( "log" "sync" "github.com/robfig/cron/v3" ) type Scheduler struct { cron *cron.Cron entryID cron.EntryID settings *SettingsManager modlists *ModlistManager steamcmd *SteamCmdManager mu sync.Mutex } func NewScheduler(settings *SettingsManager, modlists *ModlistManager, steamcmd *SteamCmdManager) *Scheduler { return &Scheduler{ cron: cron.New(), settings: settings, modlists: modlists, steamcmd: steamcmd, } } func (s *Scheduler) Start() { s.cron.Start() s.Refresh() } func (s *Scheduler) Stop() { s.cron.Stop() } func (s *Scheduler) Refresh() { s.mu.Lock() defer s.mu.Unlock() if s.entryID != 0 { s.cron.Remove(s.entryID) s.entryID = 0 } sett, err := s.settings.Load() if err != nil || sett.ScheduledUpdate == "" { return } id, err := s.cron.AddFunc(sett.ScheduledUpdate, s.runScheduledUpdate) if err != nil { log.Printf("scheduler: invalid cron expression %q: %v", sett.ScheduledUpdate, err) return } s.entryID = id log.Printf("scheduler: scheduled update with cron %q", sett.ScheduledUpdate) } func (s *Scheduler) runScheduledUpdate() { sett, err := s.settings.Load() if err != nil { return } if sett.SteamUser != "" && sett.SteamUser != "anonymous" { log.Print("scheduler: running gameserver update") if err := s.steamcmd.UpdateGame(sett.SteamBranch, sett.SteamUser); err != nil { log.Printf("scheduler: game update failed: %v", err) } } if sett.ActiveModlist != "" { ml, err := s.modlists.Get(sett.ActiveModlist) if err != nil { log.Printf("scheduler: load modlist %s: %v", sett.ActiveModlist, err) return } var modIDs []string for _, m := range ml.Mods { if m.Enabled { modIDs = append(modIDs, m.ID) } } if len(modIDs) > 0 { log.Printf("scheduler: updating %d mod(s)", len(modIDs)) if err := s.steamcmd.DownloadMods(modIDs); err != nil { log.Printf("scheduler: mod update failed: %v", err) } } } }