BravoTaco Posted August 26, 2019 Share Posted August 26, 2019 (edited) 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. The constructor takes the MethodProvider as a parameter. The trade() method takes a Player or a string of the players name as a parameter. The offerItem() method takes an Item or a string with the name of the item as a parameter, and the amount to offer. The offerAll() method also takes an Item or a string as the parameter. The acceptTrade() method takes a boolean value as a parameter, if True it will accept both screens, else it will only accept one. 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 August 28, 2019 by BravoTaco Fixed canceling trade to re-trade if already in a trade. 1 Quote Link to comment Share on other sites More sharing options...
Kramnik Posted August 26, 2019 Share Posted August 26, 2019 Nice, my bots trading always was atleast a little bit buggy so hope I would implement something Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted August 26, 2019 Author Share Posted August 26, 2019 2 minutes ago, Kramnik said: Nice, my bots trading always was atleast a little bit buggy so hope I would implement something 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. Quote Link to comment Share on other sites More sharing options...
Gunman Posted August 26, 2019 Share Posted August 26, 2019 I haven't had any issues using osbot trade API. Not buggy at all for me. Always seems to work without a hitch Quote Link to comment Share on other sites More sharing options...
osrsgmaster Posted August 26, 2019 Share Posted August 26, 2019 Is this for muling? Quote Link to comment Share on other sites More sharing options...
Kramnik Posted August 26, 2019 Share Posted August 26, 2019 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 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. 1 Quote Link to comment Share on other sites More sharing options...
Gunman Posted August 26, 2019 Share Posted August 26, 2019 2 hours ago, Kramnik said: It's buggy for me not because of API, but how my scripts are writen I think 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. Quote Link to comment Share on other sites More sharing options...
HeyImJamie Posted August 26, 2019 Share Posted August 26, 2019 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. Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted August 26, 2019 Author Share Posted August 26, 2019 (edited) 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 August 27, 2019 by BravoTaco Update on lag Quote Link to comment Share on other sites More sharing options...
HeyImJamie Posted August 27, 2019 Share Posted August 27, 2019 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. Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted August 27, 2019 Author Share Posted August 27, 2019 (edited) 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 August 28, 2019 by BravoTaco Quote Link to comment Share on other sites More sharing options...
danielmedvec Posted November 10, 2019 Share Posted November 10, 2019 (edited) 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 November 10, 2019 by danielmedvec Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted November 10, 2019 Author Share Posted November 10, 2019 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. 1 Quote Link to comment Share on other sites More sharing options...
danielmedvec Posted November 10, 2019 Share Posted November 10, 2019 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 . Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted November 10, 2019 Author Share Posted November 10, 2019 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; } Quote Link to comment Share on other sites More sharing options...