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.

Trade Handler

Featured Replies

I've seen a couple threads with people having trouble with the trade api so I wrote this up to hopefully help with that. This features initiating trades, offering items, declining the trade and accepting all the way through the trade or accepting just one screen.  If you want anything added to it or find any bugs let me know, and I will try and implement/fix it quickly.

  1. The constructor takes the MethodProvider as a parameter.
  2. The trade() method takes a Player or a string of the players name as a parameter.
  3. The offerItem() method takes an Item or a string with the name of the item as a parameter, and the amount to offer.
  4. The offerAll() method also takes an Item or a string as the parameter.
  5. The acceptTrade() method takes a boolean value as a parameter, if True it will accept both screens, else it will only accept one.
  6. The declineTrade() method takes no parameters.

Example of it being used.

Spoiler

import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

@ScriptManifest(name = "TradeExample", author = "BravoTaco", version = 1.0, info = "", logo = "")
public class TradeExample extends Script {

    private Trader trader;

    @Override
    public void onStart() {
        trader = new Trader(this);
    }

    @Override
    public int onLoop() {

        if (trader.trade("BravoTaco")) {
            if (trader.offerItem("Rune scimitar", 1)) {
                if (trader.acceptTrade(true)) {
                    log("Trade completed!");
                }
            }
        }

        return random(1300, 2300);

    }

}

 

The Code.

Spoiler

import org.osbot.rs07.api.filter.Filter;
import org.osbot.rs07.api.model.Item;
import org.osbot.rs07.api.model.Player;
import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.script.MethodProvider;
import org.osbot.rs07.utility.ConditionalSleep;

public class Trader {

    private MethodProvider mp;

    private RS2Widget inTradeWidget;
    private RS2Widget amountWidget;
    private RS2Widget declineButton;
    private RS2Widget acceptButton;
    private RS2Widget acceptButtonSelected;

    public Trader(MethodProvider mp) {
        this.mp = mp;
    }

    private boolean inputXAmount(int amount) {
        new ConditionalSleep(10000, 100) {
            @Override
            public boolean condition() throws InterruptedException {
                return ((amountWidget = mp.getWidgets().get(162, 44)) != null) && amountWidget.isVisible();
            }
        }.sleep();
        if (amountWidget != null) {
            return mp.keyboard.typeString("" + amount);
        } else {
            return false;
        }
    }

