FrostBug Posted May 23, 2015 Share Posted May 23, 2015 (edited) This class uses the recently added instant hop feature to switch worlds. FrostHopper.java Spoiler /** * Tool for instant world hopping * * @author FrostBug */ public class FrostHopper { private final Script parent; public static enum HopMode { NONE(-1), ANY(-1), F2P(1130), P2P(1131); private final int spriteID; private HopMode(int spriteID) { this.spriteID = spriteID; } public int getSpriteID() { return this.spriteID; } } private final static int WIDGET_INDEX_ROOT = 15; private final static int WIDGET_CONTENT_ROOT = 8; private final static int WIDGET_ROOT = 69; private final static int WIDGET_SCROLL = 16; private final static int WIDGET_SCROLL_UP = 4; private final static int WIDGET_SCROLL_DOWN = 5; private final static int WIDGET_WORLD = 0; private final static int WIDGET_WORLDTYPE = 1; private final static int WIDGET_WORLDNUMBER = 2; private final static int WIDGET_PLAYERCOUNT = 4; private final static int WIDGET_WORLDACTIVITY = 5; private final static int WIDGET_OFFSET = 6; private final static int MIN_FRAME_Y = 230; private final static int MAX_FRAME_Y = 416; private final List<Integer> disabled; private HopMode hopMode; private int sourceWorld; private RS2Widget destinationWorld; private int destW; private int attempts; public FrostHopper(Script parent) { this.parent = parent; this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.attempts = 0; this.disabled = Arrays.asList(25, 29, 37, 65, 21, 49); } public void hop(HopMode hopMode) { this.hopMode = hopMode; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.destinationWorld = null; this.destW = -1; this.parent.log("[FrostHopper] Starting quickhop"); this.attempts = 0; } private void finishHop() { parent.log("[FrostHopper] Hopped successfully"); this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.destinationWorld = null; this.destW = -1; this.attempts = 0; } public boolean isHopping() { return this.hopMode != HopMode.NONE; } public int execute() throws InterruptedException { int delay = random(30, 60); if (getCurrentWorld() != getSourceWorld()) { if (destW != getCurrentWorld()) { parent.log("[FrostHopper] ERROR: Incorrect destination world. Hopping again"); this.destinationWorld = null; this.destW = -1; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.attempts = 0; } else { finishHop(); return random(4000, 5000); } } if (parent.getDialogues().isPendingOption() && (!parent.getWidgets().containingText("Switch to World " + destW).isEmpty() || !parent.getWidgets().containingText("World " + destW + " is a High Risk world!").isEmpty())){ if (parent.getDialogues().selectOption("Yes.", "Switch to the High Risk world.")) { delay = random(3000, 4000); } } else if (this.parent.getTabs().getOpen() == Tab.LOGOUT) { if (isQuickhopOpen()) { if (!parent.getWidgets().containingText("Loading...").isEmpty()) { parent.log("Loading worlds.."); return random(1000, 1500); } if (this.destinationWorld == null || attempts >= 3) { attempts = 0; RS2Widget dest = pickWorld(); if (dest != null) { parent.log("[FrostHopper] Hopping to world: " + getWorldNumber(dest)); this.destinationWorld = dest; this.destW = getWorldNumber(dest); } else { parent.log("[FrostHopper] Failed to select world"); } } else { if (isSelectable(this.destinationWorld)) { attempts = 0; parent.log("Interacting with world widget.."); Rectangle rect = this.destinationWorld.getBounds(); rect.translate(0, 2); rect.setSize((int) rect.getWidth(), (int) rect.getHeight() - 4); RectangleDestination dest = new RectangleDestination(parent.getBot(), rect); if (parent.getMouse().move(dest)) { sleep(random(100, 150)); parent.getMouse().click(false); delay = random(800, 1100); } } else { attempts++; scrollToWidget(this.destinationWorld); delay = random(200, 300); } } } else if (openQuickhop()) { delay = random(800, 1200); } } else if (this.parent.getTabs().open(Tab.LOGOUT)) { delay = random(200, 300); } return delay; } private int getWorldWidgetIndex(RS2Widget widget) { int index = 0; for (int i = 300; i < 401; i++) { RS2Widget w = parent.getWidgets().get(WIDGET_ROOT, WIDGET_INDEX_ROOT, i); if (w != null && !w.getHiddenUntilMouseOver()) { if (i == widget.getThirdLevelId()) { return index; } index++; } } return -1; } private boolean isQuickhopOpen() { return parent.getTabs().getOpen() == Tab.LOGOUT && parent.getWidgets().containingText("World Switcher").isEmpty(); } private boolean openQuickhop() { List<RS2Widget> list = parent.getWidgets().containingText("World Switcher"); if (!list.isEmpty()) { return list.get(0).interact(); } return false; } private RS2Widget pickWorld() { List<RS2Widget> list = parent.getWidgets().filter(WIDGET_ROOT, (Filter<RS2Widget>) (RS2Widget w) -> { if (!w.isThirdLevel() || w.getSecondLevelId() != WIDGET_INDEX_ROOT || w.getThirdLevelId() <= 300 || w.getThirdLevelId() > 400 || w.getHiddenUntilMouseOver()) { return false; } int worldNumber = trimWorldNumber(w.getThirdLevelId()); int index = getWorldWidgetIndex(w); RS2Widget world = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLD + (index * WIDGET_OFFSET)); RS2Widget worldType = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLDTYPE + (index * WIDGET_OFFSET)); RS2Widget worldActivity = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLDACTIVITY + (index * WIDGET_OFFSET)); RS2Widget worldCount = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_PLAYERCOUNT + (index * WIDGET_OFFSET)); String activity = worldActivity.getMessage() == null ? "" : worldActivity.getMessage().toLowerCase(); boolean accessible = world.getTextColor() != 0; boolean notOwn = (worldNumber != getCurrentWorld()); boolean correctType = this.hopMode == HopMode.ANY || (worldType.getSpriteIndex1() == this.hopMode.getSpriteID()); boolean nonPvP = (!activity.contains("pvp")); boolean restricted = disabled.contains(worldNumber); boolean deadman = (activity.contains("deadman")); boolean skill = activity.contains("king of"); boolean full = Integer.parseInt(worldCount.getMessage()) >= 1980; return accessible && notOwn && correctType && nonPvP && !deadman && !restricted && !full && !skill; }); return list.isEmpty() ? null : list.get(random(list.size())); } private int trimWorldNumber(int number) { return (number > 300) ? number - 300 : number; } private int getSourceWorld() { return trimWorldNumber(this.sourceWorld); } private int getCurrentWorld() { return trimWorldNumber(parent.getWorlds().getCurrentWorld()); } private int getWorldNumber(RS2Widget widget) { return trimWorldNumber(widget.getThirdLevelId()); } private void scrollToWidget(RS2Widget widget) { RS2Widget scroll; if (widget.getPosition().getY() < MIN_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_UP); } else if (widget.getPosition().getY() > MAX_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_DOWN); } else { parent.log("[FrostHopper] Error determining scroll requirement"); return; } if (scroll != null) { final long startTime = System.currentTimeMillis(); WidgetDestination wDest = new WidgetDestination(parent.getBot(), scroll); parent.getMouse().continualClick(wDest, new Condition() { @Override public boolean evaluate() { return isSelectable(widget) || (System.currentTimeMillis() - startTime) >= 6000; } }); } else { parent.log("[FrostHopper] Cannot find scroll button"); } } private boolean isSelectable(RS2Widget widget) { return widget.getPosition().getY() >= MIN_FRAME_Y && widget.getPosition().getY() <= MAX_FRAME_Y; } } Example usage: Spoiler private FrostHopper hopper; @Override public void onStart() throws InterruptedException { this.hopper = new FrostHopper(this); } @Override public int onLoop() throws InterruptedException { if(this.hopper.isHopping()) { return this.hopper.execute(); } if(runeOresAvailable()) { mineRuneOres(); } else { this.hopper.hop(FrostHopper.HopMode.P2P); } return 1000; } Edited September 27, 2018 by FrostBug 17 Quote Link to comment Share on other sites More sharing options...
Joseph Posted May 23, 2015 Share Posted May 23, 2015 Oh nice I like the snippet my bug friend. Life is bug, bug is life Quote Link to comment Share on other sites More sharing options...
Fruity Posted May 23, 2015 Share Posted May 23, 2015 Wew ty for the snippet Quote Link to comment Share on other sites More sharing options...
FrostBug Posted May 23, 2015 Author Share Posted May 23, 2015 Guess I should add that it will pick a random world (excluding PVP worlds) within the provided HopMode Quote Link to comment Share on other sites More sharing options...
Joseph Posted May 23, 2015 Share Posted May 23, 2015 (edited) Guess I should add that it will pick a random world (excluding PVP worlds) within the provided HopMode it was kind of a bit obv if not there would not be a point in having an enum Edited May 23, 2015 by josedpay Quote Link to comment Share on other sites More sharing options...
OSRS_____Evan Posted May 26, 2015 Share Posted May 26, 2015 Hey I keep having a problem where eventually the hopper with try to join the world I'm already in, and never moves on to try a different option. Did I implement it in my script wrong? Thanks Quote Link to comment Share on other sites More sharing options...
FrostBug Posted June 2, 2015 Author Share Posted June 2, 2015 Updated with some fixes and failsafes. Quote Link to comment Share on other sites More sharing options...
iJodix Posted June 26, 2015 Share Posted June 26, 2015 This class uses the recently added instant hop feature to switch worlds. FrostHopper.java import java.util.List; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.api.ui.Tab; import org.osbot.rs07.input.mouse.RectangleDestination; import org.osbot.rs07.input.mouse.WidgetDestination; import static org.osbot.rs07.script.MethodProvider.random; import static org.osbot.rs07.script.MethodProvider.sleep; import org.osbot.rs07.script.Script; import org.osbot.rs07.utility.Condition; /** * Tool for instant world hopping * * @author FrostBug */ public class FrostHopper { private final Script parent; public static enum HopMode { NONE(-1), ANY(-1), F2P(1130), P2P(1131); private final int spriteID; private HopMode(int spriteID) { this.spriteID = spriteID; } public int getSpriteID() { return this.spriteID; } } private final static int WIDGET_ROOT = 69; private final static int WIDGET_SCROLL_ROOT = 113; private final static int WIDGET_SCROLL_UP = 4; private final static int WIDGET_SCROLL_DOWN = 5; private final static int WIDGET_WORLDTYPE = 1; private final static int WIDGET_WORLDNUMBER = 2; private final static int WIDGET_WORLDACTIVITY = 4; private final static int MIN_FRAME_Y = 230; private final static int MAX_FRAME_Y = 416; private HopMode hopMode; private int sourceWorld; private RS2Widget destinationWorld; private int destW; private int attempts; public FrostHopper(Script parent) { this.parent = parent; this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.attempts = 0; } public void hop(HopMode hopMode) { this.hopMode = hopMode; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.destinationWorld = null; this.destW = -1; this.parent.log("[FrostHopper] Starting quickhop"); this.attempts = 0; } private void finishHop() { parent.log("[FrostHopper] Hopped successfully"); this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.destinationWorld = null; this.destW = -1; this.attempts = 0; this.parent.getGeneralUtil().hopped(); } public boolean isHopping() { return this.hopMode != HopMode.NONE; } public int execute() throws InterruptedException { int delay = random(30, 60); if (getCurrentWorld() != getSourceWorld()) { if (destW != getCurrentWorld()) { parent.log("[FrostHopper] ERROR: Incorrect destination world. Hopping again"); this.destinationWorld = null; this.destW = -1; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.attempts = 0; } else { finishHop(); return random(4000, 5000); } } if (parent.getDialogues().isPendingOption() && !parent.getWidgets().containingText("Switch to World " + destW).isEmpty()) { if (parent.getDialogues().selectOption("Yes.")) { delay = random(3000, 4000); } } else if (this.parent.getTabs().getOpen() == Tab.LOGOUT) { if (isQuickhopOpen()) { if (this.destinationWorld == null || attempts >= 3) { attempts = 0; RS2Widget dest = pickWorld(); if (dest != null) { parent.log("[FrostHopper] Hopping to world: " + getWorldNumber(dest)); this.destinationWorld = dest; this.destW = getWorldNumber(dest); } else { parent.log("[FrostHopper] Failed to select world"); } } else { if (isSelectable(this.destinationWorld)) { attempts = 0; parent.log("Interacting with world widget.."); RectangleDestination dest = new RectangleDestination(parent.getBot(), this.destinationWorld.getRectangle()); if (parent.getMouse().move(dest)) { sleep(random(100, 150)); parent.getMouse().click(false); delay = random(800, 1100); } parent.getMouse().click(false); } else { attempts++; scrollToWidget(this.destinationWorld); delay = random(200, 300); } } } else if (openQuickhop()) { delay = random(800, 1200); } } else if (this.parent.getTabs().open(Tab.LOGOUT)) { delay = random(200, 300); } return delay; } private boolean isQuickhopOpen() { return parent.getTabs().getOpen() == Tab.LOGOUT && parent.getWidgets().containingText("World Switcher").isEmpty(); } private boolean openQuickhop() { List<RS2Widget> list = parent.getWidgets().containingText("World Switcher"); if (!list.isEmpty()) { return list.get(0).interact(); } return false; } private RS2Widget pickWorld() { List<RS2Widget> list = parent.getWidgets().filter(WIDGET_ROOT, (Filter<RS2Widget>) (RS2Widget v) -> { if (v == null) { return false; } boolean secondLevel = v.isSecondLevel(); if (!secondLevel) { //parent.log("DEBUG: IFace is not 2nd level"); return false; } boolean worldNum = v.getChildWidget(WIDGET_WORLDNUMBER) != null && !v.getChildWidget(WIDGET_WORLDNUMBER).getMessage().isEmpty(); if (!worldNum) { //parent.log("DEBUG: Invalid world number"); return false; } boolean activity = v.getChildWidget(WIDGET_WORLDACTIVITY) != null; if (!activity) { //parent.log("DEBUG: Invalid activity field"); return false; } boolean pvp = v.getChildWidget(WIDGET_WORLDACTIVITY).getMessage().toLowerCase().contains("pvp"); if (pvp) { //parent.log("DEBUG: PVP world"); return false; } boolean botMonitor = 86 == getWorldNumber(v); if (botMonitor) { //parent.log("DEBUG: BotMonitor world"); return false; } boolean ownWorld = (getWorldNumber(v) == getSourceWorld()); if (ownWorld) { //parent.log("DEBUG: Own world"); return false; } boolean validMode = (this.hopMode == HopMode.ANY || isCorrectType(v)); if (!validMode) { //parent.log("DEBUG: Incorrect world type"); return false; } return true; }); //parent.log("DEBUG: ----------- WorldPick end"); return list.isEmpty() ? null : list.get(random(list.size())); } private int getSourceWorld() { return (sourceWorld > 300) ? sourceWorld - 300 : sourceWorld; } private int getCurrentWorld() { int w = parent.getWorlds().getCurrentWorld(); return (w > 300) ? w - 300 : w; } private boolean isCorrectType(RS2Widget widget) { RS2Widget type = widget.getChildWidget(WIDGET_WORLDTYPE); return type != null && type.getSpriteIndex1() == this.hopMode.getSpriteID(); } private int getWorldNumber(RS2Widget widget) { int w = Integer.parseInt(widget.getChildWidget(WIDGET_WORLDNUMBER).getMessage()); return (w > 300) ? w - 300 : w; } private void scrollToWidget(RS2Widget widget) { RS2Widget scroll; if (widget.getPosition().getY() < MIN_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL_ROOT, WIDGET_SCROLL_UP); } else if (widget.getPosition().getY() > MAX_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL_ROOT, WIDGET_SCROLL_DOWN); } else { parent.log("[FrostHopper] Error determining scroll requirement"); return; } if (scroll != null) { final long startTime = System.currentTimeMillis(); WidgetDestination wDest = new WidgetDestination(parent.getBot(), scroll); parent.getMouse().continualClick(wDest, new Condition() { @Override public boolean evaluate() { return isSelectable(widget) || (System.currentTimeMillis() - startTime) >= 6000; } }); } else { parent.log("[FrostHopper] Cannot find scroll button"); } } private boolean isSelectable(RS2Widget widget) { return widget.getPosition().getY() >= MIN_FRAME_Y && widget.getPosition().getY() <= MAX_FRAME_Y; } } Example usage: @ScriptManifest(author = "FrostBug", info = "TestScript", logo = "", name = "Test script", version = 1.0) public class TestScript extends Script { private FrostHopper hopper; @Override public void onStart() throws InterruptedException { this.hopper = new FrostHopper(this); } @Override public int onLoop() throws InterruptedException { if(this.hopper.isHopping()) { return this.hopper.execute(); } if(runeOresAvailable()) { mineRuneOres(); } else { this.hopper.hop(FrostHopper.HopMode.P2P); } return 1000; } } Sometimes can't find the destination world and pretty much the hopper dies, though, sometimes it fixes itself plsfix Quote Link to comment Share on other sites More sharing options...
FrostBug Posted June 26, 2015 Author Share Posted June 26, 2015 Sometimes can't find the destination world and pretty much the hopper dies, though, sometimes it fixes itself plsfix Lrn2 copy/paste sir Quote Link to comment Share on other sites More sharing options...
FrostBug Posted July 21, 2015 Author Share Posted July 21, 2015 Updated to work with the recent changes to the widget layout 2 Quote Link to comment Share on other sites More sharing options...
FrostBug Posted August 21, 2015 Author Share Posted August 21, 2015 Updated to avoid worlds that you do not have the total level to use 2 Quote Link to comment Share on other sites More sharing options...
Chris Posted November 8, 2015 Share Posted November 8, 2015 Updated to avoid worlds that you do not have the total level to use Can you also avoid Deadman worlds? Quote Link to comment Share on other sites More sharing options...
FrostBug Posted November 8, 2015 Author Share Posted November 8, 2015 Can you also avoid Deadman worlds? Updated to avoid deadman worlds. 2 Quote Link to comment Share on other sites More sharing options...
Joseph Posted January 17, 2016 Share Posted January 17, 2016 hat random method did you use cant seem to find one. Quote Link to comment Share on other sites More sharing options...
FrostBug Posted January 17, 2016 Author Share Posted January 17, 2016 hat random method did you use cant seem to find one. return list.isEmpty() ? null : list.get(random(list.size())); Quote Link to comment Share on other sites More sharing options...