structured everything into packages
This commit is contained in:
parent
6b082a383a
commit
1b2b24c317
@ -1,394 +0,0 @@
|
||||
import java.awt.MouseInfo
|
||||
import java.awt.Point
|
||||
import java.awt.Robot
|
||||
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)
|
||||
|
||||
/**
|
||||
* Performs a mousewheel 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 mousewheel 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 a random variance between 0 inclusive and [variance] exclusive.
|
||||
* The variance is divided in half to generate a random positive 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
|
||||
* and rolled as two separate random numbers to create a normal distribution
|
||||
*/
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* val controller = DesktopController()
|
||||
* val wiggle = WiggleParams(xWiggle = 10, yWiggle = 15)
|
||||
*
|
||||
* val target = Point(100, 200)
|
||||
* val actual = controller.getAlmostPoint(target, wiggle) // (104, 197)
|
||||
* ```
|
||||
*
|
||||
* @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
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
val xDir = if (Random.nextDouble() > 0.5) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
val yDir = if (Random.nextDouble() > 0.5) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
return Point(point.x + (xDel * xDir), point.y + (yDel * yDir))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for full-featured desktop automation controllers.
|
||||
*
|
||||
* Automaton combines capabilities from other interfaces to create a controller that can:
|
||||
*
|
||||
* - Get desktop and mouse state information like pointer location via [DesktopController]
|
||||
*
|
||||
* - Perform mouse and keyboard input like clicks, key presses, and scrolling via [InputController]
|
||||
*
|
||||
* - Handle timing and delays between actions using [TemporalController]
|
||||
*
|
||||
* By composing multiple capabilities, Automaton aims to provide a simple yet powerful interface for implementing
|
||||
* desktop automation routines.
|
||||
*
|
||||
* Typical usage involves:
|
||||
*
|
||||
* 1. Obtaining an Automaton instance bound to the current OS/desktop
|
||||
* 2. Calling methods like [moveMouse] and [mouseClick] to perform actions
|
||||
* 3. Using [sleep] and [sleepWithVariance] to add delays
|
||||
*
|
||||
* This interface allows the underlying OS/desktop implementation details to be abstracted and swapped as needed.
|
||||
*/
|
||||
interface Automaton : DesktopController, InputController, TemporalController
|
||||
|
||||
|
||||
/**
|
||||
* Desktop automation controller using java.awt.Robot.
|
||||
*
|
||||
* This provides mouse, keyboard, and timing control capabilities by
|
||||
* wrapping the java.awt.Robot class.
|
||||
*
|
||||
* Key features:
|
||||
*
|
||||
* - Get current mouse/pointer location
|
||||
* - Move mouse and perform clicks
|
||||
* - Keyboard presses and hotkeys
|
||||
* - Scroll wheel motions
|
||||
* - Sleep/delay methods with variance
|
||||
*
|
||||
* RobotController aims to provide a simple and easy to use API for
|
||||
* automating desktop interactions and workflows.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Move mouse to 100, 200
|
||||
* robot.mouseMove(Point(100, 200))
|
||||
*
|
||||
* // Left click at current position
|
||||
* robot.click(InputEvent.BUTTON1_MASK)
|
||||
*
|
||||
* // Press A key
|
||||
* robot.keyPress(KeyEvent.VK_A)
|
||||
* ```
|
||||
*
|
||||
* @param robot The Robot instance to use. A default is created if not provided.
|
||||
*/
|
||||
open class RobotController(private val robot: Robot = Robot()) : Automaton {
|
||||
|
||||
/**
|
||||
* Moves the mouse pointer to the given [Point] coordinates.
|
||||
*
|
||||
* This will use the [Robot] API to move the mouse to the x,y position.
|
||||
* It also does validation to retry the move if ended up at incorrect location.
|
||||
*
|
||||
* Usage examples:
|
||||
*
|
||||
* ```
|
||||
* val controller = DesktopController()
|
||||
* controller.moveMouse(Point(100, 200))
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* ```
|
||||
* val target = Point(500, 300)
|
||||
* controller.moveMouse(target)
|
||||
* ```
|
||||
*
|
||||
* @param point The destination [Point] x,y coordinates to move the mouse to.
|
||||
*
|
||||
*
|
||||
|
||||
*
|
||||
*/
|
||||
override fun moveMouse(point: Point) {
|
||||
robot.mouseMove(point.x, point.y)
|
||||
|
||||
//There's a bug in OpenJDK that results in incorrect cursor position in the [Robot.mouseMove] function if using
|
||||
//a Windows Resolution scale other than 100%. As a result, we have to check that the cursor made it all the way.
|
||||
//From some anecdotal observation, it has an overshoot/decay pattern sort of like a binary search. The mouse will
|
||||
//usually be in the correct place within 2-3 loop itterations
|
||||
|
||||
repeat(10) {
|
||||
val rPoint = getPointerLocation()
|
||||
//here, we check the points and if we're good, we
|
||||
if (rPoint.x == point.x && rPoint.y == point.y) {
|
||||
return
|
||||
} else {
|
||||
robot.mouseMove(point.x, point.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a mouse click of the specified button.
|
||||
*
|
||||
* This uses the Robot to press and release the given mouse button.
|
||||
*
|
||||
* A random sleep is added in between pressing and releasing the button
|
||||
* to add variance and avoid robotic timing.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Perform left click at current mouse position
|
||||
* robot.click(InputEvent.BUTTON1_MASK)
|
||||
* ```
|
||||
*
|
||||
* @param button The button to click. Must be a valid constant like [InputEvent.BUTTON1_MASK].
|
||||
*
|
||||
* Returns immediately If button is negative. Button must be a positive integer.
|
||||
*/
|
||||
override fun mouseClick(button: Int) {
|
||||
//guardian logic
|
||||
if (button < 0) {
|
||||
return
|
||||
}
|
||||
robot.mousePress(button)
|
||||
|
||||
//we add in some random time variance here to appear less robotic
|
||||
sleepWithVariance(8, 8)
|
||||
|
||||
robot.mouseRelease(button)
|
||||
}
|
||||
|
||||
/**
|
||||
* Presses and releases the given key.
|
||||
*
|
||||
* This uses the Robot to simulate pressing and releasing the key with the given key code.
|
||||
*
|
||||
* A random sleep is added after pressing the key before releasing it to add variance
|
||||
* and avoid robotic timing.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Press the 'A' key
|
||||
* robot.keyPress(KeyEvent.VK_A)
|
||||
* ```
|
||||
*
|
||||
* @param keyCode The key code of the key to press, such as [KeyEvent.VK_A].
|
||||
*
|
||||
* Returns immediately if keyCode < 0. This can be useful for skipping actions by passing -1
|
||||
*/
|
||||
override fun keyPress(keyCode: Int) {
|
||||
//guardian logic
|
||||
if (keyCode < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
robot.keyPress(keyCode)
|
||||
|
||||
//we add in some random time variance here to appear less robotic
|
||||
sleepWithVariance(8, 8)
|
||||
|
||||
robot.keyRelease(keyCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the mouse wheel down by one unit.
|
||||
*
|
||||
* Uses the [Robot.mouseWheel] method to scroll down and then sleeps
|
||||
* for a random duration between 10-20ms to pace the scrolling.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Scroll down 5 units
|
||||
* repeat(5) {
|
||||
* robot.scrollDown()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override fun scrollOut(sleepDur: Long, sleepDurVariance: Long) {
|
||||
robot.mouseWheel(1)
|
||||
sleepWithVariance(sleepDur, sleepDurVariance)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the mouse wheel up by one unit.
|
||||
*
|
||||
* Uses the [Robot.mouseWheel] method to scroll up and then sleeps for a
|
||||
* random duration between 10-20ms to pace the scrolling.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Scroll up 10 units
|
||||
* repeat(10) {
|
||||
* robot.scrollUp()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override fun scrollIn(sleepDur: Long, sleepDurVariance: Long) {
|
||||
robot.mouseWheel(-1)
|
||||
sleepWithVariance(sleepDur, sleepDurVariance)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,14 +1,6 @@
|
||||
import java.awt.Point
|
||||
import game_logic.runescape.RunescapeRoutines
|
||||
|
||||
fun main() {
|
||||
val agent = RSOrchestrator.getInstance()
|
||||
val p = agent.getBankPoint()
|
||||
repeat(25){
|
||||
// val newPoint = agent.automaton.getAlmostPoint(p, WiggleParams(10, 10))
|
||||
val newPoint = p
|
||||
println("Moving mouse to $newPoint")
|
||||
agent.automaton.moveMouse(newPoint)
|
||||
agent.automaton.sleep(500)
|
||||
}
|
||||
RunescapeRoutines.fullRunIncense(0, 500, 500, 500)
|
||||
}
|
||||
|
||||
|
||||
@ -1,157 +0,0 @@
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
* Interface for common task parameters used across automation routines.
|
||||
*
|
||||
* This defines standard fields needed by most routines like total volume,
|
||||
* volume per step, and the Agent instance.
|
||||
*
|
||||
* @property totalVolume The total number of items to process in the routine.
|
||||
* @property volumePerStep The volume of items to process per step.
|
||||
* @property agent The Agent instance that will run the routine.
|
||||
*/
|
||||
interface TaskParams {
|
||||
val totalVolume: Int
|
||||
val volumePerStep: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for bank related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve banking items will need bank specific
|
||||
* configuration like location and preset hotkeys.
|
||||
*
|
||||
* This interface encapsulates those common bank parameters. Classes
|
||||
* that represent task params should implement this if banking is required.
|
||||
*
|
||||
* @property bankPoint The Point location of the bank to use.
|
||||
* @property bankPresetHotkey The bank preset hotkey to withdraw/deposit items.
|
||||
*/
|
||||
interface BankParams {
|
||||
val bankPoint: Point
|
||||
val bankPresetHotkey: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for crafting related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve a crafting action like fletching, cooking, etc will
|
||||
* need crafting specific configuration like hotkeys and timing.
|
||||
*
|
||||
* This interface encapsulates those common crafting parameters. Classes
|
||||
* that represent task params should implement this if they involve crafting.
|
||||
*
|
||||
* @property craftingDialogHotkey The hotkey used to open the crafting dialog.
|
||||
* @property craftingWaitDurationMillis Base time in ms to wait after crafting.
|
||||
* @property craftingWaitDurationVarianceMillis Random variance added to wait.
|
||||
*/
|
||||
interface CraftingParams {
|
||||
val craftingDialogHotkey: Int
|
||||
val craftingWaitDurationMillis: Long
|
||||
val craftingWaitDurationVarianceMillis: Long
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for travel related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve traveling between a bank and activity area (e.g.
|
||||
* crafting, cooking) will need travel related configuration.
|
||||
*
|
||||
* This interface encapsulates those common travel params. Classes that
|
||||
* represent travel task params should implement this interface.
|
||||
*
|
||||
* @property travelPoint The Point destination to travel to.
|
||||
* @property travelDurationMillis The expected travel time in milliseconds.
|
||||
* @property travelDurationVarianceMillis Random variance to apply to the
|
||||
* travel time. This helps simulate human-like travel.
|
||||
*/
|
||||
interface TravelParams {
|
||||
val travelPoint: Point
|
||||
val travelDurationMillis: Long
|
||||
val travelDurationVarianceMillis: Long
|
||||
}
|
||||
|
||||
/**
|
||||
* Task parameters for routines performed while standing in one spot.
|
||||
*
|
||||
* This represents routines like fletching, cooking, etc. that are done
|
||||
* without traveling between a bank and activity area.
|
||||
*
|
||||
* @param totalVolume Total number of items to process.
|
||||
* @param volumePerStep The volume of items to process per iteration.
|
||||
* @param agent The Agent instance.
|
||||
* @param bankPoint Location of the bank.
|
||||
* @param bankPresetHotkey Bank preset hotkey to use.
|
||||
* @param craftingDialogHotkey Hotkey to open crafting dialog.
|
||||
* @param craftingWaitDurationMillis Crafting action duration.
|
||||
* @param craftingWaitDurationVarianceMillis Random variance for duration.
|
||||
*/
|
||||
data class StandingTaskParams(
|
||||
override val totalVolume: Int,
|
||||
override val volumePerStep: Int,
|
||||
override val bankPoint: Point,
|
||||
override val bankPresetHotkey: Int,
|
||||
override val craftingDialogHotkey: Int,
|
||||
override val craftingWaitDurationMillis: Long,
|
||||
override val craftingWaitDurationVarianceMillis: Long
|
||||
) : TaskParams, BankParams, CraftingParams
|
||||
|
||||
/**
|
||||
* Task parameters for routines that involve traveling.
|
||||
*
|
||||
* This encapsulates all the configuration needed for routines where the
|
||||
* player travels between a bank and activity area for crafting, cooking, etc.
|
||||
*
|
||||
* It brings together the common [TaskParams], bank [BankParams], crafting
|
||||
* [CraftingParams], and travel [TravelParams] parameters into one data class.
|
||||
*
|
||||
* @param totalVolume Total number of items to process.
|
||||
* @param volumePerStep The volume of items per crafting iteration.
|
||||
* @param agent The Agent instance.
|
||||
* @param bankPoint The bank location.
|
||||
* @param travelPoint The travel destination.
|
||||
* @param bankPresetHotkey Hotkey for bank preset.
|
||||
* @param craftingDialogHotkey Hotkey to open crafting dialog.
|
||||
* @param craftingWaitDurationMillis Base crafting action time.
|
||||
* @param craftingWaitDurationVarianceMillis Crafting time variance.
|
||||
* @param travelDurationMillis Expected travel time.
|
||||
* @param travelDurationVarianceMillis Travel time variance.
|
||||
*/
|
||||
data class TravelTaskParams(
|
||||
override val totalVolume: Int,
|
||||
override val volumePerStep: Int,
|
||||
override val bankPoint: Point,
|
||||
override val travelPoint: Point,
|
||||
override val bankPresetHotkey: Int,
|
||||
override val craftingDialogHotkey: Int = -1, //all current travel tasks click the thing that starts the crafting dialogue
|
||||
override val craftingWaitDurationMillis: Long,
|
||||
override val craftingWaitDurationVarianceMillis: Long,
|
||||
override val travelDurationMillis: Long,
|
||||
override val travelDurationVarianceMillis: Long
|
||||
) : TaskParams, BankParams, CraftingParams, TravelParams
|
||||
|
||||
/**
|
||||
* CommonVolumesPerStep provides constants for common inventory volumes used during routines.
|
||||
*/
|
||||
object CommonVolumesPerStep {
|
||||
/**
|
||||
* Full inventory volume constant.
|
||||
*/
|
||||
const val FullInventory = 28
|
||||
|
||||
/**
|
||||
* Two-reagent full inventory volume constant.
|
||||
* For example, when combining two items that fill the inventory.
|
||||
*/
|
||||
const val TwoReagentFullInventory = 14
|
||||
|
||||
/**
|
||||
* Volume for coating incense sticks with ashes.
|
||||
*/
|
||||
const val CoatingIncenseWithAsh = 26
|
||||
|
||||
/**
|
||||
* Volume for infusing incense sticks with herbs.
|
||||
*/
|
||||
const val InfusingIncenseWithHerb = 27
|
||||
}
|
||||
26
src/main/kotlin/controllers/Automaton.kt
Normal file
26
src/main/kotlin/controllers/Automaton.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package controllers
|
||||
|
||||
|
||||
/**
|
||||
* Interface for full-featured desktop automation controllers.
|
||||
*
|
||||
* Automaton combines capabilities from other interfaces to create a controller that can:
|
||||
*
|
||||
* - Get desktop and mouse state information like pointer location via [DesktopController]
|
||||
*
|
||||
* - Perform mouse and keyboard input like clicks, key presses, and scrolling via [InputController]
|
||||
*
|
||||
* - Handle timing and delays between actions using [TemporalController]
|
||||
*
|
||||
* By composing multiple capabilities, Automaton aims to provide a simple yet powerful interface for implementing
|
||||
* desktop automation routines.
|
||||
*
|
||||
* Typical usage involves:
|
||||
*
|
||||
* 1. Obtaining an Automaton instance bound to the current OS/desktop
|
||||
* 2. Calling methods like [moveMouse] and [mouseClick] to perform actions
|
||||
* 3. Using [sleep] and [sleepWithVariance] to add delays
|
||||
*
|
||||
* This interface allows the underlying OS/desktop implementation details to be abstracted and swapped as needed.
|
||||
*/
|
||||
interface Automaton : DesktopController, InputController, TemporalController
|
||||
54
src/main/kotlin/controllers/DesktopController.kt
Normal file
54
src/main/kotlin/controllers/DesktopController.kt
Normal file
@ -0,0 +1,54 @@
|
||||
package controllers
|
||||
|
||||
import params.WiggleParams
|
||||
import java.awt.MouseInfo
|
||||
import java.awt.Point
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* 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)
|
||||
val xDir = if (Random.nextDouble() > 0.5) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
val yDir = if (Random.nextDouble() > 0.5) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
return Point(point.x + (xDel * xDir), point.y + (yDel * yDir))
|
||||
}
|
||||
}
|
||||
59
src/main/kotlin/controllers/InputController.kt
Normal file
59
src/main/kotlin/controllers/InputController.kt
Normal file
@ -0,0 +1,59 @@
|
||||
package controllers
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* Performs a mousewheel 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 mousewheel scroll out motion.
|
||||
*
|
||||
* Same as [scrollIn] but moves the scroll wheel backward.
|
||||
*/
|
||||
fun scrollOut(sleepDur: Long, sleepDurVariance: Long)
|
||||
}
|
||||
@ -1,3 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import util.HelperFunctions
|
||||
import java.awt.Point
|
||||
import java.awt.event.InputEvent
|
||||
|
||||
@ -223,7 +226,7 @@ interface Orchestrator {
|
||||
*
|
||||
* @param totalVolume The total number of units that need to be processed.
|
||||
* @param volumePerStep The number of units to process per iteration.
|
||||
* @param task The function to call each iteration, passing the Orchestrator as argument.
|
||||
* @param task The function to call each iteration, passing the controllers.Orchestrator as argument.
|
||||
*/
|
||||
fun doLoop(
|
||||
totalVolume: Int,
|
||||
200
src/main/kotlin/controllers/RobotAutomaton.kt
Normal file
200
src/main/kotlin/controllers/RobotAutomaton.kt
Normal file
@ -0,0 +1,200 @@
|
||||
package controllers
|
||||
|
||||
import java.awt.Point
|
||||
import java.awt.Robot
|
||||
import java.awt.event.InputEvent
|
||||
|
||||
/**
|
||||
* Desktop automation controller using java.awt.Robot.
|
||||
*
|
||||
* This provides mouse, keyboard, and timing control capabilities by
|
||||
* wrapping the java.awt.Robot class.
|
||||
*
|
||||
* Key features:
|
||||
*
|
||||
* - Get current mouse/pointer location
|
||||
* - Move mouse and perform clicks
|
||||
* - Keyboard presses and hotkeys
|
||||
* - Scroll wheel motions
|
||||
* - Sleep/delay methods with variance
|
||||
*
|
||||
* RobotController aims to provide a simple and easy to use API for
|
||||
* automating desktop interactions and workflows.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Move mouse to 100, 200
|
||||
* robot.mouseMove(Point(100, 200))
|
||||
*
|
||||
* // Left click at current position
|
||||
* robot.click(InputEvent.BUTTON1_MASK)
|
||||
*
|
||||
* // Press A key
|
||||
* robot.keyPress(KeyEvent.VK_A)
|
||||
* ```
|
||||
*
|
||||
* @param robot The Robot instance to use. A default is created if not provided.
|
||||
*/
|
||||
open class RobotAutomaton(private val robot: Robot = Robot()) : Automaton {
|
||||
|
||||
/**
|
||||
* Moves the mouse pointer to the given [Point] coordinates.
|
||||
*
|
||||
* This will use the [Robot] API to move the mouse to the x,y position.
|
||||
* It also does validation to retry the move if ended up at incorrect location.
|
||||
*
|
||||
* Usage examples:
|
||||
*
|
||||
* ```
|
||||
* val controller = DesktopController()
|
||||
* controller.moveMouse(Point(100, 200))
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* ```
|
||||
* val target = Point(500, 300)
|
||||
* controller.moveMouse(target)
|
||||
* ```
|
||||
*
|
||||
* @param point The destination [Point] x,y coordinates to move the mouse to.
|
||||
*
|
||||
*
|
||||
|
||||
*
|
||||
*/
|
||||
override fun moveMouse(point: Point) {
|
||||
robot.mouseMove(point.x, point.y)
|
||||
|
||||
//There's a bug in OpenJDK that results in incorrect cursor position in the [Robot.mouseMove] function if using
|
||||
//a Windows Resolution scale other than 100%. As a result, we have to check that the cursor made it all the way.
|
||||
//From some anecdotal observation, it has an overshoot/decay pattern sort of like a binary search. The mouse will
|
||||
//usually be in the correct place within 2-3 loop itterations
|
||||
|
||||
repeat(10) {
|
||||
val rPoint = getPointerLocation()
|
||||
//here, we check the points and if we're good, we
|
||||
if (rPoint.x == point.x && rPoint.y == point.y) {
|
||||
return
|
||||
} else {
|
||||
robot.mouseMove(point.x, point.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a mouse click of the specified button.
|
||||
*
|
||||
* This uses the Robot to press and release the given mouse button.
|
||||
*
|
||||
* A random sleep is added in between pressing and releasing the button
|
||||
* to add variance and avoid robotic timing.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Perform left click at current mouse position
|
||||
* robot.click(InputEvent.BUTTON1_MASK)
|
||||
* ```
|
||||
*
|
||||
* @param button The button to click. Must be a valid constant like [InputEvent.BUTTON1_MASK].
|
||||
*
|
||||
* Returns immediately If button is negative. Button must be a positive integer.
|
||||
*/
|
||||
override fun mouseClick(button: Int) {
|
||||
//guardian logic
|
||||
if (button < 0) {
|
||||
return
|
||||
}
|
||||
robot.mousePress(button)
|
||||
|
||||
//we add in some random time variance here to appear less robotic
|
||||
sleepWithVariance(8, 8)
|
||||
|
||||
robot.mouseRelease(button)
|
||||
}
|
||||
|
||||
/**
|
||||
* Presses and releases the given key.
|
||||
*
|
||||
* This uses the Robot to simulate pressing and releasing the key with the given key code.
|
||||
*
|
||||
* A random sleep is added after pressing the key before releasing it to add variance
|
||||
* and avoid robotic timing.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Press the 'A' key
|
||||
* robot.keyPress(KeyEvent.VK_A)
|
||||
* ```
|
||||
*
|
||||
* @param keyCode The key code of the key to press, such as [KeyEvent.VK_A].
|
||||
*
|
||||
* Returns immediately if keyCode < 0. This can be useful for skipping actions by passing -1
|
||||
*/
|
||||
override fun keyPress(keyCode: Int) {
|
||||
//guardian logic
|
||||
if (keyCode < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
robot.keyPress(keyCode)
|
||||
|
||||
//we add in some random time variance here to appear less robotic
|
||||
sleepWithVariance(8, 8)
|
||||
|
||||
robot.keyRelease(keyCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the mouse wheel down by one unit.
|
||||
*
|
||||
* Uses the [Robot.mouseWheel] method to scroll down and then sleeps
|
||||
* for a random duration between 10-20ms to pace the scrolling.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Scroll down 5 units
|
||||
* repeat(5) {
|
||||
* robot.scrollDown()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override fun scrollOut(sleepDur: Long, sleepDurVariance: Long) {
|
||||
robot.mouseWheel(1)
|
||||
sleepWithVariance(sleepDur, sleepDurVariance)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the mouse wheel up by one unit.
|
||||
*
|
||||
* Uses the [Robot.mouseWheel] method to scroll up and then sleeps for a
|
||||
* random duration between 10-20ms to pace the scrolling.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```
|
||||
* val robot = RobotController()
|
||||
*
|
||||
* // Scroll up 10 units
|
||||
* repeat(10) {
|
||||
* robot.scrollUp()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override fun scrollIn(sleepDur: Long, sleepDurVariance: Long) {
|
||||
robot.mouseWheel(-1)
|
||||
sleepWithVariance(sleepDur, sleepDurVariance)
|
||||
}
|
||||
|
||||
}
|
||||
40
src/main/kotlin/controllers/TemporalController.kt
Normal file
40
src/main/kotlin/controllers/TemporalController.kt
Normal file
@ -0,0 +1,40 @@
|
||||
package controllers
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.random.Random
|
||||
|
||||
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 a random variance between 0 inclusive and [variance] exclusive.
|
||||
* The variance is divided in half to generate a random positive 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
|
||||
* and rolled as two separate random numbers to create a normal distribution
|
||||
*/
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1,166 +1,15 @@
|
||||
package game_logic.runescape
|
||||
|
||||
import controllers.Automaton
|
||||
import controllers.RobotAutomaton
|
||||
import params.WiggleParams
|
||||
import params.StandingTaskParams
|
||||
import params.TravelTaskParams
|
||||
import java.awt.Point
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
/**
|
||||
* Interface for a RuneScape orchestrator that can execute bot actions.
|
||||
*
|
||||
* This defines the capabilities that a RuneScape orchestrator needs to
|
||||
* coordinate and perform bot actions like banking, traveling, and crafting.
|
||||
*
|
||||
* Implementations will contain the game-specific logic to interact with the
|
||||
* RuneScape client and APIs to carry out the actions.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = StandingTaskParams(...)
|
||||
* RSOrchestrator.doStandingTask(orch, params)
|
||||
* ```
|
||||
*/
|
||||
interface RSOrchestrator : Orchestrator {
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Performs a standing crafting task loop at the bank.
|
||||
*
|
||||
* This handles a simple crafting loop where the player stands at the bank and crafts.
|
||||
*
|
||||
* It withdraws items from the bank, crafts a batch of items, deposits crafted items,
|
||||
* and repeats.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = StandingTaskParams(...)
|
||||
* RSOrchestrator.doStandingTask(orch, params)
|
||||
* ```
|
||||
*
|
||||
* @param orchestrator The [RSOrchestrator] that will execute the actions.
|
||||
* @param params The [StandingTaskParams] configuring the task details.
|
||||
* @return Unit.
|
||||
*/
|
||||
fun doStandingTask(orchestrator: RSOrchestrator, params: StandingTaskParams) {
|
||||
orchestrator.doLoop(params.totalVolume, params.volumePerStep) {
|
||||
orchestrator.processAtBank(params)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a crafting workflow loop that involves traveling between a bank and crafting station.
|
||||
*
|
||||
* This handles the overall workflow orchestration of:
|
||||
* 1. Withdrawing items from the bank.
|
||||
* 2. Traveling to the crafting station.
|
||||
* 3. Crafting items.
|
||||
* 4. Traveling back to the bank when inventory is empty.
|
||||
*
|
||||
* It will repeat this loop for the specified total volume of items to craft, doing the given volume per loop iteration.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = TravelTaskParams(...)
|
||||
* RSOrchestrator.doTravelTask(orch, params)
|
||||
* ```
|
||||
*
|
||||
* @param orchestrator The [RSOrchestrator] instance that will execute the actual actions.
|
||||
* @param params The [TravelTaskParams] configuring the crafting loop details.
|
||||
* @return Unit.
|
||||
*/
|
||||
fun doTravelTask(orchestrator: RSOrchestrator, params: TravelTaskParams) {
|
||||
orchestrator.doLoop(params.totalVolume, params.volumePerStep) {
|
||||
orchestrator.processAtStationNearBank(params)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the [RSOrchestrator].
|
||||
*
|
||||
* This provides access to the orchestrator instance that can be used to
|
||||
* coordinate bot actions.
|
||||
*
|
||||
* @return The [RSOrchestrator] instance.
|
||||
*/
|
||||
fun getInstance(): RSOrchestrator {
|
||||
return RSAgent()
|
||||
}
|
||||
} //end of companion object
|
||||
|
||||
|
||||
/**
|
||||
* Handles the crafting process when standing at the bank.
|
||||
*
|
||||
* This method orchestrates the workflow when standing at the bank:
|
||||
*
|
||||
* - Opens the bank interface by left-clicking near the provided bank point location.
|
||||
* - Withdraws the desired inventory preset using the provided hotkey.
|
||||
* - Opens the crafting interface using the provided crafting dialogue hotkey.
|
||||
* - Clicks the default "Make" hotkey to start crafting.
|
||||
* - Waits for the specified crafting duration plus random variance.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val params = StandingTaskParams(...)
|
||||
* orchestrator.processAtBank(params)
|
||||
* ```
|
||||
*
|
||||
* @param taskParams The StandingTaskParams configuring the task details like bank location, hotkeys, durations etc.
|
||||
*/
|
||||
fun processAtBank(taskParams: StandingTaskParams)
|
||||
|
||||
/**
|
||||
* Handles the crafting workflow when at a station near the bank.
|
||||
*
|
||||
* This orchestrates the steps to craft items at a station near the bank:
|
||||
*
|
||||
* - Travels from the bank to the station by left-clicking near the bank point.
|
||||
* - Waits for the randomized travel duration.
|
||||
*
|
||||
* - Withdraws the preset inventory from the bank using the hotkey.
|
||||
* - Waits for the randomized bank interaction duration.
|
||||
*
|
||||
* - Travels to the crafting station by left-clicking the station point.
|
||||
* - Waits for the randomized travel duration.
|
||||
*
|
||||
* - Opens the crafting interface using the provided hotkey.
|
||||
* - Clicks the "Make" button using the hotkey to craft items.
|
||||
* - Waits for the randomized crafting duration.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val params = TravelTaskParams(...)
|
||||
* orchestrator.processAtStationNearBank(params)
|
||||
* ```
|
||||
*
|
||||
* @param taskParams The TravelTaskParams configuring the task details like locations, durations, hotkeys etc.
|
||||
*/
|
||||
fun processAtStationNearBank(taskParams: TravelTaskParams)
|
||||
|
||||
/**
|
||||
* Gets the screen point location of the bank.
|
||||
*
|
||||
* This returns the x,y screen coordinates where the bank is located, which can be used to interact with the bank.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* val bankPoint = orchestrator.getBankLocation()
|
||||
*
|
||||
* // Left click the bank location to open the interface
|
||||
* orchestrator.moveMouseLeftClickAndSleep(bankPoint, 100)
|
||||
*
|
||||
* // Withdraw preset inventory at bank
|
||||
* orchestrator.automaton.keyPress(KeyEvent.VK_F1)
|
||||
* ```
|
||||
*
|
||||
* @return The Point representing the x,y screen coordinates of the bank location.
|
||||
*/
|
||||
fun getBankPoint(): Point
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of [RSOrchestrator] using a [RobotController].
|
||||
* Implementation of [RSOrchestrator] using a [RobotAutomaton].
|
||||
*
|
||||
* This class handles executing RuneScape automation tasks by controlling
|
||||
* the game client via image recognition and input emulation.
|
||||
@ -179,9 +28,9 @@ interface RSOrchestrator : Orchestrator {
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @param automaton The [Automaton] instance used to control the game. Defaults to [RobotController].
|
||||
* @param automaton The [Automaton] instance used to control the game. Defaults to [RobotAutomaton].
|
||||
*/
|
||||
private class RSAgent(override val automaton: Automaton = RobotController()) : RSOrchestrator {
|
||||
class RSAgent(override val automaton: Automaton = RobotAutomaton()) : RSOrchestrator {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
164
src/main/kotlin/game_logic/runescape/RSOrchestrator.kt
Normal file
164
src/main/kotlin/game_logic/runescape/RSOrchestrator.kt
Normal file
@ -0,0 +1,164 @@
|
||||
package game_logic.runescape
|
||||
|
||||
import controllers.Orchestrator
|
||||
import params.StandingTaskParams
|
||||
import params.TravelTaskParams
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
* Interface for a RuneScape orchestrator that can execute bot actions.
|
||||
*
|
||||
* This defines the capabilities that a RuneScape orchestrator needs to
|
||||
* coordinate and perform bot actions like banking, traveling, and crafting.
|
||||
*
|
||||
* Implementations will contain the game-specific logic to interact with the
|
||||
* RuneScape client and APIs to carry out the actions.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = StandingTaskParams(...)
|
||||
* RSOrchestrator.doStandingTask(orch, params)
|
||||
* ```
|
||||
*/
|
||||
interface RSOrchestrator : Orchestrator {
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Performs a standing crafting task loop at the bank.
|
||||
*
|
||||
* This handles a simple crafting loop where the player stands at the bank and crafts.
|
||||
*
|
||||
* It withdraws items from the bank, crafts a batch of items, deposits crafted items,
|
||||
* and repeats.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = StandingTaskParams(...)
|
||||
* RSOrchestrator.doStandingTask(orch, params)
|
||||
* ```
|
||||
*
|
||||
* @param orchestrator The [RSOrchestrator] that will execute the actions.
|
||||
* @param params The [StandingTaskParams] configuring the task details.
|
||||
* @return Unit.
|
||||
*/
|
||||
fun doStandingTask(orchestrator: RSOrchestrator, params: StandingTaskParams) {
|
||||
orchestrator.doLoop(params.totalVolume, params.volumePerStep) {
|
||||
orchestrator.processAtBank(params)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a crafting workflow loop that involves traveling between a bank and crafting station.
|
||||
*
|
||||
* This handles the overall workflow orchestration of:
|
||||
* 1. Withdrawing items from the bank.
|
||||
* 2. Traveling to the crafting station.
|
||||
* 3. Crafting items.
|
||||
* 4. Traveling back to the bank when inventory is empty.
|
||||
*
|
||||
* It will repeat this loop for the specified total volume of items to craft, doing the given volume per loop iteration.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* ```
|
||||
* val orch = RSOrchestrator.getInstance()
|
||||
* val params = TravelTaskParams(...)
|
||||
* RSOrchestrator.doTravelTask(orch, params)
|
||||
* ```
|
||||
*
|
||||
* @param orchestrator The [RSOrchestrator] instance that will execute the actual actions.
|
||||
* @param params The [TravelTaskParams] configuring the crafting loop details.
|
||||
* @return Unit.
|
||||
*/
|
||||
fun doTravelTask(orchestrator: RSOrchestrator, params: TravelTaskParams) {
|
||||
orchestrator.doLoop(params.totalVolume, params.volumePerStep) {
|
||||
orchestrator.processAtStationNearBank(params)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the [RSOrchestrator].
|
||||
*
|
||||
* This provides access to the orchestrator instance that can be used to
|
||||
* coordinate bot actions.
|
||||
*
|
||||
* @return The [RSOrchestrator] instance.
|
||||
*/
|
||||
fun getInstance(): RSOrchestrator {
|
||||
return RSAgent()
|
||||
}
|
||||
} //end of companion object
|
||||
|
||||
|
||||
/**
|
||||
* Handles the crafting process when standing at the bank.
|
||||
*
|
||||
* This method orchestrates the workflow when standing at the bank:
|
||||
*
|
||||
* - Opens the bank interface by left-clicking near the provided bank point location.
|
||||
* - Withdraws the desired inventory preset using the provided hotkey.
|
||||
* - Opens the crafting interface using the provided crafting dialogue hotkey.
|
||||
* - Clicks the default "Make" hotkey to start crafting.
|
||||
* - Waits for the specified crafting duration plus random variance.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val params = StandingTaskParams(...)
|
||||
* orchestrator.processAtBank(params)
|
||||
* ```
|
||||
*
|
||||
* @param taskParams The StandingTaskParams configuring the task details like bank location, hotkeys, durations etc.
|
||||
*/
|
||||
fun processAtBank(taskParams: StandingTaskParams)
|
||||
|
||||
/**
|
||||
* Handles the crafting workflow when at a station near the bank.
|
||||
*
|
||||
* This orchestrates the steps to craft items at a station near the bank:
|
||||
*
|
||||
* - Travels from the bank to the station by left-clicking near the bank point.
|
||||
* - Waits for the randomized travel duration.
|
||||
*
|
||||
* - Withdraws the preset inventory from the bank using the hotkey.
|
||||
* - Waits for the randomized bank interaction duration.
|
||||
*
|
||||
* - Travels to the crafting station by left-clicking the station point.
|
||||
* - Waits for the randomized travel duration.
|
||||
*
|
||||
* - Opens the crafting interface using the provided hotkey.
|
||||
* - Clicks the "Make" button using the hotkey to craft items.
|
||||
* - Waits for the randomized crafting duration.
|
||||
*
|
||||
* Usage example:
|
||||
* ```
|
||||
* val params = TravelTaskParams(...)
|
||||
* orchestrator.processAtStationNearBank(params)
|
||||
* ```
|
||||
*
|
||||
* @param taskParams The TravelTaskParams configuring the task details like locations, durations, hotkeys etc.
|
||||
*/
|
||||
fun processAtStationNearBank(taskParams: TravelTaskParams)
|
||||
|
||||
/**
|
||||
* Gets the screen point location of the bank.
|
||||
*
|
||||
* This returns the x,y screen coordinates where the bank is located, which can be used to interact with the bank.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* val bankPoint = orchestrator.getBankLocation()
|
||||
*
|
||||
* // Left click the bank location to open the interface
|
||||
* orchestrator.moveMouseLeftClickAndSleep(bankPoint, 100)
|
||||
*
|
||||
* // Withdraw preset inventory at bank
|
||||
* orchestrator.automaton.keyPress(KeyEvent.VK_F1)
|
||||
* ```
|
||||
*
|
||||
* @return The Point representing the x,y screen coordinates of the bank location.
|
||||
*/
|
||||
fun getBankPoint(): Point
|
||||
}
|
||||
@ -1,3 +1,7 @@
|
||||
package game_logic.runescape
|
||||
import params.StandingTaskParams
|
||||
import params.TravelTaskParams
|
||||
import util.HelperFunctions
|
||||
import java.awt.Point
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
@ -26,7 +30,7 @@ import java.awt.event.KeyEvent
|
||||
* Scripts can invoke the routines directly rather than reimplementing the
|
||||
* underlying actions. Parameters allow customizing volumes, locations etc.
|
||||
*/
|
||||
object Routines {
|
||||
object RunescapeRoutines {
|
||||
/**
|
||||
* The duration in milliseconds of one game tick.
|
||||
*
|
||||
@ -136,7 +140,7 @@ object Routines {
|
||||
fun cleanHerbs(volume: Int, agent: RSOrchestrator = RSOrchestrator.getInstance(), bankPoint: Point = agent.getBankPoint()) {
|
||||
val params = StandingTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.FullInventory,
|
||||
util.Constants.FullInventory,
|
||||
bankPoint,
|
||||
KeyEvent.VK_F1,
|
||||
KeyEvent.VK_1,
|
||||
@ -175,7 +179,7 @@ object Routines {
|
||||
fun cutIncenseSticks(volume: Int, agent: RSOrchestrator = RSOrchestrator.getInstance(), bankPoint: Point = agent.getBankPoint()) {
|
||||
val params = StandingTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.FullInventory,
|
||||
util.Constants.FullInventory,
|
||||
bankPoint,
|
||||
KeyEvent.VK_F2,
|
||||
KeyEvent.VK_2,
|
||||
@ -215,7 +219,7 @@ object Routines {
|
||||
fun coatIncenseSticks(volume: Int, agent: RSOrchestrator = RSOrchestrator.getInstance(), bankPoint: Point = agent.getBankPoint()) {
|
||||
val params = StandingTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.CoatingIncenseWithAsh,
|
||||
util.Constants.CoatingIncenseWithAsh,
|
||||
bankPoint,
|
||||
KeyEvent.VK_F3,
|
||||
KeyEvent.VK_3,
|
||||
@ -253,7 +257,7 @@ object Routines {
|
||||
fun infuseIncenseSticks(volume: Int, agent: RSOrchestrator = RSOrchestrator.getInstance(), bankPoint: Point = agent.getBankPoint()) {
|
||||
val params = StandingTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.InfusingIncenseWithHerb,
|
||||
util.Constants.InfusingIncenseWithHerb,
|
||||
bankPoint,
|
||||
KeyEvent.VK_F4,
|
||||
KeyEvent.VK_4,
|
||||
@ -292,7 +296,7 @@ object Routines {
|
||||
fun craftPotionAtBank(volume: Int, agent: RSOrchestrator = RSOrchestrator.getInstance(), bankPoint: Point = agent.getBankPoint()) {
|
||||
val params = StandingTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.FullInventory,
|
||||
util.Constants.FullInventory,
|
||||
bankPoint,
|
||||
KeyEvent.VK_F6,
|
||||
KeyEvent.VK_MINUS,
|
||||
@ -342,7 +346,7 @@ object Routines {
|
||||
val well = agent.promptUserForPoint("Put your mouse over the well...")
|
||||
val params = TravelTaskParams(
|
||||
volume,
|
||||
CommonVolumesPerStep.FullInventory,
|
||||
util.Constants.FullInventory,
|
||||
bankPoint,
|
||||
well,
|
||||
KeyEvent.VK_F6,
|
||||
20
src/main/kotlin/params/BankParams.kt
Normal file
20
src/main/kotlin/params/BankParams.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package params
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
* Interface for bank related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve banking items will need bank specific
|
||||
* configuration like location and preset hotkeys.
|
||||
*
|
||||
* This interface encapsulates those common bank parameters. Classes
|
||||
* that represent task params should implement this if banking is required.
|
||||
*
|
||||
* @property bankPoint The Point location of the bank to use.
|
||||
* @property bankPresetHotkey The bank preset hotkey to withdraw/deposit items.
|
||||
*/
|
||||
interface BankParams {
|
||||
val bankPoint: Point
|
||||
val bankPresetHotkey: Int
|
||||
}
|
||||
20
src/main/kotlin/params/CraftingParams.kt
Normal file
20
src/main/kotlin/params/CraftingParams.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package params
|
||||
|
||||
/**
|
||||
* Interface for crafting related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve a crafting action like fletching, cooking, etc will
|
||||
* need crafting specific configuration like hotkeys and timing.
|
||||
*
|
||||
* This interface encapsulates those common crafting parameters. Classes
|
||||
* that represent task params should implement this if they involve crafting.
|
||||
*
|
||||
* @property craftingDialogHotkey The hotkey used to open the crafting dialog.
|
||||
* @property craftingWaitDurationMillis Base time in ms to wait after crafting.
|
||||
* @property craftingWaitDurationVarianceMillis Random variance added to wait.
|
||||
*/
|
||||
interface CraftingParams {
|
||||
val craftingDialogHotkey: Int
|
||||
val craftingWaitDurationMillis: Long
|
||||
val craftingWaitDurationVarianceMillis: Long
|
||||
}
|
||||
29
src/main/kotlin/params/StandingTaskParams.kt
Normal file
29
src/main/kotlin/params/StandingTaskParams.kt
Normal file
@ -0,0 +1,29 @@
|
||||
package params
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
|
||||
/**
|
||||
* Task parameters for routines performed while standing in one spot.
|
||||
*
|
||||
* This represents routines like fletching, cooking, etc. that are done
|
||||
* without traveling between a bank and activity area.
|
||||
*
|
||||
* @param totalVolume Total number of items to process.
|
||||
* @param volumePerStep The volume of items to process per iteration.
|
||||
* @param agent The Agent instance.
|
||||
* @param bankPoint Location of the bank.
|
||||
* @param bankPresetHotkey Bank preset hotkey to use.
|
||||
* @param craftingDialogHotkey Hotkey to open crafting dialog.
|
||||
* @param craftingWaitDurationMillis Crafting action duration.
|
||||
* @param craftingWaitDurationVarianceMillis Random variance for duration.
|
||||
*/
|
||||
data class StandingTaskParams(
|
||||
override val totalVolume: Int,
|
||||
override val volumePerStep: Int,
|
||||
override val bankPoint: Point,
|
||||
override val bankPresetHotkey: Int,
|
||||
override val craftingDialogHotkey: Int,
|
||||
override val craftingWaitDurationMillis: Long,
|
||||
override val craftingWaitDurationVarianceMillis: Long
|
||||
) : TaskParams, BankParams, CraftingParams
|
||||
20
src/main/kotlin/params/TaskParams.kt
Normal file
20
src/main/kotlin/params/TaskParams.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package params
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
* Interface for common task parameters used across automation routines.
|
||||
*
|
||||
* This defines standard fields needed by most routines like total volume,
|
||||
* volume per step, and the Agent instance.
|
||||
*
|
||||
* @property totalVolume The total number of items to process in the routine.
|
||||
* @property volumePerStep The volume of items to process per step.
|
||||
* @property agent The Agent instance that will run the routine.
|
||||
*/
|
||||
interface TaskParams {
|
||||
val totalVolume: Int
|
||||
val volumePerStep: Int
|
||||
}
|
||||
|
||||
|
||||
23
src/main/kotlin/params/TravelParams.kt
Normal file
23
src/main/kotlin/params/TravelParams.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package params
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
* Interface for travel related parameters used in automation routines.
|
||||
*
|
||||
* Routines that involve traveling between a bank and activity area (e.g.
|
||||
* crafting, cooking) will need travel related configuration.
|
||||
*
|
||||
* This interface encapsulates those common travel params. Classes that
|
||||
* represent travel task params should implement this interface.
|
||||
*
|
||||
* @property travelPoint The Point destination to travel to.
|
||||
* @property travelDurationMillis The expected travel time in milliseconds.
|
||||
* @property travelDurationVarianceMillis Random variance to apply to the
|
||||
* travel time. This helps simulate human-like travel.
|
||||
*/
|
||||
interface TravelParams {
|
||||
val travelPoint: Point
|
||||
val travelDurationMillis: Long
|
||||
val travelDurationVarianceMillis: Long
|
||||
}
|
||||
38
src/main/kotlin/params/TravelTaskParams.kt
Normal file
38
src/main/kotlin/params/TravelTaskParams.kt
Normal file
@ -0,0 +1,38 @@
|
||||
package params
|
||||
|
||||
import java.awt.Point
|
||||
|
||||
|
||||
/**
|
||||
* Task parameters for routines that involve traveling.
|
||||
*
|
||||
* This encapsulates all the configuration needed for routines where the
|
||||
* player travels between a bank and activity area for crafting, cooking, etc.
|
||||
*
|
||||
* It brings together the common [TaskParams], bank [BankParams], crafting
|
||||
* [CraftingParams], and travel [TravelParams] parameters into one data class.
|
||||
*
|
||||
* @param totalVolume Total number of items to process.
|
||||
* @param volumePerStep The volume of items per crafting iteration.
|
||||
* @param agent The Agent instance.
|
||||
* @param bankPoint The bank location.
|
||||
* @param travelPoint The travel destination.
|
||||
* @param bankPresetHotkey Hotkey for bank preset.
|
||||
* @param craftingDialogHotkey Hotkey to open crafting dialog.
|
||||
* @param craftingWaitDurationMillis Base crafting action time.
|
||||
* @param craftingWaitDurationVarianceMillis Crafting time variance.
|
||||
* @param travelDurationMillis Expected travel time.
|
||||
* @param travelDurationVarianceMillis Travel time variance.
|
||||
*/
|
||||
data class TravelTaskParams(
|
||||
override val totalVolume: Int,
|
||||
override val volumePerStep: Int,
|
||||
override val bankPoint: Point,
|
||||
override val travelPoint: Point,
|
||||
override val bankPresetHotkey: Int,
|
||||
override val craftingDialogHotkey: Int = -1, //all current travel tasks click the thing that starts the crafting dialogue
|
||||
override val craftingWaitDurationMillis: Long,
|
||||
override val craftingWaitDurationVarianceMillis: Long,
|
||||
override val travelDurationMillis: Long,
|
||||
override val travelDurationVarianceMillis: Long
|
||||
) : TaskParams, BankParams, CraftingParams, TravelParams
|
||||
36
src/main/kotlin/params/WiggleParams.kt
Normal file
36
src/main/kotlin/params/WiggleParams.kt
Normal file
@ -0,0 +1,36 @@
|
||||
package params
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* val controller = DesktopController()
|
||||
* val wiggle = WiggleParams(xWiggle = 10, yWiggle = 15)
|
||||
*
|
||||
* val target = Point(100, 200)
|
||||
* val actual = controller.getAlmostPoint(target, wiggle) // (104, 197)
|
||||
* ```
|
||||
*
|
||||
* @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
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
24
src/main/kotlin/util/Constants.kt
Normal file
24
src/main/kotlin/util/Constants.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package util
|
||||
|
||||
object Constants {
|
||||
/**
|
||||
* Full inventory volume constant.
|
||||
*/
|
||||
const val FullInventory = 28
|
||||
|
||||
/**
|
||||
* Two-reagent full inventory volume constant.
|
||||
* For example, when combining two items that fill the inventory.
|
||||
*/
|
||||
const val TwoReagentFullInventory = 14
|
||||
|
||||
/**
|
||||
* Volume for coating incense sticks with ashes.
|
||||
*/
|
||||
const val CoatingIncenseWithAsh = 26
|
||||
|
||||
/**
|
||||
* Volume for infusing incense sticks with herbs.
|
||||
*/
|
||||
const val InfusingIncenseWithHerb = 27
|
||||
}
|
||||
@ -1,3 +1,7 @@
|
||||
package util
|
||||
|
||||
import controllers.Orchestrator
|
||||
|
||||
/**
|
||||
* A collection of helper functions for common utility tasks.
|
||||
*/
|
||||
Loading…
Reference in New Issue
Block a user