// Package input provides human-like mouse and keyboard simulation. // // Mouse movement uses Bézier curves with natural acceleration. // All inputs include randomized timing to mimic human behavior. // Platform-specific backends: SendInput (Windows), X11/uinput (Linux). package input import ( "image" "math" "math/rand" "time" ) // MouseController handles human-like mouse movement and clicks. type MouseController struct { humanizer *Humanizer } // NewMouseController creates a mouse controller with the given humanizer. func NewMouseController(h *Humanizer) *MouseController { return &MouseController{humanizer: h} } // MoveTo moves the mouse to target using a Bézier curve. func (m *MouseController) MoveTo(target image.Point) { // Get current position current := m.GetPosition() // Generate Bézier control points points := m.bezierPath(current, target) // Animate along the path speed := m.humanizer.MouseSpeed() totalDist := m.pathLength(points) steps := int(totalDist / speed * 1000) // ms-based steps if steps < 5 { steps = 5 } for i := 1; i <= steps; i++ { t := float64(i) / float64(steps) // Ease in-out for natural acceleration t = m.easeInOut(t) p := m.evalBezier(points, t) m.setPosition(p) time.Sleep(time.Millisecond) } } // Click performs a mouse click at the current position. func (m *MouseController) Click() { m.humanizer.Wait() // TODO: Platform-specific click (SendInput / X11) // Randomize hold duration holdMs := 50 + rand.Intn(80) time.Sleep(time.Duration(holdMs) * time.Millisecond) } // ClickAt moves to position and clicks. func (m *MouseController) ClickAt(pos image.Point) { jittered := m.humanizer.JitterPosition(pos) m.MoveTo(jittered) m.Click() } // RightClick performs a right mouse click. func (m *MouseController) RightClick() { m.humanizer.Wait() holdMs := 50 + rand.Intn(80) time.Sleep(time.Duration(holdMs) * time.Millisecond) } // GetPosition returns current mouse position. func (m *MouseController) GetPosition() image.Point { // TODO: Platform-specific implementation return image.Point{} } func (m *MouseController) setPosition(p image.Point) { // TODO: Platform-specific implementation } // bezierPath generates a cubic Bézier curve with randomized control points. func (m *MouseController) bezierPath(start, end image.Point) [4]image.Point { dx := float64(end.X - start.X) dy := float64(end.Y - start.Y) // Randomize control points for natural curvature cp1 := image.Point{ X: start.X + int(dx*0.25+rand.Float64()*50-25), Y: start.Y + int(dy*0.25+rand.Float64()*50-25), } cp2 := image.Point{ X: start.X + int(dx*0.75+rand.Float64()*50-25), Y: start.Y + int(dy*0.75+rand.Float64()*50-25), } return [4]image.Point{start, cp1, cp2, end} } // evalBezier evaluates a cubic Bézier curve at parameter t. func (m *MouseController) evalBezier(pts [4]image.Point, t float64) image.Point { u := 1 - t return image.Point{ X: int(u*u*u*float64(pts[0].X) + 3*u*u*t*float64(pts[1].X) + 3*u*t*t*float64(pts[2].X) + t*t*t*float64(pts[3].X)), Y: int(u*u*u*float64(pts[0].Y) + 3*u*u*t*float64(pts[1].Y) + 3*u*t*t*float64(pts[2].Y) + t*t*t*float64(pts[3].Y)), } } // easeInOut applies ease-in-out for natural mouse acceleration. func (m *MouseController) easeInOut(t float64) float64 { return t * t * (3 - 2*t) } func (m *MouseController) pathLength(pts [4]image.Point) float64 { length := 0.0 prev := pts[0] for i := 1; i <= 20; i++ { t := float64(i) / 20.0 p := m.evalBezier(pts, t) dx := float64(p.X - prev.X) dy := float64(p.Y - prev.Y) length += math.Sqrt(dx*dx + dy*dy) prev = p } return length } // KeyboardController handles human-like keyboard input. type KeyboardController struct { humanizer *Humanizer } // NewKeyboardController creates a keyboard controller. func NewKeyboardController(h *Humanizer) *KeyboardController { return &KeyboardController{humanizer: h} } // PressKey presses and releases a key with human-like timing. func (k *KeyboardController) PressKey(key string) { k.humanizer.Wait() // TODO: Platform-specific key press holdMs := 30 + rand.Intn(70) time.Sleep(time.Duration(holdMs) * time.Millisecond) } // TypeText types text with randomized inter-key delays. func (k *KeyboardController) TypeText(text string) { for _, ch := range text { k.PressKey(string(ch)) delay := 30 + rand.Intn(120) // 30-150ms between keys time.Sleep(time.Duration(delay) * time.Millisecond) } } // HoldKey holds a key down for a duration. func (k *KeyboardController) HoldKey(key string, durationMs int) { // TODO: Platform-specific key down/up variance := rand.Intn(durationMs / 5) time.Sleep(time.Duration(durationMs+variance) * time.Millisecond) }