Jump to content

Trade Handler


BravoTaco

Recommended Posts

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.
  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 2 months later...
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.

  • Heart 1
Link to comment
Share on other sites

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;
}

 

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.
Note: Your post will require moderator approval before it will be visible.

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...