diff --git a/src/main/kotlin/RobotController.kt b/src/main/kotlin/RobotController.kt index 11905df..ddb83a7 100644 --- a/src/main/kotlin/RobotController.kt +++ b/src/main/kotlin/RobotController.kt @@ -5,27 +5,129 @@ import java.awt.event.InputEvent import java.util.concurrent.TimeUnit import kotlin.random.Random +/** + * Interface for controllers that provide input capabilities. + * + * This defines methods for mouse and keyboard input like: + * + * - Moving the mouse + * - Mouse clicks + * - Key presses + * - Scrolling + * + * Classes that implement this interface can serve as input automation controllers. + */ interface InputController { + /** + * Moves the mouse to the given [Point]. + * + * @param point The destination [Point] to move the mouse to. + */ fun moveMouse(point: Point) + /** + * Performs a mouse click at the current pointer location. + * + * @param button The mouse button to click. + * e.g. [InputEvent.BUTTON1_MASK] + */ fun mouseClick(button: Int) + /** + * Presses and releases the given key. + * + * @param keyCode The key code of the key to press. + */ fun keyPress(keyCode: Int) - fun sleep(duration: Long) - - fun sleepWithVariance(duration: Long, variance: Long) - + /** + * Performs a scroll in motion. + * + * This will move the scroll wheel forward by the number of ticks + * over the duration. It will sleep for short intervals between + * ticks using the provided sleep duration and variance. + * + * @param sleepDur The base sleep duration between scroll ticks. + * @param sleepDurVariance The variance in sleep duration. + */ fun scrollIn(sleepDur: Long, sleepDurVariance: Long) + /** + * Performs a scroll out motion. + * + * Same as [scrollIn] but moves the scroll wheel backward. + */ fun scrollOut(sleepDur: Long, sleepDurVariance: Long) } +interface TemporalController{ + /** + * Sleeps for the specified duration. + * + * This uses [TimeUnit.MILLISECONDS] to sleep for the given duration in milliseconds. + * + * @param dur The sleep duration in milliseconds. + */ + fun sleep(dur: Long) { + TimeUnit.MILLISECONDS.sleep(dur) + } + + /** + * Sleeps for the specified duration with some variance. + * + * This will sleep for the given duration plus or minus a random variance. + * The variance is divided in half to generate a random positive and negative + * value that is added to the duration. + * + * If the duration is negative or the variance is less than 1, this method + * will return immediately without sleeping. + * + * @param duration The base sleep duration in ms + * @param variance The amount of variance to add in ms. Gets divided in half + * to generate random +/- values. + */ + fun sleepWithVariance(duration: Long, variance: Long) { + if (duration < 0 || variance <= 1) { + return + } + val dSize = (variance) / 2 + val r1 = Random.nextLong(dSize) + val r2 = Random.nextLong(dSize) + sleep(duration + r1 + r2) + } +} + +/** + * Interface for controllers that interact with the desktop. + * + * This defines methods for getting desktop state like the mouse pointer + * location. + * + * Classes that implement this can serve as desktop automation controllers. + */ interface DesktopController { + /** + * Gets the current pointer/mouse location on the desktop. + * + * @return The current [Point] location of the mouse pointer. + */ fun getPointerLocation(): Point { return MouseInfo.getPointerInfo().location } + /** + * Gets a "wiggly" point near the given point. + * + * This takes in a target [Point] and [WiggleParams] and returns a new + * point that is randomly offset from the target point based on the + * wiggle parameters. + * + * This is useful for adding variance to mouse movements. + * + * @param point The target point to wiggle around + * @param params The wiggle parameters + * @return A new [Point] randomly offset from the target point. + */ fun getAlmostPoint(point: Point, params : WiggleParams): Point{ val xDel = Random.nextInt(0, params.xWiggle) val yDel = Random.nextInt(0, params.yWiggle) @@ -43,18 +145,52 @@ interface DesktopController { } } -interface DesktopInputController : DesktopController, InputController - - -data class WiggleParams(val xWiggle: Int = 25, val yWiggle: Int = 25) +/** + * Interface for controllers that provide desktop input capabilities. + * + * This interface extends [DesktopController], [InputController], and + * [TemporalController] to create a combined interface that can: + * + * - Get desktop/mouse info like pointer location + * - Perform mouse and keyboard input like clicks and key presses + * - Control timing and add delays + * + * Classes that implement this interface can serve as full featured + * controllers for desktop automation tasks. + */ +interface DesktopInputController : DesktopController, InputController, TemporalController +/** + * Data class to hold wiggle parameters for mouse movement. + * + * This simple data class holds two integer properties for x and y wiggle amounts. + * These are used when generating simulated mouse movements to add some variance + * and randomness to the coordinates. + * + * For example, if a target destination point is (100, 200), the wiggle params + * might generate an actual movement point like (102, 198) to add some randomness. + * + * @param xWiggle The max amount of variance in x direction. Default 25. + * @param yWiggle The max amount of variance in y direction. Default 25. + */ +data class WiggleParams( + val xWiggle: Int = 25, + val yWiggle: Int = 25 +) +/** + * Implementation of [DesktopInputController] using [java.awt.Robot]. + * + * This class implements desktop automation capabilities using the Robot + * class from the AWT library. It provides methods for: + * + * - Getting mouse/pointer info + * - Mouse and keyboard input + * - Adding timing and delays + * + * @param robot The Robot instance to use. A default is created if not provided. + */ open class RobotController(private val robot: Robot = Robot()) : DesktopInputController { - - - - - /** * Moves the mouse cursor to the given [Point]. * @@ -130,28 +266,6 @@ open class RobotController(private val robot: Robot = Robot()) : DesktopInputCon robot.keyRelease(key) } - /** - * Sleeps for the specified duration. - * - * This uses [TimeUnit.MILLISECONDS] to sleep for the given duration in milliseconds. - * - * @param dur The sleep duration in milliseconds. - */ - override fun sleep(dur: Long) { - TimeUnit.MILLISECONDS.sleep(dur) - } - - - override fun sleepWithVariance(duration: Long, variance: Long) { - if (duration < 0 || variance <= 1) { - return - } - val dSize = (variance) / 2 - val r1 = Random.nextLong(dSize) - val r2 = Random.nextLong(dSize) - sleep(duration + r1 + r2) - } - /** * Scrolls the mouse wheel down by one unit. *