Skip to content
Merged

2.0.17 #1549

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion runelite-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<git.commit.id.abbrev>nogit</git.commit.id.abbrev>
<git.dirty>false</git.dirty>
<shade.skip>false</shade.skip>
<microbot.version>2.0.16.1</microbot.version>
<microbot.version>2.0.17</microbot.version>
<microbot.commit.sha>nogit</microbot.commit.sha>
</properties>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package net.runelite.client.plugins.microbot.util.inventory;

import java.awt.Rectangle;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.MenuAction;
import net.runelite.api.Varbits;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WidgetLoaded;
Expand All @@ -12,6 +14,8 @@
import net.runelite.client.plugins.microbot.util.Global;
import net.runelite.client.plugins.microbot.util.bank.Rs2Bank;
import net.runelite.client.plugins.microbot.util.magic.Runes;
import net.runelite.client.plugins.microbot.util.menu.NewMenuEntry;
import net.runelite.client.plugins.microbot.util.misc.Rs2UiHelper;
import net.runelite.client.plugins.microbot.util.widget.Rs2Widget;

import java.util.*;
Expand Down Expand Up @@ -42,10 +46,10 @@ public class Rs2RunePouch
};

private static final int BANK_PARENT_ID = InterfaceID.BANKSIDE;
private static final int RUNEPOUCH_ROOT_CHILD_ID = 19;
private static final int RUNEPOUCH_CLOSE_CHILD_ID = 22;
private static final int RUNEPOUCH_DEPOSIT_ALL_CHILD_ID = 20;
private static final List<Integer> RUNEPOUCH_LOADOUT_WIDGETS = Arrays.asList(28, 30, 32, 34);
private static final int RUNEPOUCH_ROOT_CHILD_ID = 19; // Validated
private static final int RUNEPOUCH_CLOSE_CHILD_ID = 22; // Validated
private static final int RUNEPOUCH_DEPOSIT_ALL_CHILD_ID = 20; // Validated
private static final List<Integer> RUNEPOUCH_LOADOUT_WIDGETS = Arrays.asList(34, 38, 41, 44, 46, 48, 50, 52, 54, 56); // New Loadout Child IDs

@Getter
private static final List<PouchSlot> slots = new ArrayList<>();
Expand Down Expand Up @@ -427,8 +431,22 @@ private static boolean coreLoad(Map<Runes, Integer> requiredRunes)

