Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[SmartAPI] Mouse / Camera / Webwalking API

Featured Replies

 

Ever since I've started writing scripts for Runescape (Dating back to 2009 https://villavu.com/forum/archive/index.php/t-43804.html) I wanted to write my own interaction APIs

Obviously I was just a scrub during most of my "scripting career", with little knowledge on how to write decent OOP code.

Past few years I've starting focussing more on programming eventually turning my knowledge into a job, currently I work for a telecom company as a back-end developer.

Anyway, enough gibberish, let me introduce SmartAPI

 

SmartAPI is a package that combines all common game interactions into a single package. This includes:

  • Mouse movement
  • Camera movement
  • Walking and Webwalking
  • Keyboard
  • Inventory interactions
  • Object interactions
  • Widget interactions
  • Grand Exchange
  • Banking
  • Shop interfaces
  • and much more ...

Why did I decide to create SmartAPI? I felt limited by the implementations of interactions in pretty much any client. They run on the same thread as the script logic making in difficult to write efficient yet simple code. Also I wanted to have more control on how I handle interactions.

 

Progress

10 February 2017

J17DFDA.png

  1. Most of the API's have been implemented and tested, there are still some slight issues with screen walking, but those should be easy to fix

Interaction + Walking demo:

Banking demo (Endless withdraw / deposit loop) :

19 December 2016:

  1. - Initial skeleton has been written.
  2. - Basic mouse movement / path generation is working (Whooho!)
  3. - Traces of an almost working webwalker can be found throught the code :D

[Webwalker]

 

 

[Mouse]

 

 

 

 

Edited by Abuse

  • Author

Update: Most of the API's have been implemented and tested, there are still some slight issues with screen walking, but those should be easy to fix

 

 

Demo code used for the agility script I've quickly thrown together:

package bundle.skills.agility;

import bundle.Activity;
import org.osbot.rs07.api.filter.Filter;
import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.Message;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.api.util.GraphicUtilities;
import org.osbot.rs07.input.mouse.EntityDestination;
import org.osbot.rs07.script.MethodProvider;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.utility.ConditionalSleep;
import smartapi.SmartAPI;

import java.awt.*;
import java.util.*;
import java.util.List;

public class Agility implements Activity {
    private SmartAPI smartAPI;
    private Script self;
    private List<Course> courses = new ArrayList();
    private boolean move = false;
    private Obstacle currentObstacle;
    private boolean preaimed = false;
    private State currentState = State.IDLE;
    //private Course currentCourse;

