Compare commits

..

No commits in common. "bda9fc5e8a75ba22feba37d24566d729d5c97f73" and "5f24267ebb7c78ab2731c1db737c48be35b699bb" have entirely different histories.

View File

@ -6,31 +6,22 @@ import java.util.concurrent.TimeUnit
import kotlin.random.Random import kotlin.random.Random
/** /**
* Utility class for programmatically controlling mouse and keyboard actions. * Class providing methods for programmatic control of mouse and keyboard.
* *
* This class allows performing mouse movements, clicks, and keyboard presses * This uses a Robot instance to facilitate actions like mouse movements,
* through a [Robot] instance. It includes utility methods to add less-robotic * clicks, scrolls, and key presses.
* variance and pacing to the actions.
* *
* Basic usage: * It contains utility methods to perform actions in a human-like way,
* including random pacing and wiggle to avoid robotic movement.
*
* Typical usage:
* *
* ``` * ```
* val doer = Doer() * val doer = Doer()
* * val nearbyPoint = doer.getAlmostPoint(Point(100, 200), WiggleParams(50, 50))
* // Move mouse * doer.mouseMove(nearbyPoint)
* val target = Point(100, 200) * doer.click(InputEvent.BUTTON1_DOWN_MASK)
* val nearTarget = doer.getAlmostPoint(target, WiggleParams())
* doer.mouseMove(nearTarget)
*
* // Mouse click
* doer.click(Doer.LEFT_CLICK)
*
* // Type keys
* doer.keypress(KeyEvent.VK_A)
* doer.keypress(KeyEvent.VK_B)
* ``` * ```
*
* @constructor Creates a Doer instance with a Robot.
*/ */
class Doer { class Doer {
@ -39,8 +30,18 @@ class Doer {
*/ */
private val robot = Robot() private val robot = Robot()
companion object { companion object {
/** /**
* The duration in milliseconds of one "tick". The duration of 600ms matches the tick duration of game servers. * Mouse button mask for a left mouse click.
*
* This stores the button mask value from [InputEvent] that represents a left mouse click.
*
* It can be passed to [click] or other methods that expect a mouse button value.
*/
private const val LEFT_CLICK = InputEvent.BUTTON1_DOWN_MASK
/**
* The duration in milliseconds of one "tick".
* *
* This defines the concept of a "tick" as a unit of time used for pacing actions. * This defines the concept of a "tick" as a unit of time used for pacing actions.
* *
@ -52,8 +53,7 @@ class Doer {
const val TICK_DURATION_MS = 600L const val TICK_DURATION_MS = 600L
/** /**
* Extra padding in milliseconds added before actions to account for latency. 500ms is entirely arbitrary. It is * Extra padding in milliseconds added before actions to account for latency.
* simply a value that works well during high-load periods. Better to be conservative than lossy.
* *
* This defines an extra duration in milliseconds that is added to sleeps * This defines an extra duration in milliseconds that is added to sleeps
* and waits. * and waits.
@ -65,16 +65,15 @@ class Doer {
} }
/** /**
* Data class to hold parameters for random wiggle amounts when moving the mouse. This is useful for avoiding * Data class to hold parameters for random wiggle amounts when moving the mouse.
* "robotic" location patterns on the screen. You'll still converge into an absolutely perfect box, but meh.
* *
* This holds the maximum x and y wiggle offset values to use when randomly * This holds the maximum x and y wiggle offset values to use when randomly
* offsetting mouse movements to make them less robotic. * offsetting mouse movements to make them less robotic.
* *
* For example, this could be passed to [getAlmostPoint] to control the randomization. * For example, this could be passed to [getAlmostPoint] to control the randomization.
* *
* @param xWiggle The max x offset for both parities. So a xWiggle value of 5 will result in a value of x +/- 5, default 25. * @param xWiggle The max x offset, default 25.
* @param yWiggle The max y offset for both parities. So a yWiggle value of 5 will result in a value of y +/- 5, default 25. * @param yWiggle The max y offset, default 25.
*/ */
data class WiggleParams(val xWiggle: Int = 25, val yWiggle: Int = 25) data class WiggleParams(val xWiggle: Int = 25, val yWiggle: Int = 25)
@ -84,18 +83,6 @@ class Doer {
* This uses the Robot [mouseMove] method to move the mouse cursor * This uses the Robot [mouseMove] method to move the mouse cursor
* to the x and y coordinates specified by the provided [Point] p. * to the x and y coordinates specified by the provided [Point] p.
* *
* Usage:
*```
* val doer = Doer()
*
* // Create target point
* val target = Point(100, 200)
*
* // Move mouse to target
* doer.mouseMove(target)
*```
*
*
* @param p The [Point] representing the x and y coordinates to move the mouse to. * @param p The [Point] representing the x and y coordinates to move the mouse to.
*/ */
fun mouseMove(p: Point) { fun mouseMove(p: Point) {
@ -114,12 +101,8 @@ class Doer {
* @param button The mouse button to click, as a button mask from [InputEvent]. * @param button The mouse button to click, as a button mask from [InputEvent].
*/ */
fun click(button: Int) { fun click(button: Int) {
robot.mousePress(button) robot.mousePress(button)
//we add in some random time variance here to appear less robotic
sleep(8, 8) sleep(8, 8)
robot.mouseRelease(button) robot.mouseRelease(button)
} }
@ -135,12 +118,8 @@ class Doer {
* @param key The key code of the key to press, from [java.awt.event.KeyEvent]. * @param key The key code of the key to press, from [java.awt.event.KeyEvent].
*/ */
fun keypress(key: Int) { fun keypress(key: Int) {
robot.keyPress(key) robot.keyPress(key)
//we add in some random time variance here to appear less robotic
sleep(8, 8) sleep(8, 8)
robot.keyRelease(key) robot.keyRelease(key)
} }
@ -158,8 +137,7 @@ class Doer {
fun moveMouseLeftClickAndSleep(p: Point, dur: Long, durRange: Long) { fun moveMouseLeftClickAndSleep(p: Point, dur: Long, durRange: Long) {
mouseMove(p) mouseMove(p)
sleep(100, 50) sleep(100, 50)
//left click click(LEFT_CLICK)
click(InputEvent.BUTTON1_DOWN_MASK)
sleep(dur, durRange) sleep(dur, durRange)
} }