update the MouseJiggler,change to use the goroutine

This commit is contained in:
LingkongSky
2025-04-08 14:21:47 +08:00
parent d45aaf6cb2
commit 8037081e0c
3 changed files with 108 additions and 79 deletions

View File

@@ -1,53 +0,0 @@
#!/bin/sh
#
# mouse-jiggler Starts mouse-jiggler.
#
PIDFILE="/var/run/mouse-jiggler.pid"
start() {
if [ ! -f "$PIDFILE" ];then
echo "Starting Mouse Jiggler"
(
status=true
while true;do
if [ "$status" = true ];then
echo -ne \\x00\\x10\\x00\\x00 > /dev/hidg1
status=false
else
echo -ne \\x10\\x00\\x00\\x00 > /dev/hidg1
status=true
fi
sleep 60
done
) >/dev/null 2>&1 &
echo $! > "$PIDFILE"
else
stop
start
fi
}
stop() {
echo "Stopping Mouse Jiggler"
[ -f "$PIDFILE" ] && kill $(cat "$PIDFILE") && rm -f "$PIDFILE"
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0

View File

@@ -4,11 +4,17 @@ import (
"encoding/binary"
"errors"
"os"
"sync"
"time"
log "github.com/sirupsen/logrus"
)
var (
LastHIDTime time.Time
HidMutex sync.Mutex
)
const (
MouseUp = iota
MouseDown
@@ -43,6 +49,7 @@ func (h *Hid) Mouse(queue <-chan []int) {
}
h.mouseMutex.Unlock()
UpdateLastHIDTime()
}
}
@@ -109,3 +116,9 @@ func (h *Hid) writeWithTimeout(file *os.File, data []byte) {
log.Debugf("write to hid: %+v", data)
}
func UpdateLastHIDTime() {
HidMutex.Lock()
defer HidMutex.Unlock()
LastHIDTime = time.Now()
}

View File

@@ -2,25 +2,42 @@ package vm
import (
"NanoKVM-Server/proto"
"errors"
"fmt"
"NanoKVM-Server/service/hid"
"os"
"os/exec"
"strings"
"sync/atomic"
"time"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
const (
MouseJigglerStartFlag = "/var/run/mouse-jiggler.pid"
MouseJigglerScript = "/etc/init.d/S50mouse-jiggler"
MouseJigglerBackupScript = "/kvmapp/system/init.d/S50mouse-jiggler"
mouseJiggleInterval = 15
MouseJigglerStartFlag = "/etc/kvm/mouse-jiggler_start"
)
var (
jigglerEnabled int32
jigglerStopChan chan struct{}
)
type mouseReport struct {
buttons byte
xMove int8
yMove int8
wheel int8
}
func init() {
enabled := isMouseJigglerEnabled()
if enabled {
hid.UpdateLastHIDTime()
go mouseJigglerRoutine()
}
}
func (s *Service) GetMouseJigglerState(c *gin.Context) {
var rsp proto.Response
enabled := isMouseJigglerEnabled()
rsp.OkRspWithData(c, &proto.GetMouseJigglerStateRsp{
Enabled: enabled,
@@ -30,21 +47,25 @@ func (s *Service) GetMouseJigglerState(c *gin.Context) {
func (s *Service) EnableMouseJiggler(c *gin.Context) {
var rsp proto.Response
commands := []string{
fmt.Sprintf("cp -f %s %s", MouseJigglerBackupScript, MouseJigglerScript),
fmt.Sprintf("chmod +x %s", MouseJigglerScript),
fmt.Sprintf("dos2unix %s", MouseJigglerScript),
fmt.Sprintf("%s start", MouseJigglerScript),
enabled := isMouseJigglerEnabled()
if enabled {
rsp.OkRsp(c)
return
}
command := strings.Join(commands, " && ")
err := exec.Command("sh", "-c", command).Run()
atomic.StoreInt32(&jigglerEnabled, 1)
jigglerStopChan = make(chan struct{})
go mouseJigglerRoutine()
fp, err := os.Create(MouseJigglerStartFlag)
if err != nil {
log.Errorf("failed to run MouseJiggler script: %s", err)
log.Errorf("MouseJiggler enable failed: %s", err)
rsp.ErrRsp(c, -1, "operation failed")
return
}
defer fp.Close()
rsp.OkRsp(c)
log.Debugf("MouseJiggler enabled")
}
@@ -52,26 +73,74 @@ func (s *Service) EnableMouseJiggler(c *gin.Context) {
func (s *Service) DisableMouseJiggler(c *gin.Context) {
var rsp proto.Response
command := fmt.Sprintf("%s stop", MouseJigglerScript)
err := exec.Command("sh", "-c", command).Run()
if err != nil {
log.Errorf("failed to run MouseJiggler script: %s", err)
rsp.ErrRsp(c, -1, "operation failed")
enabled := isMouseJigglerEnabled()
if !enabled {
rsp.OkRsp(c)
return
}
_ = os.Remove(MouseJigglerScript)
atomic.StoreInt32(&jigglerEnabled, 0)
close(jigglerStopChan)
_ = os.Remove(MouseJigglerStartFlag)
rsp.OkRsp(c)
log.Debugf("MouseJiggler disabled")
}
func isMouseJigglerEnabled() bool {
_, err := os.Stat(MouseJigglerStartFlag)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return false
if atomic.LoadInt32(&jigglerEnabled) == 1 {
return true
}
return false
}
func mouseJigglerRoutine() {
ticker := time.NewTicker(mouseJiggleInterval * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if shouldJiggleMouse() {
hid.UpdateLastHIDTime()
jiggleMouse()
}
case <-jigglerStopChan:
return
}
}
}
func shouldJiggleMouse() bool {
enabled := isMouseJigglerEnabled()
if !enabled {
return false
}
hid.HidMutex.Lock()
defer hid.HidMutex.Unlock()
if time.Since(hid.LastHIDTime) < mouseJiggleInterval*time.Second {
return false
}
return true
}
func jiggleMouse() {
moveRight := []byte{0x00, 0x0a, 0x00, 0x00}
moveLeft := []byte{0x00, 0xf6, 0x00, 0x00}
err := os.WriteFile("/dev/hidg1", moveRight, 0644)
if err != nil {
log.Debugf("MouseJiggler write error:", err)
return
}
err = os.WriteFile("/dev/hidg1", moveLeft, 0644)
if err != nil {
log.Debugf("MouseJiggler write error:", err)
return
}
}