    /**
     * Constructor
     * @param self Script reference
     * @param smartAPI SmartAPI reference
     */
    public Agility(Script self, SmartAPI smartAPI) {
        this.smartAPI = smartAPI;
        this.self = self;

        /** Add courses, highest level -> lowest level */
        /** Course(name, minimum level, Obstacles  (Name, obstacle area, action, entrance, isFinished(), isDoing()) ... )*/
        courses.add(new Course("Gnome agility",
                30,
                new Obstacle("Rough wall",
                        new Area(new Position(3221, 3417, 0), new Position(3224, 3412, 0)),
                        "Climb",
                        new Position(3221, 3414, 0),
                        () -> new Area(new Position(3218, 3417, 3), new Position(3219, 3412, 3)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 828
                ),
                new Obstacle("Clothes line",
                        new Area(new Position(3212, 3415, 3), new Position(3214, 3412, 3)),
                        "Cross",
                        new Position(3214, 3414, 3),
                        () -> new Area(new Position(3206, 3416, 3), new Position(3208, 3414, 3)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 741
                ),
                new Obstacle("Gap",
                        new Area(new Position(3198, 3417, 3), new Position(3202, 3414, 3)),
                        "Leap",
                        new Position(3201, 3416, 3),
                        () -> new Area(new Position(3196, 3417, 1), new Position(3198, 3415, 1)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 2588
                ),
                new Obstacle("Wall",
                        new Area(new Position(3191, 3415, 1), new Position(3191, 3415, 1)),
                        "Balance",
                        new Position(3194, 3416, 1),
                        () -> new Area(new Position(3191, 3407, 3), new Position(3193, 3405, 3)).contains(self.myPosition()),
                        () -> new Area(new Position(3190, 3410, 3), new Position(3190, 3405, 3)).contains(self.myPosition()) || self.myPlayer().getAnimation() != -1
                ),
                new Obstacle("Gap",
                        new Area(new Position(3191, 3403, 3), new Position(3199, 3400, 3)),
                        "Leap",
                        new Position(3196, 3402, 3),
                        () -> new Area(new Position(3192, 3398, 3), new Position(3199, 3397, 3)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() != -1
                ),
                new Obstacle("Gap",
                        new Area(new Position(3208, 3402, 3), new Position(3210, 3395, 3)),
                        "Leap",
                        new Position(3208, 3400, 3),
                        () -> new Area(new Position(3217, 3401, 3), new Position(3220, 3397, 3)).contains(self.myPosition()),
                        () -> new Area(new Position(3209, 3403, 3), new Position(3217, 3396, 3)).contains(self.myPosition()) || self.myPlayer().getAnimation() == 1995 || self.myPlayer().getAnimation() == 2585 || self.myPlayer().getAnimation() == 4789 // HERE
                ),


                new Obstacle("Gap",
                        new Area(new Position(3230, 3403, 3), new Position(3234, 3398, 3)),
                        "Leap",
                        new Position(3231, 3402, 3),
                        () -> new Area(new Position(3234, 3404, 3), new Position(3236, 3401, 3)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() != -1
                ),
                new Obstacle("Ledge",
                        new Area(new Position(3236, 3409, 3), new Position(3241, 3407, 3)),
                        "Hurdle",
                        new Position(3236, 3408, 3),
                        () -> new Area(new Position(3235, 3412, 3), new Position(3236, 3409, 3)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() != -1
                ),

                new Obstacle("Edge",
                        new Area(new Position(3234, 3417, 3), new Position(3241, 3414, 3)),
                        "Jump-off",
                        new Position(3236, 3414, 3),
                        () -> new Area(new Position(3234, 3419, 0), new Position(3239, 3416, 0)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 741
                )
        ));

        courses.add(new Course("Gnome agility",
                1,
                new Obstacle("Log balance",
                        new Area(new Position(2473, 3436, 0), new Position(2475, 3435, 0)),
                        "Walk-across",
                        new Position(2474, 3436, 0),
                        () -> new Area(new Position(2471, 3429, 0), new Position(2477, 3425, 0)).contains(self.myPosition()),
                        () -> new Area(new Position(2471, 3435, 0), new Position(2477, 3430, 0)).contains(self.myPosition())
                ),
                new Obstacle("Obstacle net",
                        new Area(new Position(2470, 3426, 0), new Position(2477, 3424, 0)),
                        "Climb-over",
                        new Position(2474, 3426, 0),
                        () -> new Area(new Position(2471, 3424, 1), new Position(2476, 3422, 1)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 828
                ),
                new Obstacle("Tree branch",
                        new Area(new Position(2472, 3423, 1), new Position(2474, 3421, 1)),
                        "Climb",
                        new Position(2473, 3423, 1),
                        () -> new Area(new Position(2472, 3421, 2), new Position(2477, 3418, 2)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 828
                ),
                new Obstacle("Balancing rope",
                        new Area(new Position(2477, 3421, 2), new Position(2478, 3419, 2)),
                        "Walk-on",
                        new Position(2477, 3420, 2),
                        () -> new Area(new Position(2483, 3421, 2), new Position(2488, 3418, 2)).contains(self.myPosition()),
                        () -> new Area(new Position(2478, 3421, 2), new Position(2482, 3419, 2)).contains(self.myPosition())
                ),
                new Obstacle("Tree branch",
                        new Area(new Position(2485, 3421, 2), new Position(2487, 3419, 2)),
                        "Climb-down", new Position(2485, 3419, 2),
                        () -> new Area(new Position(2482, 3423, 0), new Position(2489, 3419, 0)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 828
                ),
                new Obstacle("Obstacle net",
                        new Area(new Position(2483, 3426, 0), new Position(2488, 3425, 0)),
                        "Climb-over",
                        new Position(2485, 3425, 0),
                        () -> new Area(new Position(2483, 3430, 0), new Position(2489, 3427, 0)).contains(self.myPosition()),
                        () -> self.myPlayer().getAnimation() == 828
                ),
                new Obstacle("Obstacle pipe",
                        new Area(new Position(2483, 3432, 0), new Position(2488, 3430, 0)),
                        "Squeeze-through", new Position(2486, 3430, 0),
                        () -> {
                            if (new Area(new Position(2482, 3439, 0), new Position(2489, 3437, 0)).contains(self.myPosition())) {
                                if (!self.myPlayer().isAnimating()) {
                                    return true;
                                } else {
                                    MethodProvider.sleep(MethodProvider.random(800, 1200));
                                    return true;
                                }
                            }
                            return false;
                        },
                        () -> (new Area(new Position(2483, 3435, 0), new Position(2488, 3432, 0)).contains(self.myPosition()) || self.myPlayer().getAnimation() == 749)
                )
        ));
    }

    /**
     * Gets appropriate course for your level
     * @return Course
     */
    private Course getCourse() {
        int agilityLevel = self.getSkills().getStatic(Skill.AGILITY);
        for (Course course : courses) {
            if (agilityLevel >= course.getLevelRequirement()) {
                return course;
            }
        }
        return null;
    }

    /**
     * Unused
     */
    private enum State {
        IDLE
    }
    

    /**
     * Are prerequisites met? 
     * Unused
     * @return
     */
    @Override
    public boolean canExecute() {
        return true;
    }

    /**
     * Return false if current action can not be interrupted
     * @return
     */
    @Override
    public boolean canIdle() {
        return true;
    }

    /**
     * Checks the position is reachable
     * @param position
     * @return
     */
    private boolean canReach(Position position) {
        return position.getZ() == self.myPosition().getZ() && smartAPI.getWalker().canReach(position);
    }


    /**
     * Returns the closest reachable and valid obstacle
     * @return
     */
    private Obstacle getClosestObstacle() {
        List<Obstacle> sortedObstacles = new ArrayList<>(getCourse().getObstacles());
        sortedObstacles.sort((left, right) -> {
            int leftDistance = left.getPosition().distance(self.myPosition());
            int rightDistance = right.getPosition().distance(self.myPosition());

            return leftDistance - rightDistance;
        });

        for (Obstacle obstacle : sortedObstacles) {
            if (canReach(obstacle.getPosition()) && getEntity(obstacle.getName(), obstacle.getArea(), false) != null) {
                return obstacle;
            }
        }

        return null;
    }

    /**
     * Returns the next possible obstacle
     * @param currentObstacle Current Obstacle
     * @param ignorePosition Should we ignore reachability
     * @return
     */
    private Obstacle getNextObstacle(Obstacle currentObstacle, boolean ignorePosition) {
        if (currentObstacle.equals(getCourse().getObstacles().get(getCourse().getObstacles().size() - 1))) {
            return getCourse().getObstacles().get(0);
        } else {
            int index = 0;
            for (Obstacle obstacle : getCourse().getObstacles()) {
                if (obstacle.equals(currentObstacle)) {
                    if (canReach(getCourse().getObstacles().get(index + 1).getPosition()) || ignorePosition) {
                        return getCourse().getObstacles().get(index + 1);
                    }
                }
                index++;
            }
        }
        return null;
    }

    /**
     * Gets entity in area, closest to mouse if prefered
     * @param name Entity name
     * @param area Entity Area
     * @param closestToMouse
     * @return
     */
    private Entity getEntity(String name, Area area, boolean closestToMouse) {
        List<RS2Object> possibilities = self.getObjects().filter((Filter<RS2Object>) object -> object != null && object.getName().equals(name) && area.contains(object));
        if (possibilities.isEmpty()) {
            return null;
        } else {
            if (closestToMouse) {
                try {
                    Point mousePosition = self.getMouse().getPosition();
                    possibilities.sort((left, right) -> {
                        double leftDistance = GraphicUtilities.getSuitablePoint(new EntityDestination(self.bot, left)).getLocation().distance(mousePosition);
                        double rightDistance = GraphicUtilities.getSuitablePoint(new EntityDestination(self.bot, right)).getLocation().distance(mousePosition);
                        return (int) (leftDistance - rightDistance);
                    });
                    return possibilities.get(0);
                } catch (Exception e) {
                    return possibilities.get(MethodProvider.random(0, possibilities.size() - 1));
                }
            } else {
                return possibilities.get(MethodProvider.random(0, possibilities.size() - 1));
            }
        }
    }

    @Override
    public int run() throws InterruptedException {
        if (currentObstacle == null) {
            currentObstacle = getClosestObstacle();
        }
        if (currentObstacle != null) {
            if (move) {
                /** We are facing the obstacle from the wrong direction */
                Position moveTo = currentObstacle.getArea().getRandomPosition();
                if (smartAPI.block(smartAPI.interact(moveTo, "Walk here"))) {
                    new ConditionalSleep(MethodProvider.random(600, 1200), 50) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return self.myPlayer().isMoving();
                        }
                    }.sleep();
                }
                move = false;
            }

            Entity obstacle = getEntity(currentObstacle.getName(), currentObstacle.getArea(), true);
            if (obstacle != null) {
                preaimed = false;
                self.log("Interacting with " + obstacle.getName());
                if (smartAPI.block(smartAPI.interact(obstacle, currentObstacle.getAction()))) {
                    /** Sleep until we are moving, interacting or failing the obstacle */
                    new ConditionalSleep(MethodProvider.random(300, 500), 50) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return self.myPlayer().isMoving() || currentObstacle.isDoing() || self.myPlayer().isHitBarVisible();
                        }
                    }.sleep();
                    /** Reinteract if previous interact failed (Game didin't register our action due to tick timing) */
                    if (!currentObstacle.isDoing()) {
                        smartAPI.block(smartAPI.interact(obstacle, currentObstacle.getAction()));
                    }

                    /** Learn preaims */
                    if (currentObstacle.getPreaim() == null) {
                        currentObstacle.setPreaim(self.getCamera().getPitchAngle(), self.getCamera().getYawAngle());
                    }
                    
                    /** Spam obstacle */
                    if (MethodProvider.random(0, 3) > 1 && (self.getSettings().isRunning() || MethodProvider.random(0, 1) == 0)) {
                        for (int i = 0; i < MethodProvider.random(1, 3); i++) {
                            smartAPI.block(smartAPI.interact(obstacle, currentObstacle.getAction()));
                            MethodProvider.sleep(MethodProvider.random(200, 400));
                        }
                    }
                    Obstacle nextObstacle = getNextObstacle(currentObstacle, true);
                    
                    /** Track next obstacle */
                    if (MethodProvider.random(0, 1) == 1) {
                        Entity nextEntity = getEntity(nextObstacle.getName(), nextObstacle.getArea(), false);
                        if (nextEntity != null) {
                            smartAPI.track(nextEntity);
                        }
                    }
                    
                    /** Forced wait Sleep */
                    new ConditionalSleep(MethodProvider.random(2000, 3000), 50) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return currentObstacle.isDoing() || self.myPlayer().isMoving() || self.myPlayer().isHitBarVisible();
                        }
                    }.sleep();

                    /** Final wait Sleep */
                    if (self.myPlayer().isMoving() && !currentObstacle.isDoing()) {
                        new ConditionalSleep(8000, 50) {
                            @Override
                            public boolean condition() throws InterruptedException {
                                return currentObstacle.isDoing() || !self.myPlayer().isMoving() || self.myPlayer().isHitBarVisible();
                            }
                        }.sleep();
                    }

                    /** Too many sleeps, i cba */
                    if (!currentObstacle.isDoing()) {
                        new ConditionalSleep(MethodProvider.random(2000, 3000), 50) {
                            @Override
                            public boolean condition() throws InterruptedException {
                                return currentObstacle.isDoing() || self.myPlayer().isHitBarVisible();
                            }
                        }.sleep();
                    }
                    
                    /** Wait until obstacle is handled */
                    if (currentObstacle.isDoing()) {
                        
                        /** Preaim next obstacle */
                        if (!preaimed && nextObstacle != null && nextObstacle.getPreaim() != null) {
                            preaimed = true;
                            smartAPI.rotateTo(nextObstacle.getPreaim()[0], nextObstacle.getPreaim()[1]);
                            if (MethodProvider.random(0, 4) == 1) {
                                for (Obstacle unlearnObstacle : getCourse().getObstacles()) {
                                    if (MethodProvider.random(0, 1) == 1) {
                                        unlearnObstacle.resetPreaim();
                                    }
                                    smartAPI.rotateTo(MethodProvider.random(22, 67), MethodProvider.random(0, 360));
                                }
                            }
                        }
                        new ConditionalSleep(10000, 50) {
                            @Override
                            public boolean condition() throws InterruptedException {
                                return !currentObstacle.isDoing() && currentObstacle.isDone() || self.myPlayer().isHitBarVisible();
                            }
                        }.sleep();
                    } else {
                        return 0;
                    }
                }
                if (!canReach(obstacle.getPosition())) {
                    currentObstacle = null;
                } else if (currentObstacle.isDone()) {
                    currentObstacle = getNextObstacle(currentObstacle, false);
                } else {
                    currentObstacle = null;
                }
            } else {
                currentObstacle = null;
            }
        } else {
            self.log("No obstacles");
            //self.getWalking().webWalk()getCourse().getObstacles().get(0).getPosition()
        }

        return 100;
    }

    /**
     * Paint status
     * @return
     */
    @Override
    public String getCurrentState() {
        return currentState.name();
    }

    /**
     * Prerequisite actions, for example buying/banking items
     * @return
     */
    @Override
    public List<Activity> getPrerequisites() {
        return Collections.emptyList();
    }

    @Override
    public void onPaint(Graphics2D g) {
        if (currentObstacle != null) {
            g.drawString("" + currentObstacle.isDoing(), 50, 200);
        }
    }

    @Override
    public void onMessage(Message message) {
        if (message.getType().equals(Message.MessageType.GAME) && message.getMessage().equals("You can not do that from here.")) {
            move = true;
        } else if (message.getType().equals(Message.MessageType.GAME) && message.getMessage().equals("I can't reach that")) {
            currentObstacle = null;
        }
    }
}

Edited by Abuse

Very sophisticated, thank you for sharing code snippets too <3

Edited by Bamboozled

  • Author

Update: Here is a demo of the Grand exchange, banking and inventory interaction API, I've written the crafting script very lousy so disregard the random pauses / script logic fails:P

And here's the code:

 

package bundle.skills.crafting;

import bundle.Activity;
import bundle.general.BuyActivity;
import bundle.general.BuyItem;
import org.osbot.rs07.api.Bank;
import org.osbot.rs07.api.ui.Message;
import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.script.MethodProvider;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.utility.ConditionalSleep;
import smartapi.SmartAPI;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Crafting implements Activity {
    private SmartAPI smartAPI;
    private Script self;
    private static int leatherId = 1741;
    private static int needleID = 1733;
    private static int threadId = 1734;
    private static int animationId = 1249;
    private long lastAnimation = 0;
    private List<CraftItem> craftItems = new ArrayList<>();
    private CraftItem currentItem = null;

    private int buyThreadAmount = MethodProvider.random(50, 150);
    private int buyLeatherAmount = MethodProvider.random(20, 80);
    private int buyNeedleAmount = MethodProvider.random(10, 20);


    public Crafting(Script self, SmartAPI smartAPI) {
        this.smartAPI = smartAPI;
        this.self = self;

        craftItems.add(new CraftItem("Leather gloves", 3, "Make All pairs of", "Gloves", 1));
        craftItems.add(new CraftItem("Leather boots", 3, "Make All pairs of", "Boots", 7));
        craftItems.add(new CraftItem("Leather cowl", 3, "Make All", "Cowl", 9));
        craftItems.add(new CraftItem("Leather vambraces", 3, "Make All pairs of", "Vambraces", 11));
        craftItems.add(new CraftItem("Leather body", 3, "Make All", "Armour", 14));
        craftItems.add(new CraftItem("Leather chaps", 3, "Make All pairs of", "Chaps", 18));
        craftItems.add(new CraftItem("Coif", 3, "Make All", "Coif", 38));

        craftItems.sort(Comparator.comparingInt(CraftItem::getLevelRequirement));
        Collections.reverse(craftItems);
    }


    private CraftItem getItem() {
        int currentLevel = self.getSkills().getStatic(Skill.CRAFTING);
        for (CraftItem item : craftItems) {
            if (item.getLevelRequirement() <= currentLevel) {
                return item;
            }
        }
        return null;
    }

    private enum State {
        WALK_TO_GE,
        BANK,
        CRAFT
    }

    private State currentState = State.CRAFT;

    @Override
    public boolean canExecute() {
        return true;
    }

    @Override
    public boolean canIdle() {
        return true;
    }

    private State getState() {
        if (!smartAPI.getGrandExchange().getArea().contains(self.myPosition())) {
            return State.WALK_TO_GE;
        } else if (!smartAPI.getInventory().contains(leatherId, needleID, threadId)) {
            return State.BANK;
        } else {
            return State.CRAFT;
        }
    }


    @Override
    public int run() throws InterruptedException {
        currentState = getState();
        if (currentItem == null) {
            currentItem = getItem();
        }
        if (System.currentTimeMillis() - lastAnimation < 3000 && smartAPI.getInventory().contains(leatherId)) {
            if (self.getDialogues().isPendingContinuation()) {
                lastAnimation = 0;
            } else if (self.myPlayer().getAnimation() == animationId) {
                lastAnimation = System.currentTimeMillis();
            }
        } else {
            switch (currentState) {
                case WALK_TO_GE:
                    self.getWalking().webWalk(smartAPI.getGrandExchange().getArea());
                    break;
                case BANK:
                    bank();
                    break;
                case CRAFT:
                    craft();
                    break;
            }
        }

        return 100;
    }

    private void bank() {
        if (smartAPI.getBank().isOpen()) {
            smartAPI.getBank().depositAllExcept(leatherId, needleID, threadId);
            if (smartAPI.getBank().setWithdrawMode(Bank.BankMode.WITHDRAW_ITEM)) {
                if (!smartAPI.getInventory().contains(needleID) || !smartAPI.getInventory().contains(threadId)) {
                    if (!smartAPI.getInventory().contains(threadId)) {
                        smartAPI.getBank().take("Thread", 0);
                    }
                    if (!smartAPI.getInventory().contains(needleID)) {
                        smartAPI.getBank().take("Needle", 0);
                    }
                    new ConditionalSleep(MethodProvider.random(4000, 8000), MethodProvider.random(50, 200)) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return smartAPI.getInventory().contains(threadId) && smartAPI.getInventory().contains(needleID);
                        }
                    }.sleep();
                }

                if (!smartAPI.getInventory().contains(leatherId) && smartAPI.getInventory().contains(threadId) && smartAPI.getInventory().contains(needleID)) {
                    smartAPI.getBank().take("Leather", 0);
                }
            }

            smartAPI.getBank().close(false);
            new ConditionalSleep(MethodProvider.random(4000, 8000), MethodProvider.random(50, 200)) {
                @Override
                public boolean condition() throws InterruptedException {
                    return smartAPI.getInventory().contains(leatherId);
                }
            }.sleep();
        } else {
            smartAPI.getBank().open();
        }
    }

    private void craft() throws InterruptedException {
        if (self.getBank().isOpen()) {
            self.getBank().close();
        }
        RS2Widget craftWidget = currentItem.getWidget(self);
        if (craftWidget != null && craftWidget.isVisible()) {
            if (smartAPI.block(smartAPI.interact(craftWidget, currentItem.getAction()))) {
                new ConditionalSleep(MethodProvider.random(2000, 4000), MethodProvider.random(50, 200)) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return self.myPlayer().getAnimation() == animationId;
                    }
                }.sleep();
            }
            if (self.myPlayer().getAnimation() == animationId) {
                lastAnimation = System.currentTimeMillis();
            }
        } else if (self.getInventory().getSelectedItemName() != null && self.getInventory().getSelectedItemName().equals("Needle")) {
            if (smartAPI.getInventory().interact(leatherId, "Use", false)) {
                new ConditionalSleep(MethodProvider.random(2000, 4000), MethodProvider.random(50, 200)) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return currentItem.getWidget(self) != null && currentItem.getWidget(self).isVisible();
                    }
                }.sleep();
            }
        } else {
            smartAPI.getInventory().interact(needleID, "Use", false);
        }
    }

    @Override
    public String getCurrentState() {
        return currentState.name();
    }

    @Override
    public List<Activity> getPrerequisites() {
        List<Activity> prerequisites = new ArrayList<>();
        if ((!smartAPI.getBank().contains("Leather") && !smartAPI.getInventory().contains("Leather")) || (!smartAPI.getBank().contains("Needle") && !smartAPI.getInventory().contains("Needle")) || (!smartAPI.getBank().contains("Thread") && !smartAPI.getInventory().contains("Thread"))) {
            BuyActivity buyActivity = new BuyActivity(self, smartAPI);
            if (!smartAPI.getBank().contains("Leather") && !smartAPI.getInventory().contains("Leather")) {
                buyActivity.addItem(new BuyItem("Leather", leatherId, buyLeatherAmount, 2));
            }
            if (!smartAPI.getBank().contains("Needle") && !smartAPI.getInventory().contains("Needle")) {
                buyActivity.addItem(new BuyItem("Needle", needleID, buyNeedleAmount, 10));
            }
            if (!smartAPI.getBank().contains("Thread") && !smartAPI.getInventory().contains("Thread")) {
                buyActivity.addItem(new BuyItem("Thread", threadId, buyThreadAmount, 10));
            }
            prerequisites.add(buyActivity);
        }
        return prerequisites;
    }

    @Override
    public void onPaint(Graphics2D g) {

    }

    @Override
    public void onMessage(Message message) {

    }
}

