mirror of https://github.com/jetkvm/kvm.git
134 lines
3.1 KiB
Go
134 lines
3.1 KiB
Go
package kvm
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/go-co-op/gocron/v2"
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
type JigglerConfig struct {
|
|
InactivityLimitSeconds int `json:"inactivity_limit_seconds"`
|
|
JitterPercentage int `json:"jitter_percentage"`
|
|
ScheduleCronTab string `json:"schedule_cron_tab"`
|
|
}
|
|
|
|
var jigglerEnabled = false
|
|
var jobDelta time.Duration = 0
|
|
var scheduler gocron.Scheduler = nil
|
|
|
|
func rpcSetJigglerState(enabled bool) {
|
|
jigglerEnabled = enabled
|
|
}
|
|
func rpcGetJigglerState() bool {
|
|
return jigglerEnabled
|
|
}
|
|
|
|
func rpcGetJigglerConfig() (JigglerConfig, error) {
|
|
return *config.JigglerConfig, nil
|
|
}
|
|
|
|
func rpcSetJigglerConfig(jigglerConfig JigglerConfig) error {
|
|
logger.Infof("[jsonrpc.go:rpcSetJigglerConfig] jigglerConfig: %v, %v, %v", jigglerConfig.InactivityLimitSeconds, jigglerConfig.JitterPercentage, jigglerConfig.ScheduleCronTab)
|
|
config.JigglerConfig = &jigglerConfig
|
|
err := removeExistingCrobJobs(scheduler)
|
|
if err != nil {
|
|
return fmt.Errorf("error removing cron jobs from scheduler %v", err)
|
|
}
|
|
err = runJigglerCronTab()
|
|
if err != nil {
|
|
return fmt.Errorf("error scheduling jiggler crontab: %v", err)
|
|
}
|
|
err = SaveConfig()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save config: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func removeExistingCrobJobs(s gocron.Scheduler) error {
|
|
for _, j := range s.Jobs() {
|
|
err := s.RemoveJob(j.ID())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func init() {
|
|
ensureConfigLoaded()
|
|
err := runJigglerCronTab()
|
|
if err != nil {
|
|
logger.Errorf("Error scheduling jiggler crontab: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func runJigglerCronTab() error {
|
|
cronTab := config.JigglerConfig.ScheduleCronTab
|
|
s, err := gocron.NewScheduler()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
scheduler = s
|
|
_, err = s.NewJob(
|
|
gocron.CronJob(
|
|
cronTab,
|
|
true,
|
|
),
|
|
gocron.NewTask(
|
|
func() {
|
|
runJiggler()
|
|
},
|
|
),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.Start()
|
|
delta, err := calculateJobDelta(s)
|
|
jobDelta = delta
|
|
logger.Infof("Time between jiggler runs: %v", jobDelta)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func runJiggler() {
|
|
if jigglerEnabled {
|
|
if config.JigglerConfig.JitterPercentage != 0 {
|
|
jitter := calculateJitterDuration(jobDelta)
|
|
logger.Debugf("Jitter enabled, Sleeping for %v", jitter)
|
|
time.Sleep(jitter)
|
|
}
|
|
inactivitySeconds := config.JigglerConfig.InactivityLimitSeconds
|
|
if time.Since(gadget.GetLastUserInputTime()) > time.Duration(inactivitySeconds)*time.Second {
|
|
//TODO: change to rel mouse
|
|
err := rpcAbsMouseReport(1, 1, 0)
|
|
if err != nil {
|
|
logger.Warnf("Failed to jiggle mouse: %v", err)
|
|
}
|
|
err = rpcAbsMouseReport(0, 0, 0)
|
|
if err != nil {
|
|
logger.Warnf("Failed to reset mouse position: %v", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func calculateJobDelta(s gocron.Scheduler) (time.Duration, error) {
|
|
j := s.Jobs()[0]
|
|
runs, err := j.NextRuns(2)
|
|
if err != nil {
|
|
return 0.0, err
|
|
}
|
|
return runs[1].Sub(runs[0]), nil
|
|
}
|
|
|
|
func calculateJitterDuration(delta time.Duration) time.Duration {
|
|
jitter := rand.Float64() * float64(config.JigglerConfig.JitterPercentage) / 100 * delta.Seconds()
|
|
return time.Duration(jitter * float64(time.Second))
|
|
}
|