    public boolean acceptTrade(boolean acceptAllScreens) {
        new ConditionalSleep(5000, 100) {
            @Override
            public boolean condition() throws InterruptedException {
                return ((acceptButton = mp.getWidgets().getWidgetContainingText("Accept")) != null) && acceptButton.isVisible();
            }
        }.sleep();
        if (acceptButton != null) {
            if (acceptButton.interact("Accept")) {
                new ConditionalSleep(10000, 100) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return ((acceptButtonSelected = mp.getWidgets().getWidgetContainingText("Waiting for other player...")) != null) && acceptButtonSelected.isVisible();
                    }
                }.sleep();
                new ConditionalSleep(100000, 1500) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return !acceptButton.isVisible() || acceptButtonSelected.getMessage().equals("");
                    }
                }.sleep();
                if (acceptButtonSelected.getMessage().equals("")) {
                    acceptTrade(acceptAllScreens);
                }
                if (acceptAllScreens) {
                    acceptTrade(true);
                }
                return true;
            }
        }
        return false;
    }

    public boolean declineTrade() {
        if ((declineButton = mp.getWidgets().getWidgetContainingText("Decline")) != null) {
            if (declineButton.interact("Decline")) {
                new ConditionalSleep(100000, 100) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return !declineButton.isVisible();
                    }
                }.sleep();
                return true;
            }
        }
        return false;
    }

    public boolean offerAll(String itemName) {
        if (mp.getWidgets().getWidgetContainingText("Trading with: ") != null) {
            return mp.getInventory().interact("Offer-All", itemName);
        }
        return false;
    }

    public boolean offerAll(Item item) {
        if (mp.getWidgets().getWidgetContainingText("Trading with: ") != null) {
            return item.interact("Offer-All");
        }
        return false;
    }

    public boolean offerItem(String itemName, int amount) {
        String amountSelection;
        if (amount == 1) {
            amountSelection = "Offer";
        } else if (amount == 5) {
            amountSelection = "Offer-5";
        } else if (amount == 10) {
            amountSelection = "Offer-10";
        } else {
            amountSelection = "Offer-X";
        }
        if (mp.getWidgets().getWidgetContainingText("Trading with: ") != null) {
            if (mp.getInventory().interact(amountSelection, itemName)) {
                if (amountSelection.equals("Offer-X")) {
                    return inputXAmount(amount);
                } else {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean offerItem(Item item, int amount) {
        if (item == null) {
            return false;
        }
        String amountSelection;
        if (amount == 1) {
            amountSelection = "Offer";
        } else if (amount == 5) {
            amountSelection = "Offer-5";
        } else if (amount == 10) {
            amountSelection = "Offer-10";
        } else {
            amountSelection = "Offer-X";
        }
        if (mp.getWidgets().getWidgetContainingText("Trading with: ") != null) {
            if (item.interact(amountSelection)) {
                if (amountSelection.equals("Offer-X")) {
                    return inputXAmount(amount);
                } else {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean trade(Player player) {
        if (player == null) {
            return false;
        }
        if (((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null) && inTradeWidget.isVisible()) {
            return true;
        }
        if (player.interact("Trade with")) {
            new ConditionalSleep(10000, 100) {
                @Override
                public boolean condition() throws InterruptedException {
                    return ((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null);
                }
            }.sleep();
            return inTradeWidget != null;
        }
        return false;
    }

    public boolean trade(String playerName) {
        Player player = mp.players.closest((Filter<Player>) player1 -> player1.getName().equals(playerName));
        if (((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null) && inTradeWidget.isVisible()) {
            return true;
        }
        if (player != null) {
            if (player.interact("Trade with")) {
                new ConditionalSleep(10000, 100) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return ((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null);
                    }
                }.sleep();
                return inTradeWidget != null;
            }
        }
        return false;
    }


}

 

 

Edited by BravoTaco
Fixed canceling trade to re-trade if already in a trade.

Nice, my bots trading always was atleast a little bit buggy so hope I would implement something :D 

  • Author
2 minutes ago, Kramnik said:

Nice, my bots trading always was atleast a little bit buggy so hope I would implement something :D 

Thanks. I haven't tested it that much, so I'm sure that there will be some edge cases I forgot to handle. Let me know how it goes.

4 hours ago, Gunman said:

I haven't had any issues using osbot trade API. Not buggy at all for me. Always seems to work without a hitch 🤷‍♀️

It's buggy for me not because of API, but how my scripts are writen I think :D But buggy part is when two bots have to trade so sometimes because of timing issues, one of them cancel trades or accept to early and etc.

2 hours ago, Kramnik said:

It's buggy for me not because of API, but how my scripts are writen I think :D But buggy part is when two bots have to trade so sometimes because of timing issues, one of them cancel trades or accept to early and etc.

Even when using conditional sleeps? If that happens that try to put another sleep before or after the conditional sleep. It's the duct tape patch I normally use when something like that happens else where till I figure out the actual issue.

Seems like this would be very reliant on every action executing successfully. If the script ever has to re-loop because of a failed action or just general rs lag, it will break.

 

  • Author
10 hours ago, HeyImJamie said:

Seems like this would be very reliant on every action executing successfully. If the script ever has to re-loop because of a failed action or just general rs lag, it will break.

 

Thanks for the feedback.

Ive had it re-loop after failing to put an item in and it did not break it. If there is a specific part of it that will break if it has to re-loop let me know.

For the lag ill have to test it once i get home by limiting bandwith for the connection lag and using low resource mode for game lag. Ill let ya know what breaks, since im pretty sure something might. 🙂

Update: I tried it out with 10 fps, 232ish ping, and mirror mode set at 1000ms reaction time. It never broke but I did notice that if you are currently in a trade and it does loop back it will exit the trade and re-trade with the person, this should be fixed now though.

Edited by BravoTaco
Update on lag

21 hours ago, BravoTaco said:

Thanks for the feedback.

Ive had it re-loop after failing to put an item in and it did not break it. If there is a specific part of it that will break if it has to re-loop let me know.

For the lag ill have to test it once i get home by limiting bandwith for the connection lag and using low resource mode for game lag. Ill let ya know what breaks, since im pretty sure something might. 🙂

Update: I tried it out with 10 fps, 232ish ping, and mirror mode set at 1000ms reaction time. It never broke but I did notice that if you are currently in a trade and it does loop back it will exit the trade and re-trade with the person, this should be fixed now though.

     if (trader.trade("BravoTaco")) {
            if (trader.offerItem("Rune scimitar", 1)) {
    public boolean trade(String playerName) {
        Player player = mp.players.closest((Filter<Player>) player1 -> player1.getName().equals(playerName));
        if (player != null) {
            if (player.interact("Trade with")) {
                new ConditionalSleep(10000, 100) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return ((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null);
                    }
                }.sleep();
                return inTradeWidget != null;
            }
        }
        return false;
    }

Seems like it would get stuck for 10 seconds trying to trade the player if the offer screen was already loaded.

  • Author
6 hours ago, HeyImJamie said:

     if (trader.trade("BravoTaco")) {
            if (trader.offerItem("Rune scimitar", 1)) {

    public boolean trade(String playerName) {
        Player player = mp.players.closest((Filter<Player>) player1 -> player1.getName().equals(playerName));
        if (player != null) {
            if (player.interact("Trade with")) {
                new ConditionalSleep(10000, 100) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return ((inTradeWidget = mp.getWidgets().getWidgetContainingText("Accept")) != null);
                    }
                }.sleep();
                return inTradeWidget != null;
            }
        }
        return false;
    }

Seems like it would get stuck for 10 seconds trying to trade the player if the offer screen was already loaded.

Yeah i had a little issue with this when i was testing it with the lag. It wouldn't get stuck when it was already open, instead it would close the trade and re-trade the person. Which should be fixed now.

Edit: Just realised i forgot to add this fix to this particular trade() method. Currently at work and my phone keeps crashing when i try to edit it. Ill fix it once i get home.

Edit For The Edit: Should be fixed now.

Edited by BravoTaco

  • 2 months later...

Is there any way to check if the player you are trading with have declined on either of the screens? :)


Atm, if a player disconnects/cancels the trade it will still count it as trade completed :/

Edited by danielmedvec

  • Author
1 hour ago, danielmedvec said:

Is there any way to check if the player you are trading with have declined on either of the screens? :)


Atm, if a player disconnects/cancels the trade it will still count it as trade completed :/

For this, check to see if the items that you are attempting to trade are in/out of the players inventory. Ill edit this to make it work in that way once i get home.

Thanks for the quick response mate.
We need to check the amount of the item in this case, because if for example we only want to trade 10 of 50 .

 

  • Author
2 hours ago, danielmedvec said:

Thanks for the quick response mate.
We need to check the amount of the item in this case, because if for example we only want to trade 10 of 50 .

 

Hopefully this works, haven't tested. Let me know if it doesn't

Spoiler

//Use this when the item to receive, is not already in the inventory.
public boolean itemReceived(String itemName, int amountToReceive) {
    Item temp;
    return (temp = mp.getInventory().getItem(itemName)) != null && temp.getAmount() == amountToReceive;
}

//Use this when the item to receive, is already in the inventory.
public boolean itemReceivedWithSameItemInInventory(String itemName, int startAmount, int amountToReceive) {
    Item temp;
    return (temp = mp.getInventory().getItem(itemName)) != null && temp.getAmount() - startAmount == amountToReceive;
}

//Use this when the item you are trading will have no left-over amounts.
public boolean itemTraded(String itemName) {
    return mp.getInventory().getItem(itemName) == null;
}

//Use this when the item you are trading will have left-over amounts.
public boolean itemTradedWithLeftOverItemAmount(String itemName, int startAmount, int amountToTrade) {
    Item temp;
    return (temp = mp.getInventory().getItem(itemName)) == null || temp.getAmount() + amountToTrade == startAmount;
}

 

Create an account or sign in to comment

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.