Jump to content
FrostBug

Quick-Hopper

Recommended Posts

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 by FrostBug
  • Like 17
Link to comment
Share on other sites

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 :doge:

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...