├── HumanMouse.go ├── LICENSE ├── README.md └── go.mod /HumanMouse.go: -------------------------------------------------------------------------------- 1 | package HumanMouse 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | // Trajectory represents the starting position and behavior of a simulated mouse movement. 9 | type Trajectory struct { 10 | StartX float64 // Initial horizontal position 11 | StartY float64 // Initial vertical position 12 | IsStartRandom bool // Flag to randomize starting position 13 | Bounds Bounds // Movement boundary 14 | } 15 | 16 | // Movements struct holds the simulated mouse movement data. 17 | type Movements struct { 18 | X float64 19 | Y float64 20 | Duration int64 21 | } 22 | 23 | // Bounds struct defines the limits for the mouse movement. 24 | type Bounds struct { 25 | MinX, MaxX, MinY, MaxY float64 26 | } 27 | 28 | // GenerateMouseMovements creates a series of mouse movements. 29 | func (m *Trajectory) GenerateMouseMovements() (movements []Movements) { 30 | const ( 31 | step = 0.390625 32 | randiness = 16 33 | ) 34 | 35 | if m.IsStartRandom { 36 | for !m.isOutOfBounds(m.StartX, m.StartY) || m.StartY == 0 && m.StartX == 0 { 37 | m.StartX, m.StartY = getRandomX(), getRandomY() 38 | } 39 | } 40 | x, y := m.StartX, m.StartY 41 | startTime := time.Now().UnixMilli() 42 | 43 | for m.isOutOfBounds(x, y) { 44 | m.updateCoordinates(&x, &y, step, randiness) 45 | randomSleep() 46 | movements = append(movements, Movements{X: x, Y: y, Duration: time.Now().UnixMilli() - startTime}) 47 | } 48 | 49 | return movements 50 | } 51 | 52 | // isOutOfBounds checks if the current position is outside the defined bounds. 53 | func (m *Trajectory) isOutOfBounds(x, y float64) bool { 54 | return x < m.Bounds.MinX+float64(rand.Intn(10)) || 55 | x > m.Bounds.MaxX-float64(rand.Intn(10)) || 56 | y < m.Bounds.MinY+float64(rand.Intn(10)) || 57 | y > m.Bounds.MaxY-float64(rand.Intn(10)) 58 | } 59 | 60 | // updateCoordinates modifies the coordinates based on predefined logic to simulate random mouse movement. 61 | func (m *Trajectory) updateCoordinates(x, y *float64, step float64, randiness int) { 62 | n := rand.Intn(5) 63 | k := rand.Intn(2) 64 | 65 | switch { 66 | case k == 0 && *y > m.Bounds.MaxY: 67 | *y -= step * float64(rand.Intn(randiness)) 68 | case k == 0 && *y < m.Bounds.MinY: 69 | *y += step * float64(rand.Intn(randiness)) 70 | case k == 0 && rand.Intn(2) == 0 && n == 0: 71 | *y += step * float64(rand.Intn(randiness)) 72 | case k == 0 && n == 0: 73 | *y -= step * float64(rand.Intn(randiness)) 74 | case *x > m.Bounds.MaxX: 75 | *x -= step * float64(rand.Intn(randiness)) 76 | case *x < m.Bounds.MinX: 77 | *x += step * float64(rand.Intn(randiness)) 78 | case rand.Intn(2) == 0 && n == 0: 79 | *x += step * float64(rand.Intn(randiness)) 80 | case n == 0: 81 | *x -= step * float64(rand.Intn(randiness)) 82 | } 83 | } 84 | 85 | // randomSleep introduces a random delay to simulate realistic pauses between mouse movements. 86 | func randomSleep() { 87 | t := rand.Intn(1254) 88 | switch { 89 | case t < 1: 90 | time.Sleep(8 * time.Millisecond) 91 | case t < 2: 92 | time.Sleep(7 * time.Millisecond) 93 | case t < 5: 94 | time.Sleep(6 * time.Millisecond) 95 | case t < 11: 96 | time.Sleep(5 * time.Millisecond) 97 | case t < 23: 98 | time.Sleep(4 * time.Millisecond) 99 | case t < 40: 100 | time.Sleep(3 * time.Millisecond) 101 | case t < 93: 102 | time.Sleep(2 * time.Millisecond) 103 | case t >= 187 && t < 1252: 104 | time.Sleep(1 * time.Millisecond) 105 | } 106 | } 107 | 108 | // getRandomX returns a random horizontal starting position. 109 | func getRandomX() float64 { 110 | units := float64(rand.Intn(1700)) 111 | decimals := float64(390625*(rand.Intn(24)-1)) / 100000000 112 | return units + decimals 113 | } 114 | 115 | // getRandomY returns a random vertical starting position. 116 | func getRandomY() float64 { 117 | units := float64(rand.Intn(800)) 118 | decimals := float64(390625*(rand.Intn(24)-1)) / 100000000 119 | return units + decimals 120 | } 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Victor Sobral 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HumanMouse 2 | 3 | A Go package that simulates realistic, human-like mouse movements. Inspired by Brave browser's mouse position tracking, it's designed for replicating genuine user interactions on web pages and applications. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | go get -u github.com/VicSobDev/HumanMouse 9 | ``` 10 | 11 | ## Features 12 | - Simulate human-like mouse movements with user-defined bounds. 13 | - Generate sequences of mouse movements to mimic real-world user behavior. 14 | - Easy to integrate and customizable. 15 | 16 | 17 | ## Sample Outputs 18 | 19 | **Brave's Mouse Movements:** 20 | 21 | ``` 22 | x: 271, y: 766, duration: 14149ms 23 | x: 271.90234375, y: 766.05859375, duration: 1 24 | x: 272.10546875, y: 765.8515625, duration: 2 25 | x: 272.91796875, y: 765.64453125, duration: 6 26 | x: 272.91796875, y: 765.4375, duration: 6 27 | x: 272.91796875, y: 765.4375, duration: 7 28 | x: 273.12109375, y: 765.4375, duration: 7 29 | x: 273.12109375, y: 765.4375, duration: 8 30 | x: 273.52734375, y: 765.4375, duration: 10 31 | x: 273.52734375, y: 765.4375, duration: 11 32 | x: 273.73046875, y: 765.4375, duration: 11 33 | x: 273.73046875, y: 765.4375, duration: 12 34 | x: 273.73046875, y: 765.23046875, duration: 16 35 | x: 274.74609375, y: 765.0234375, duration: 17 36 | (etc..) 37 | ``` 38 | 39 | **HumanMouse's Generated Movements:** 40 | 41 | ``` 42 | X: 271, Y: 764.4375, Duration: 1 43 | X: 275.6875, Y: 764.4375, Duration: 2 44 | X: 275.6875, Y: 760.921875, Duration: 4 45 | X: 275.6875, Y: 760.921875, Duration: 5 46 | X: 278.421875, Y: 760.921875, Duration: 6 47 | X: 278.421875, Y: 756.234375, Duration: 7 48 | X: 278.8125, Y: 756.234375, Duration: 7 49 | X: 281.546875, Y: 756.234375, Duration: 8 50 | X: 281.546875, Y: 753.890625, Duration: 13 51 | X: 286.625, Y: 753.890625, Duration: 14 52 | X: 286.625, Y: 751.546875, Duration: 15 53 | X: 290.921875, Y: 751.546875, Duration: 16 54 | X: 290.921875, Y: 748.421875, Duration: 17 55 | X: 294.046875, Y: 748.421875, Duration: 18 56 | (etc..) 57 | ``` 58 | 59 | ## Usage 60 | 61 | Define your bounds, decide if the start is random, and generate mouse movements: 62 | 63 | ```go 64 | package main 65 | 66 | import ( 67 | "fmt" 68 | "github.com/VicSobDev/HumanMouse" 69 | ) 70 | 71 | func main() { 72 | m := &HumanMouse.Trajectory{ 73 | IsStartRandom: true, 74 | Bounds: HumanMouse.Bounds{ 75 | MinX: 100.0, 76 | MaxX: 800.0, 77 | MinY: 50.0, 78 | MaxY: 600.0, 79 | }, 80 | } 81 | movements := m.GenerateMouseMovements() 82 | for _, move := range movements { 83 | fmt.Println(move) 84 | } 85 | } 86 | ``` 87 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/VicSobDev/HumanMouse 2 | 3 | go 1.20 4 | --------------------------------------------------------------------------------