if (loadoutMap.equals(requiredRunes))
{
int widgetIndex = RUNEPOUCH_LOADOUT_WIDGETS.get(entry.getKey());
Rs2Widget.clickWidget(BANK_PARENT_ID, (widgetIndex + 1));
final int widgetIndex = RUNEPOUCH_LOADOUT_WIDGETS.get(entry.getKey());
Widget parentLoadoutWidget = Rs2Widget.getWidget(BANK_PARENT_ID, widgetIndex);
if (parentLoadoutWidget == null || parentLoadoutWidget.getStaticChildren() == null)
{
Microbot.log("Failed to find loadout widget for index: " + widgetIndex, Level.WARNING);
break;
}
Widget loadWidget = Rs2Widget.findWidget("Load", List.of(parentLoadoutWidget.getStaticChildren()));
if (loadWidget == null)
{
Microbot.log("Failed to find 'Load' child widget in loadout index: " + widgetIndex, Level.WARNING);
break;
}
Rectangle loadBounds = loadWidget.getBounds();
NewMenuEntry menuEntry = new NewMenuEntry("Load", "", 1, MenuAction.CC_OP, -1, loadWidget.getId(), false);
Microbot.doInvoke(menuEntry, loadBounds != null && Rs2UiHelper.isRectangleWithinCanvas(loadBounds) ? loadBounds : Rs2UiHelper.getDefaultRectangle());
Global.sleepUntil(() -> getRunes().entrySet().stream().allMatch(e -> requiredRunes.getOrDefault(e.getKey(), 0) <= e.getValue()));
return closeRunePouch();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,172 +3,125 @@
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.client.plugins.microbot.util.Global;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;

import static java.awt.event.KeyEvent.CHAR_UNDEFINED;
import net.runelite.client.plugins.microbot.util.math.Rs2Random;

/**
* Utility class for simulating keyboard input.
*/
public class Rs2Keyboard
{

public final class Rs2Keyboard {
/**
* Gets the current game canvas.
*
* @return the game canvas
* Private constructor to prevent instantiation.
*/
private static Canvas getCanvas()
{
return Microbot.getClient().getCanvas();
}
private Rs2Keyboard() {}

/**
* Executes a given action with the canvas temporarily made focusable if it wasn't already.
* This ensures key events are properly dispatched to the game client.
*
* @param action the code to run while the canvas is focusable
* Get the game canvas.
* @return
*/
private static void withFocusCanvas(Runnable action)
{
Canvas canvas = getCanvas();
boolean originalFocus = canvas.isFocusable();
if (!originalFocus) canvas.setFocusable(true);

try
{
action.run();
}
finally
{
if (!originalFocus) canvas.setFocusable(false);
}
}
private static Canvas canvas() { return Microbot.getClient().getCanvas(); }

/**
* Dispatches a low-level KeyEvent to the canvas after a specified delay.
*
* @param id the KeyEvent type (e.g. KEY_TYPED, KEY_PRESSED, etc.)
* @param keyCode the key code from {@link KeyEvent}
* @param keyChar the character to type, if applicable
* @param delay the delay in milliseconds before the event time is set
* Run an action with the canvas focused, restoring previous focus state afterwards.
* @param action
*/
private static void dispatchKeyEvent(int id, int keyCode, char keyChar, int delay)
{
KeyEvent event = new KeyEvent(
getCanvas(),
id,
System.currentTimeMillis() + delay,
0,
keyCode,
keyChar
);
getCanvas().dispatchEvent(event);
private static void withFocusedCanvas(Runnable action) {
Canvas c = canvas();
boolean wasFocusable = c.isFocusable();
boolean hadFocus = c.isFocusOwner();
if (!wasFocusable) c.setFocusable(true);
if (!hadFocus) c.requestFocusInWindow();
try { action.run(); }
finally {
if (!wasFocusable) c.setFocusable(false);
}
}

/**
* Types out a string character-by-character using KEY_TYPED events.
* Each character is sent with a short randomized delay and sleep between characters.
*
* @param word the string to type into the game
* Post an event to the AWT event queue.
* @param e
*/
public static void typeString(final String word)
{
withFocusCanvas(() -> {
for (char c : word.toCharArray())
{
int delay = Rs2Random.between(20, 200);
dispatchKeyEvent(KeyEvent.KEY_TYPED, KeyEvent.VK_UNDEFINED, c, delay);
Global.sleep(100, 200);
}
});
private static void post(KeyEvent e) {
// Safe from any thread; posts into AWT event queue
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
}

/**
* Simulates pressing a single character using a KEY_TYPED event.
*
* @param key the character to press
* Fire a keyboard event on the canvas.
* @param id
* @param keyCode
* @param keyChar
*/
public static void keyPress(final char key)
{
withFocusCanvas(() -> {
int delay = Rs2Random.between(20, 200);
dispatchKeyEvent(KeyEvent.KEY_TYPED, KeyEvent.VK_UNDEFINED, key, delay);
});
private static void fire(int id, int keyCode, char keyChar) {
long now = System.currentTimeMillis();
KeyEvent e = new KeyEvent(canvas(), id, now, 0, keyCode, keyChar);
if (SwingUtilities.isEventDispatchThread()) {
// Dispatch directly if on EDT
canvas().dispatchEvent(e);
} else {
post(e);
}
}

/**
* Simulates holding the Shift key using a KEY_PRESSED event.
* Type a string into the focused canvas, one character at a time.
* @param s
*/
public static void holdShift()
{
withFocusCanvas(() -> {
int delay = Rs2Random.between(20, 200);
dispatchKeyEvent(KeyEvent.KEY_PRESSED, KeyEvent.VK_SHIFT, CHAR_UNDEFINED, delay);
public static void typeString(String s) {
withFocusedCanvas(() -> {
for (char ch : s.toCharArray()) {
// For printable characters, send TYPED only
fire(KeyEvent.KEY_TYPED, KeyEvent.VK_UNDEFINED, ch);
Global.sleep(30, 80);
}
});
}

/**
* Simulates releasing the Shift key using a KEY_RELEASED event.
* Hold a key down on the focused canvas.
* @param keyCode
*/
public static void releaseShift()
{
withFocusCanvas(() -> {
int delay = Rs2Random.between(20, 200);
dispatchKeyEvent(KeyEvent.KEY_RELEASED, KeyEvent.VK_SHIFT, CHAR_UNDEFINED, delay);
});
public static void keyHold(int keyCode) {
withFocusedCanvas(() -> fire(KeyEvent.KEY_PRESSED, keyCode, KeyEvent.CHAR_UNDEFINED));
}

/**
* Simulates holding down a key using a KEY_PRESSED event.
*
* @param key the key code from {@link KeyEvent}
* Release a key on the focused canvas.
* @param keyCode
*/
public static void keyHold(int key)
{
withFocusCanvas(() ->
dispatchKeyEvent(KeyEvent.KEY_PRESSED, key, CHAR_UNDEFINED, 0)
);
public static void keyRelease(int keyCode) {
withFocusedCanvas(() -> fire(KeyEvent.KEY_RELEASED, keyCode, KeyEvent.CHAR_UNDEFINED));
}

/**
* Simulates releasing a key using a KEY_RELEASED event.
*
* @param key the key code from {@link KeyEvent}
* Press (hold and release) a key on the focused canvas.
* @param keyCode
*/
public static void keyRelease(int key)
{
withFocusCanvas(() -> {
int delay = Rs2Random.between(20, 200);
dispatchKeyEvent(KeyEvent.KEY_RELEASED, key, CHAR_UNDEFINED, delay);
public static void keyPress(int keyCode) {
withFocusedCanvas(() -> {
fire(KeyEvent.KEY_PRESSED, keyCode, KeyEvent.CHAR_UNDEFINED);
Global.sleep(20, 40); // real delay to preserve ordering
fire(KeyEvent.KEY_RELEASED, keyCode, KeyEvent.CHAR_UNDEFINED);
});
}

/**
* Simulates pressing and releasing a key in quick succession.
*
* @param key the key code from {@link KeyEvent}
* Press (hold and release) a key on the focused canvas, with a character.
*/
public static void keyPress(int key)
{
keyHold(key);
keyRelease(key);
}
public static void holdShift() { keyHold(KeyEvent.VK_SHIFT); }
public static void releaseShift() { keyRelease(KeyEvent.VK_SHIFT); }

/**
* Simulates pressing the Enter key.
* If the player is not logged in, this uses KEY_TYPED to avoid auto-login triggers.
* Press (hold and release) the Enter key on the focused canvas.
*/
public static void enter()
{
// this is to avoid automatically login with jagex account when you are on the login screen
if (!Microbot.isLoggedIn()) {
dispatchKeyEvent(KeyEvent.KEY_TYPED, KeyEvent.VK_UNDEFINED, '\n', 0);
return;
}

keyPress(KeyEvent.VK_ENTER);
public static void enter() {
withFocusedCanvas(() -> {
fire(KeyEvent.KEY_PRESSED, KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED);
Global.sleep(20, 40);
fire(KeyEvent.KEY_TYPED, KeyEvent.VK_UNDEFINED, '\n');
Global.sleep(5, 10);
fire(KeyEvent.KEY_RELEASED, KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,6 @@ public static boolean isInArea(WorldPoint... worldPoints) {
* @param range an int of range to which the boundaries will be drawn in a square,
* @return true if the player's current location is within the specified area, false otherwise
*/
@Deprecated(since = "1.5.5", forRemoval = true)
public static boolean isInArea(WorldPoint centerOfArea, int range) {
WorldPoint seCorner = new WorldPoint(centerOfArea.getX() + range, centerOfArea.getY() - range, centerOfArea.getPlane());
WorldPoint nwCorner = new WorldPoint(centerOfArea.getX() - range, centerOfArea.getY() + range, centerOfArea.getPlane());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@
3097 3508 1 3157 9818 0 Use;Clan Cup portal;27094 1
3157 9818 0 3097 3508 1 Use;Clan Cup portal;27095 1
2040 5240 0 2021 5223 0 Use;Portal;19005 1
1863 5239 0 1914 5222 0 Use;Portal;20786 1
2120 5257 0 2146 5287 0 Use;Portal;23707 1
2119 5258 0 2146 5287 0 Use;Portal;23707 1
2121 5258 0 2146 5287 0 Use;Portal;23707 1
1863 5239 0 1914 5222 0 Use;Portal;20786 2309=1 1
2120 5257 0 2146 5287 0 Use;Portal;23707 2310=1 1
2119 5258 0 2146 5287 0 Use;Portal;23707 2311=1 1
2121 5258 0 2146 5287 0 Use;Portal;23707 2312=1 1
2119 5258 0 2146 5287 0 Use;Portal;23707 1
2121 5258 0 2146 5287 0 Use;Portal;23707 1
2364 5212 0 2341 5219 0 Use;Portal;23922 1
Expand Down