Edited by Abuse

  • Author

Made some more progress on the GrandExchange API today

 

 

That's crazy, good work buddy!  Going to release to the public?

Dang, nice work! Although, the mouse movements do seem a little accurate for how quickly it's traveling, not sure if it would look human after doing it for so long. Just a suggestion! Otherwise, awesome :)

God I hope you release at least the Grand Exchange stuff for public xD ours currently isnt that great

Good stuff! Will definitely be following this thread.

 

7 hours ago, whipz said:

God I hope you release at least the Grand Exchange stuff for public xD ours currently isnt that great

You might want to check this out: 

 

1 hour ago, Adept said:

Good stuff! Will definitely be following this thread.

 

You might want to check this out: 

 

Yeah I have its still not the greatest API tho 

  • Author
On 14/02/2017 at 3:06 PM, lrdblk said:

That's crazy, good work buddy!  Going to release to the public?

Thank you! Most definitely, as soon as I deem the code to be ready for public :)

22 hours ago, pnkwzrd said:

Dang, nice work! Although, the mouse movements do seem a little accurate for how quickly it's traveling, not sure if it would look human after doing it for so long. Just a suggestion! Otherwise, awesome :)

I agree, i'm not currently focussed on making it 'human like', as soon as I finish the code base I'll look into randomizing it more :)

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.