Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Buy OSRS Gold

Sell OSRS Gold
NeuroGenix

[SNIPPETS] Neuro's GE API

Recommended Posts

After originally posting this in the Scripting Help section I have decided it would be better suited here where there might be a larger audience to get feedback from to improve my own API and learn a thing or two in the process.

What calling the method Exchange#offer(int itemID, int price, int quantity, boolean buy) will do:

  1. If the GE is closed it will open it and continue.
  2. Search for the item to buy 1-3 chars at a time, checking each time whether or not the first 9 results contains the item, clicking it if it does.
  3. If the price is set to -1 it will use the +/-5% buttons to increase/decrease the price until it is at a price that will buy/sell instantly, otherwise it will use the custom amount interface to set the price.
  4. It will set the quantity using the 1/10/100/1000 buttons, using the custom amount interface if it accidently goes over by more than 10, otherwise it will use the -1 button to get to the correct amount if it is within 10.
  5. If it gets onto the history screen, or the wrong offer type screen, it will return to the selection screen and continue.
  6. It doesn't collect items after it has made the offer, returning true when the offer has been made. This is so that in my scripts I can be selling 9+ items, from toBuy and toSell HashMaps, in one go; only collecting when there are no more empty slots. This, in my mind, is more human-like than collecting the item straight away after each offer is made, thoughts?
  7. It will prioritise buy offers over sell overs. So if it is buying something and there are no empty slots, or offers to collect, then it will cancel a sell offer, collect it and continue now it has an empty slot. If it is a sell offer and there are no slots available it will return true. This is so that in my scripts the item is removed from the toSell HashMap so it can be put back into to bank to sell later as my script has the items it needs to continue botting. If it has a buy offer and there are no empty slots, offers to collect or sell offers to cancel it will wait until an offer had completed, collect it and continue. I should add a time-out function here, and I'm also thinking of implementing some sort of priority feature whereby it will cancel a buy offer if this new buy offer has a higher priority, should be simple enough.

It currently doesn't implement any antiban, I am hoping some of you can suggest the best way to implement that.

Below is an example of the implementation. In this example, starting with the ge closed but near it, the bot will open the ge, buy 276 impling jars instantly, wait a few seconds before collecting them and then sell them all again instantly.

All of the classes required to run this are below. I hope this can be helpful to somebody and I'm sure someone reading this can be helpful to me, thanks for reading, lemme know what you think.

Zoo Class - Example of the code working

Spoiler
package scripts.zoo;

import org.tribot.api.General;
import org.tribot.api2007.Inventory;
import org.tribot.api2007.types.RSItem;
import org.tribot.script.Script;
import org.tribot.script.ScriptManifest;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.grandexchange.Exchange;
import scripts.api.utils.helpers.InfoHelper;

@ScriptManifest(authors = { "Kyle" }, category = "Zoo", name = "Zoo")

public class Zoo extends Script {

	@Override
	public void run() {
		while(true) {
			if(Exchange.offer(11260, -1, 276, true)) {
				General.println("Successfully bought");
				General.sleep(3000);
				if(GEInterfaces.COLLECT_BTN.isVisible()) {
					if(GEInterfaces.COLLECT_BTN.get().click()) {
						General.println("Successfully collected" );
						General.sleep(3000);
						
						RSItem[] impJars = Inventory.find(InfoHelper.getItemNameFromID(11260));
						if(impJars != null && impJars.length > 0) {
							if(Exchange.offer(impJars[0].getID()-1, -1, impJars[0].getStack(), false)) {
								General.println("Successfully sold");
								General.sleep(3000);
							} else {
								General.println("Failed");
							}
						}
					}
				}
			} else {
				General.println("Failed");
				General.sleep(5000);
			}
		}
	}

}

 

Exchange Class - The main class

Spoiler
package scripts.api.utils.grandexchange;

import org.tribot.api.Clicking;
import org.tribot.api.General;
import org.tribot.api.Timing;
import org.tribot.api.input.Keyboard;
import org.tribot.api2007.Interfaces;
import org.tribot.api2007.Inventory;
import org.tribot.api2007.NPCs;
import org.tribot.api2007.types.RSInterface;
import org.tribot.api2007.types.RSItem;
import org.tribot.api2007.types.RSNPC;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.conditions.GEConditions;
import scripts.api.utils.helpers.InfoHelper;

public class Exchange {
	
	public static boolean offer(int itemID, int price, int quantity, boolean buy) {
		String name = InfoHelper.getItemNameFromID(itemID);
		if(name == null) return false;
		
		switch(getOfferState(itemID, price, quantity, buy)) {
		case GE_CLOSED:
			open();
			General.sleep(250,400);
			break;
		case HISTORY_SCREEN:
			exitHistoryScreen();
			General.sleep(250,400);
			break;
		case LOADING_SCREENS:
			General.sleep(300,600);
			break;
		case OFFER_SCREEN_ITEM_WRONG:
			handleWrongOfferItem(name, itemID, buy);
			General.sleep(250,400);
			break;
		case OFFER_SCREEN_OFFER_CORRECT:
			if(GEInterfaces.CONFIRM_NEW_OFFER.get().click())
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case OFFER_SCREEN_PRICE_WRONG:
			handleWrongOfferPrice(price, buy);
			General.sleep(600, 900);
			break;
		case OFFER_SCREEN_QUANTITY_WRONG:
			handleWrongOfferQuantity(quantity);
			General.sleep(150, 300);
			break;
		case OFFER_SCREEN_TYPE_WRONG:
			if(GEInterfaces.BACK_BTN.get().click())
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case SELECTION_SCREEN_CAN_COLLECT:
			if(GEInterfaces.COLLECT_BTN.get().click())
				Timing.waitCondition(GEConditions.hasCollected(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case SELECTION_SCREEN_CAN_MAKE_OFFER:
			handleMakingOffer(name, buy);
			General.sleep(600,1200);
			break;
		case SELECTION_SCREEN_OFFER_ACTIVE:
			return true;
		case SELECTION_SCREEN_SHOULD_CANCEL_OFFER:
			handleCancellingOffer();
			General.sleep(400,700);
			break;
		case SELECTION_SCREEN_SHOULD_RETURN_TRUE:
			return true;
		case SELECTION_SCREEN_SHOULD_WAIT:
			General.sleep(3000, 6000);
			break;
		}
		
		return offer(itemID, price, quantity, buy);
	}
	
	public static OfferState getOfferState(int itemID, int price, int quantity, boolean buy) {
		if(isOpen()) {
			//The GE is open, what window are we on?
			if(GEInterfaces.SELECTION_WINDOW.isVisible()) {
				//We are on the selection window.
				for(int i = 7; i < 15 ; i++) {
					//Do we already have an offer of this item?
					RSInterface item = Interfaces.get(465, i, 18);
					if(item != null && !item.isHidden()) {
						if(item.getComponentItem() == itemID) {
							//Yes we do, is it the right type?
							RSInterface type = Interfaces.get(465, i, 16);
							if(type != null && !type.isHidden()) {
								if(type.getText().contains("Buy")) {
									if(buy == true) {
										//Yes it is, return we have made the offer.
										return OfferState.SELECTION_SCREEN_OFFER_ACTIVE;
									}
								} else {
									if(buy == false) {
										//Yes it is, return we have made the offer.
										return OfferState.SELECTION_SCREEN_OFFER_ACTIVE;
									}
								}
							}
						}
					}
				}	
				//No we don't already have an active offer
				for(int b = 7; b < 15 ; b++) {
					//Do we have an empty offer slot?
					RSInterface type = Interfaces.get(465, b, 16);
					if(type != null && !type.isHidden()) {
						if(type.getText().contains("Empty")) {
							//Yes we do, return we can make the offer
							return OfferState.SELECTION_SCREEN_CAN_MAKE_OFFER;
						}
					}
				}
				//No we don't, do we have any offers to collect?
				if(GEInterfaces.COLLECT_BTN.isVisible()) {
					//Yes we do, return we can collect offers
					return OfferState.SELECTION_SCREEN_CAN_COLLECT;
				}
						
				//No we don't, should we cancel an offer?
				if(buy == true) {
					//Check if there is a sell offer to cancel
					for(int c = 7; c < 15 ; c++) {
						RSInterface type = Interfaces.get(465, c, 16);
						if(type != null && !type.isHidden()) {
							if(type.getText().contains("Sell")) {
								//Yes there is, return we can abort a sell offer.
								return OfferState.SELECTION_SCREEN_SHOULD_CANCEL_OFFER;
							}
						}
					}
					
					//No there isn't, we should wait because we are trying to buy something
					return OfferState.SELECTION_SCREEN_SHOULD_WAIT;
				} else {
					return OfferState.SELECTION_SCREEN_SHOULD_RETURN_TRUE;
				}
			} else if(GEInterfaces.CONFIRM_NEW_OFFER.isVisible()) {
				//We are on an offer screen, check that it is the right type
				if(GEInterfaces.BUY_WINDOW.isVisible())
					if(buy == false)
						return OfferState.OFFER_SCREEN_TYPE_WRONG;
				
				if(GEInterfaces.SELL_WINDOW.isVisible())
					if(buy == true)
						return OfferState.OFFER_SCREEN_TYPE_WRONG;
				
				//The type is correct, check if the item is correct
				if(GEInterfaces.OFFER_ITEM.get().getComponentItem() == itemID) {
					//The item is correct, check if the price is correct
					int currentPrice = InfoHelper.stringToInt(GEInterfaces.OFFER_PRICE.get().getText(), " coins",",");
					if(price == -1) {
						int avrPrice = InfoHelper.stringToInt(GEInterfaces.OFFER_AVR_PRICE.get().getText(), ",");
						if(buy == true) {
							Double targ = avrPrice * 1.2;
							int target = targ.intValue();
							if(currentPrice > target) {
								//The price is correct, check if the quantity is correct
								int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
								if(currentQuantity == quantity) {
									//The quantity is correct, return confirm offer
									return OfferState.OFFER_SCREEN_OFFER_CORRECT;
								} else {
									//No the quantity isn't correct, return quantity wrong
									return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
								}
							} else {
								//the price is wrong
								return OfferState.OFFER_SCREEN_PRICE_WRONG;
							}
						} else {
							Double targ = avrPrice * 0.67;
							int target = targ.intValue();
							if(currentPrice < target) {
								//The price is correct, check if the quantity is correct
								int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
								if(currentQuantity == quantity) {
									//The quantity is correct, return confirm offer
									return OfferState.OFFER_SCREEN_OFFER_CORRECT;
								} else {
									//No the quantity isn't correct, return quantity wrong
									return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
								}
							} else {
								//the price is wrong
								return OfferState.OFFER_SCREEN_PRICE_WRONG;
							}
						}
					} else if(currentPrice == price) {
						//The price is correct, check if the quantity is correct
						int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
						if(currentQuantity == quantity) {
							//The quantity is correct, return confirm offer
							return OfferState.OFFER_SCREEN_OFFER_CORRECT;
						} else {
							//No the quantity isn't correct, return quantity wrong
							return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
						}
					} else {
						//No the price isn't correct, return price wrong
						return OfferState.OFFER_SCREEN_PRICE_WRONG;
					}
				} else {
					//The item isn't correct
					return OfferState.OFFER_SCREEN_ITEM_WRONG;
				}
			} else if(GEInterfaces.HISTORY_WINDOW.isVisible()){
				//We are on the history screen, return on history screen
				return OfferState.HISTORY_SCREEN;
			} else {
				return OfferState.LOADING_SCREENS;
			}
		} else {
			return OfferState.GE_CLOSED;
		}
	}
	
	public static enum QuantityState {
		PLUS_1000, PLUS_100, PLUS_10, PLUS_1, CUSTOM, PLUS, MINUS, CORRECT
	}

	public static QuantityState getQuantityState(int goal, int current) {
		if(goal == current)
			return QuantityState.CORRECT;
		if(goal > current + 998)
			return QuantityState.PLUS_1000;
		if(goal > current + 98)
			return QuantityState.PLUS_100;
		if(goal > current + 9)
			return QuantityState.PLUS_10;
		if(goal > current)
			return General.random(1, 10) > 2 ? QuantityState.PLUS_1 : QuantityState.PLUS;
		if(goal + 10 < current)
			return QuantityState.CUSTOM;
		return QuantityState.MINUS;
	}
	
	public enum OfferState {
		 GE_CLOSED,
		 SELECTION_SCREEN_OFFER_ACTIVE,
		 SELECTION_SCREEN_CAN_MAKE_OFFER,
		 SELECTION_SCREEN_CAN_COLLECT,
		 SELECTION_SCREEN_SHOULD_RETURN_TRUE,
		 SELECTION_SCREEN_SHOULD_CANCEL_OFFER,
		 SELECTION_SCREEN_SHOULD_WAIT,
		 OFFER_SCREEN_TYPE_WRONG,
		 OFFER_SCREEN_ITEM_WRONG,
		 OFFER_SCREEN_PRICE_WRONG,
		 OFFER_SCREEN_QUANTITY_WRONG,
		 OFFER_SCREEN_OFFER_CORRECT,
		 HISTORY_SCREEN,
		 LOADING_SCREENS
	}
	
	public enum WindowState {
		CLOSED, SELECTION_SCREEN, BUY_SCREEN, SELL_SCREEN, HISTORY_SCREEN
	}
	
	public static WindowState getWindowState() {
		if(GEInterfaces.SELECTION_WINDOW.isVisible())
			return WindowState.SELECTION_SCREEN;
		
		if(GEInterfaces.HISTORY_WINDOW.isVisible())
			return WindowState.HISTORY_SCREEN;
		
		if(GEInterfaces.BUY_WINDOW.isVisible())
			return WindowState.BUY_SCREEN;
		
		if(GEInterfaces.SELL_WINDOW.isVisible())
			return WindowState.SELL_SCREEN;
		
		return WindowState.CLOSED;
	}
	
	public static void handleCancellingOffer() {
		for(int i = 7; i < 15 ; i++) {
			RSInterface type = Interfaces.get(465, i, 16);
			if(type != null && !type.isHidden()) {
				if(type.getText().contains("Sell")) {
					RSInterface slot = Interfaces.get(465, i, 2);
					if(slot != null && !slot.isHidden()) {
						if(slot.click("Abort offer")) {
							Timing.waitCondition(GEConditions.canCollect(), General.random(4000, 7000));
						}
					}
				}
			}
		}
	}
	
	public static void handleMakingOffer(String name, boolean buy) {
		if(buy == true) {
			for(int i = 7; i < 15 ; i++) {
				RSInterface type = Interfaces.get(465, i, 16);
				if(type != null && !type.isHidden()) {
					if(type.getText().contains("Empty")) {
						RSInterface buyBtn = Interfaces.get(465, i, 3);
						if(buyBtn != null && !buyBtn.isHidden()) {
							if(buyBtn.click()) {
								Timing.waitCondition(GEConditions.GEBuyWindowVisible(), General.random(4000, 7000));
							}
						}
					}
				}
			}
		} else {
			RSItem[] target = Inventory.find(name);
			if(target != null && target.length > 0) {
				if(target[0].click()) {
					Timing.waitCondition(GEConditions.GESellWindowVisible(), General.random(4000, 7000));
				}
			}
		}
	}
	
	public static void handleWrongOfferPrice(int price, boolean buy) {
		if(GEInterfaces.OFFER_AVR_PRICE.isVisible()) {
			if(price == -1) {
				if(buy == true) {
					GEInterfaces.PRICE_PLUS_5.get().click();
					return;
				} else {
					GEInterfaces.PRICE_MINUS_5.get().click();
					return;
				}
			}
		}
		
		if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
			Keyboard.typeSend(Integer.toString(price));
			Timing.waitCondition(GEConditions.GESearchBoxDissapeared(), General.random(4000, 7000));
			return;
		} 
		
		if(GEInterfaces.PRICE_CUSTOM.isVisible()) {
			if(GEInterfaces.PRICE_CUSTOM.get().click()) {
				Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
				return;
			}
		}
	}
	
	public static void handleWrongOfferQuantity(int quantity) {
		// quantity isn't correct
		if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
			Keyboard.typeSend(Integer.toString(quantity));
			Timing.waitCondition(GEConditions.GESearchBoxDissapeared(), General.random(4000, 7000));
			return;
		} 
		int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
		switch(getQuantityState(quantity, currentQuantity)) {
		case CORRECT:
			break;
		case CUSTOM:
			if(GEInterfaces.QUAN_CUSTOM.isVisible()) {
				GEInterfaces.QUAN_CUSTOM.get().click();
				Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
			}
			break;
		case MINUS:
			if(GEInterfaces.QUAN_MINUS.isVisible())
				GEInterfaces.QUAN_MINUS.get().click();
			break;
		case PLUS:
			if(GEInterfaces.QUAN_PLUS.isVisible())
				GEInterfaces.QUAN_PLUS.get().click();
			break;
		case PLUS_1:
			if(GEInterfaces.QUAN_PLUS_1.isVisible())
				GEInterfaces.QUAN_PLUS_1.get().click();
			break;
		case PLUS_10:
			if(GEInterfaces.QUAN_PLUS_10.isVisible())
				GEInterfaces.QUAN_PLUS_10.get().click();
			break;
		case PLUS_100:
			if(GEInterfaces.QUAN_PLUS_100.isVisible())
				GEInterfaces.QUAN_PLUS_100.get().click();
			break;
		case PLUS_1000:
			if(GEInterfaces.QUAN_PLUS_1000.isVisible())
				GEInterfaces.QUAN_PLUS_1000.get().click();
			break;
		}
	}
	
	public static void handleWrongOfferItem(String name, int itemID, boolean buy) {
		if(buy == true) {
			if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
				if(GEInterfaces.SEARCH_ITEM_RESULTS_CONTAINER.isVisible()) {
					if(hasSearchTarget(itemID)) {
						if(clickSearchTarget(itemID)) {
							General.sleep(1300, 2100);
							return;
						}
					} else {
						String alreadyTyped = GEInterfaces.SEARCH_ITEM_INPUT_TEXT.get().getText();
						String trimmed = alreadyTyped.substring(46, alreadyTyped.length()-1);
						Keyboard.typeString(InfoHelper.partNameToType(name, trimmed.replace("*", "")));
						General.sleep(600,900);
						return;
					}
					
				}
			}
			
			if(GEInterfaces.OFFER_ITEM.isVisible()) {
				if(GEInterfaces.OFFER_ITEM.get().click()) {
					Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
					return;
				}
			}
		} else {
			RSItem[] target = Inventory.find(itemID);
			if(target != null && target.length < 0) {
				if(target[0].click()) {
					General.sleep(900, 2100);
				}
			}
		}
	}
	
	public static boolean hasSearchTarget(int itemID) {
		if(GEInterfaces.SEARCH_RESULT_1.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_1.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_2.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_2.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_3.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_3.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_4.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_4.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_5.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_5.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_6.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_6.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_7.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_7.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_8.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_8.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_9.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_9.get().getComponentItem() == itemID) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean clickSearchTarget(int itemID) {
		if(GEInterfaces.SEARCH_RESULT_1.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_1.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_1.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_2.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_2.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_2.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_3.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_3.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_3.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_4.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_4.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_4.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_5.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_5.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_5.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_6.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_6.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_6.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_7.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_7.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_7.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_8.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_8.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_8.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_9.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_9.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_9.get().click();
			}
		}
		return false;
	}
	
	public static void exitHistoryScreen() {
		if(GEInterfaces.EXCHANGE_BTN.isVisible()) {
			if(GEInterfaces.EXCHANGE_BTN.get().click()) {
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			}
		}
	}
	
	public static boolean isOpen() {
		return GEInterfaces.MASTER.isVisible() || GEInterfaces.HISTORY_WINDOW.isVisible();
	}
	
	public static boolean open() {
		if(isOpen()) return true;
		
		RSNPC[] geClerks = NPCs.findNearest("Grand Exchange Clerk");
		if (geClerks.length > 0)
			if(Clicking.click("Exchange Grand Exchange Clerk", geClerks[0])) 
				Timing.waitCondition(GEConditions.GEOpen(), General.random(3000, 7000));
				return isOpen();
	}

}

 

GEInterfaces Class

Spoiler
package scripts.api.data;

import org.tribot.api2007.Interfaces;
import org.tribot.api2007.types.RSInterface;

public enum GEInterfaces {

	MASTER(465), SELECTION_WINDOW(465, 7, 16), HISTORY_WINDOW(383, 3, 0), BUY_WINDOW(465, 24, 19, 1118), SELL_WINDOW(465, 24, 19, 1119),
	
	SLOT(465, 7), SLOT_ACTIVE(465, 7, 2), SLOT_TYPE(465, 7, 16), SLOT_ITEM(465, 7, 18), SLOT_NAME(465, 7, 19), 
	SLOT_PROGRESS_WIDTH(465, 7, 22), SLOT_PRICE(465, 7, 25), SLOT_BUY_BTN(465, 7, 3), SLOT_SELL_BTN(465, 7, 4),
	
	SEARCH_ITEM_RESULTS_CONTAINER(162, 46), SEARCH_ITEM_INPUT_TEXT(162, 38),
	SEARCH_RESULT_1(162, 46, 2), SEARCH_RESULT_2(162, 46, 5), SEARCH_RESULT_3(162, 46, 8), SEARCH_RESULT_4(162, 46, 11), 
	SEARCH_RESULT_5(162, 46, 14), SEARCH_RESULT_6(162, 46, 17), SEARCH_RESULT_7(162, 46, 20), SEARCH_RESULT_8(162, 46, 23),
	SEARCH_RESULT_9(162, 46, 26),
	
	OFFER_NAME(465, 24, 25), OFFER_ITEM(465, 24, 21), OFFER_PRICE(465, 24, 39), OFFER_QUANTITY(465, 24, 32), OFFER_TOTAL(465, 24, 43),
	OFFER_AVR_PRICE(465, 26),
	
	QUAN_MINUS(465, 24, 1), QUAN_PLUS(465, 24, 2), QUAN_PLUS_1(465, 24, 3), QUAN_PLUS_10(465, 24, 4), QUAN_PLUS_100(465, 24, 5),
	QUAN_PLUS_1000(465, 24, 6), QUAN_CUSTOM(465, 24, 7),
	
	PRICE_MINUS(465, 24, 8), PRICE_PLUS(465, 24, 9), PRICE_MINUS_5(465, 24, 10), PRICE_CUSTOM(465, 24, 12), PRICE_PLUS_5(465, 24, 13),
	
	CONFIRM_NEW_OFFER(465, 27), 
	
	HISTORY_BTN(465, 3), EXCHANGE_BTN(383,2), COLLECT_BTN(465, 6, 0),
	
	CLOSE_OFFER(465, 2, 11), CLOSE_HISTORY(383, 1, 11), BACK_BTN(465, 4);
	
	
	private int parent, child, component, texture;
	private int[] id;
	
	GEInterfaces(int... ids){
		this.id = ids;
		switch(id.length) {
		case 1:
			this.parent = id[0];
			break;
		case 2:
			this.parent = id[0];
			this.child = id[1];
			break;
		case 3:
			this.parent = id[0];
			this.child = id[1];
			this.component = id[2];
			break;
		case 4:
			this.parent = id[0];
			this.child = id[1];
			this.component = id[2];
			this.texture = id[3];
		}
	}
	
	public boolean isVisible() {
		switch(id.length) {
		case 1:
			return Interfaces.get(parent) != null && !Interfaces.get(parent).isHidden();
		case 2:
			return Interfaces.get(parent, child) != null && !Interfaces.get(parent, child).isHidden();
		case 3:
			return Interfaces.get(parent, child, component) != null && !Interfaces.get(parent, child, component).isHidden();
		case 4:
			return Interfaces.get(parent, child, component) != null && !Interfaces.get(parent, child, component).isHidden() && Interfaces.get(parent, child, component).getTextureID() == texture;
		}
			
		return false;
	}
	
	public int[] getID() {
		switch(id.length) {
		case 1:
			return new int[] {parent};
		case 2:
			return new int[] {parent, child};
		}
		return new int[] {parent, child, component};
	}
	
	public RSInterface get() {
		switch(id.length) {
		case 1:
			return Interfaces.get(parent);
			
		case 2:
			return Interfaces.get(parent, child);
		}
		return Interfaces.get(parent, child, component);
	}
}

 

GEConditions Class

Spoiler
package scripts.api.utils.conditions;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.grandexchange.Exchange;

public class GEConditions {

	public static Condition hasCollected() {
		return new Condition(() -> !GEInterfaces.COLLECT_BTN.isVisible());
	}
	
	public static Condition canCollect() {
		return new Condition(() -> GEInterfaces.COLLECT_BTN.isVisible());
	}
	
	public static Condition GEOpen() {
		return new Condition(() -> Exchange.isOpen());
	}
	
	public static Condition GEClosed() {
		return new Condition(() -> !Exchange.isOpen());
	}
	
	public static Condition GEBuyWindowVisible() {
		return new Condition(() -> GEInterfaces.BUY_WINDOW.isVisible());
	}
	
	public static Condition GESellWindowVisible() {
		return new Condition(() -> GEInterfaces.SELL_WINDOW.isVisible());
	}
	
	public static Condition GESelectionWindowVisible() {
		return new Condition(() -> GEInterfaces.SELECTION_WINDOW.isVisible());
	}
	
	public static Condition GESearchBoxDissapeared() {
		return new Condition(() -> !GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible());
	}
	
	public static Condition GESearchBoxAppeared() {
		return new Condition(() -> GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible());
	}
	
	private interface BooleanLambda{
        boolean active();
    }

    private static class Condition extends org.tribot.api.types.generic.Condition{
        private BooleanLambda lambda;

        public Condition(BooleanLambda lambda){
            super();
            this.lambda = lambda;
        }

        @Override
        public boolean active() {
            return lambda.active();
        }
    }
	
}

 

InfoHelper Class

Spoiler
package scripts.api.utils.helpers;

import org.tribot.api.General;
import org.tribot.api2007.types.RSItemDefinition;

public class InfoHelper {

	public static int stringToInt(String input, String... toRemove) {
		String[] forRemoving = toRemove;
		switch(forRemoving.length) {
		case 1:
			return Integer.parseInt(input.replace(forRemoving[0], ""));
		case 2:
			String first = input.replace(forRemoving[0], "");
			return Integer.parseInt(first.replace(forRemoving[1], ""));
		case 3:
			String first2 = input.replace(forRemoving[0], "");
			String second = first2.replace(forRemoving[1], "");
			return Integer.parseInt(second.replace(forRemoving[2], ""));
		default:
			return -1;
		}
	}
	
	public static String partNameToType(String fullName, String alreadyTyped) {
		String remaining = fullName.replaceFirst(alreadyTyped, "");
		return remaining.length() > 2 ? remaining.substring(0, General.random(1, 2)) : remaining;
	}
	
	public static String getItemNameFromID(int itemID){
        RSItemDefinition itemDef  = RSItemDefinition.get(itemID);
        if(itemDef !=null){
            String itemName = itemDef.getName();
            if(itemName!=null){
                return itemName;
            }
        }
        return "";
	}
	
}

 

 

  • Like 2
  • Thanks 2

Share this post


Link to post
Share on other sites
38 minutes ago, adamhackz said:

Damn looks sweet, thanks for the contribution

Thanks man, I'm glad it's appreciated :)Lemme if there's anything you'd add or change, I plan on adding a method int Exchange#getMargin(int itemID) tomorrow, and also the ability to start offers from the history screen which I envision happening after the getMargin method is called; if the margin returned meets our criteria for adding the item to our toBuy list (or toMerch list).

Share this post


Link to post
Share on other sites
On 1/28/2019 at 6:10 PM, botuser420 said:

Very nice. I'm using this now and it's working perfectly so far after updating a few interface id's 

That's awesome, great to hear! I haven't used it recently and don't actually think I fixed it myself. Getting back into it now I have more free time though. Let me know what else you change and if you have any ideas on improving it :)

Share this post


Link to post
Share on other sites
2 minutes ago, NeuroGenix said:

That's awesome, great to hear! I haven't used it recently and don't actually think I fixed it myself. Getting back into it now I have more free time though. Let me know what else you change and if you have any ideas on improving it :)

One improvement I can think of is also being able to use item names instead of ID's.

Share this post


Link to post
Share on other sites
2 minutes ago, botuser420 said:

One improvement I can think of is also being able to use item names instead of ID's.

I never did that because I found it easier to work with the ID's alone but it should be easy, by altering the constructor for this part since it works out the name straight away with the #getItemNameFromID method. Changing the "int itemID" to String itemName and then either giving it the ID or having a method that gets the ID from the name (like Inventory.Find(string name)) if it's something we're selling from the inventory or have just collected after buying.

public class Exchange {
	
	public static boolean offer(int itemID, int price, int quantity, boolean buy) {
		String name = InfoHelper.getItemNameFromID(itemID);

I'm going to re-write it soon, if I update it here I'll be sure to include a method that does it by name instead of ID. I'd also like it to buy from the history screen after checking the price, at some variable rate so sometimes it gets it from the offer screen directly.

 

Share this post


Link to post
Share on other sites
On 1/30/2019 at 5:22 PM, NeuroGenix said:

I never did that because I found it easier to work with the ID's alone but it should be easy, by altering the constructor for this part since it works out the name straight away with the #getItemNameFromID method. Changing the "int itemID" to String itemName and then either giving it the ID or having a method that gets the ID from the name (like Inventory.Find(string name)) if it's something we're selling from the inventory or have just collected after buying.

public class Exchange {
	
	public static boolean offer(int itemID, int price, int quantity, boolean buy) {
		String name = InfoHelper.getItemNameFromID(itemID);

I'm going to re-write it soon, if I update it here I'll be sure to include a method that does it by name instead of ID. I'd also like it to buy from the history screen after checking the price, at some variable rate so sometimes it gets it from the offer screen directly.

 

Thanks. I didn't look into using names yet but this is very easy to alter indeed. Since I got a PM about wich interfaces needed to be updated here is what I use: https://bitbucket.org/snippets/botuser420/bej9nx

I don't know if that is all that needed to be updated

Share this post


Link to post
Share on other sites
On 2/1/2019 at 1:20 AM, botuser420 said:

Thanks. I didn't look into using names yet but this is very easy to alter indeed. Since I got a PM about wich interfaces needed to be updated here is what I use: https://bitbucket.org/snippets/botuser420/bej9nx

I don't know if that is all that needed to be updated

Sweet I'll check it out, thank you :)

Share this post


Link to post
Share on other sites
On 9/13/2018 at 1:24 AM, NeuroGenix said:

After originally posting this in the Scripting Help section I have decided it would be better suited here where there might be a larger audience to get feedback from to improve my own API and learn a thing or two in the process.

What calling the method Exchange#offer(int itemID, int price, int quantity, boolean buy) will do:

  1. If the GE is closed it will open it and continue.
  2. Search for the item to buy 1-3 chars at a time, checking each time whether or not the first 9 results contains the item, clicking it if it does.
  3. If the price is set to -1 it will use the +/-5% buttons to increase/decrease the price until it is at a price that will buy/sell instantly, otherwise it will use the custom amount interface to set the price.
  4. It will set the quantity using the 1/10/100/1000 buttons, using the custom amount interface if it accidently goes over by more than 10, otherwise it will use the -1 button to get to the correct amount if it is within 10.
  5. If it gets onto the history screen, or the wrong offer type screen, it will return to the selection screen and continue.
  6. It doesn't collect items after it has made the offer, returning true when the offer has been made. This is so that in my scripts I can be selling 9+ items, from toBuy and toSell HashMaps, in one go; only collecting when there are no more empty slots. This, in my mind, is more human-like than collecting the item straight away after each offer is made, thoughts?
  7. It will prioritise buy offers over sell overs. So if it is buying something and there are no empty slots, or offers to collect, then it will cancel a sell offer, collect it and continue now it has an empty slot. If it is a sell offer and there are no slots available it will return true. This is so that in my scripts the item is removed from the toSell HashMap so it can be put back into to bank to sell later as my script has the items it needs to continue botting. If it has a buy offer and there are no empty slots, offers to collect or sell offers to cancel it will wait until an offer had completed, collect it and continue. I should add a time-out function here, and I'm also thinking of implementing some sort of priority feature whereby it will cancel a buy offer if this new buy offer has a higher priority, should be simple enough.

It currently doesn't implement any antiban, I am hoping some of you can suggest the best way to implement that.

Below is an example of the implementation. In this example, starting with the ge closed but near it, the bot will open the ge, buy 276 impling jars instantly, wait a few seconds before collecting them and then sell them all again instantly.

All of the classes required to run this are below. I hope this can be helpful to somebody and I'm sure someone reading this can be helpful to me, thanks for reading, lemme know what you think.

Zoo Class - Example of the code working

  Reveal hidden contents

package scripts.zoo;

import org.tribot.api.General;
import org.tribot.api2007.Inventory;
import org.tribot.api2007.types.RSItem;
import org.tribot.script.Script;
import org.tribot.script.ScriptManifest;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.grandexchange.Exchange;
import scripts.api.utils.helpers.InfoHelper;

@ScriptManifest(authors = { "Kyle" }, category = "Zoo", name = "Zoo")

public class Zoo extends Script {

	@Override
	public void run() {
		while(true) {
			if(Exchange.offer(11260, -1, 276, true)) {
				General.println("Successfully bought");
				General.sleep(3000);
				if(GEInterfaces.COLLECT_BTN.isVisible()) {
					if(GEInterfaces.COLLECT_BTN.get().click()) {
						General.println("Successfully collected" );
						General.sleep(3000);
						
						RSItem[] impJars = Inventory.find(InfoHelper.getItemNameFromID(11260));
						if(impJars != null && impJars.length > 0) {
							if(Exchange.offer(impJars[0].getID()-1, -1, impJars[0].getStack(), false)) {
								General.println("Successfully sold");
								General.sleep(3000);
							} else {
								General.println("Failed");
							}
						}
					}
				}
			} else {
				General.println("Failed");
				General.sleep(5000);
			}
		}
	}

}

 

Exchange Class - The main class

  Reveal hidden contents

package scripts.api.utils.grandexchange;

import org.tribot.api.Clicking;
import org.tribot.api.General;
import org.tribot.api.Timing;
import org.tribot.api.input.Keyboard;
import org.tribot.api2007.Interfaces;
import org.tribot.api2007.Inventory;
import org.tribot.api2007.NPCs;
import org.tribot.api2007.types.RSInterface;
import org.tribot.api2007.types.RSItem;
import org.tribot.api2007.types.RSNPC;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.conditions.GEConditions;
import scripts.api.utils.helpers.InfoHelper;

public class Exchange {
	
	public static boolean offer(int itemID, int price, int quantity, boolean buy) {
		String name = InfoHelper.getItemNameFromID(itemID);
		if(name == null) return false;
		
		switch(getOfferState(itemID, price, quantity, buy)) {
		case GE_CLOSED:
			open();
			General.sleep(250,400);
			break;
		case HISTORY_SCREEN:
			exitHistoryScreen();
			General.sleep(250,400);
			break;
		case LOADING_SCREENS:
			General.sleep(300,600);
			break;
		case OFFER_SCREEN_ITEM_WRONG:
			handleWrongOfferItem(name, itemID, buy);
			General.sleep(250,400);
			break;
		case OFFER_SCREEN_OFFER_CORRECT:
			if(GEInterfaces.CONFIRM_NEW_OFFER.get().click())
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case OFFER_SCREEN_PRICE_WRONG:
			handleWrongOfferPrice(price, buy);
			General.sleep(600, 900);
			break;
		case OFFER_SCREEN_QUANTITY_WRONG:
			handleWrongOfferQuantity(quantity);
			General.sleep(150, 300);
			break;
		case OFFER_SCREEN_TYPE_WRONG:
			if(GEInterfaces.BACK_BTN.get().click())
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case SELECTION_SCREEN_CAN_COLLECT:
			if(GEInterfaces.COLLECT_BTN.get().click())
				Timing.waitCondition(GEConditions.hasCollected(), General.random(4000, 7000));
			General.sleep(250,400);
			break;
		case SELECTION_SCREEN_CAN_MAKE_OFFER:
			handleMakingOffer(name, buy);
			General.sleep(600,1200);
			break;
		case SELECTION_SCREEN_OFFER_ACTIVE:
			return true;
		case SELECTION_SCREEN_SHOULD_CANCEL_OFFER:
			handleCancellingOffer();
			General.sleep(400,700);
			break;
		case SELECTION_SCREEN_SHOULD_RETURN_TRUE:
			return true;
		case SELECTION_SCREEN_SHOULD_WAIT:
			General.sleep(3000, 6000);
			break;
		}
		
		return offer(itemID, price, quantity, buy);
	}
	
	public static OfferState getOfferState(int itemID, int price, int quantity, boolean buy) {
		if(isOpen()) {
			//The GE is open, what window are we on?
			if(GEInterfaces.SELECTION_WINDOW.isVisible()) {
				//We are on the selection window.
				for(int i = 7; i < 15 ; i++) {
					//Do we already have an offer of this item?
					RSInterface item = Interfaces.get(465, i, 18);
					if(item != null && !item.isHidden()) {
						if(item.getComponentItem() == itemID) {
							//Yes we do, is it the right type?
							RSInterface type = Interfaces.get(465, i, 16);
							if(type != null && !type.isHidden()) {
								if(type.getText().contains("Buy")) {
									if(buy == true) {
										//Yes it is, return we have made the offer.
										return OfferState.SELECTION_SCREEN_OFFER_ACTIVE;
									}
								} else {
									if(buy == false) {
										//Yes it is, return we have made the offer.
										return OfferState.SELECTION_SCREEN_OFFER_ACTIVE;
									}
								}
							}
						}
					}
				}	
				//No we don't already have an active offer
				for(int b = 7; b < 15 ; b++) {
					//Do we have an empty offer slot?
					RSInterface type = Interfaces.get(465, b, 16);
					if(type != null && !type.isHidden()) {
						if(type.getText().contains("Empty")) {
							//Yes we do, return we can make the offer
							return OfferState.SELECTION_SCREEN_CAN_MAKE_OFFER;
						}
					}
				}
				//No we don't, do we have any offers to collect?
				if(GEInterfaces.COLLECT_BTN.isVisible()) {
					//Yes we do, return we can collect offers
					return OfferState.SELECTION_SCREEN_CAN_COLLECT;
				}
						
				//No we don't, should we cancel an offer?
				if(buy == true) {
					//Check if there is a sell offer to cancel
					for(int c = 7; c < 15 ; c++) {
						RSInterface type = Interfaces.get(465, c, 16);
						if(type != null && !type.isHidden()) {
							if(type.getText().contains("Sell")) {
								//Yes there is, return we can abort a sell offer.
								return OfferState.SELECTION_SCREEN_SHOULD_CANCEL_OFFER;
							}
						}
					}
					
					//No there isn't, we should wait because we are trying to buy something
					return OfferState.SELECTION_SCREEN_SHOULD_WAIT;
				} else {
					return OfferState.SELECTION_SCREEN_SHOULD_RETURN_TRUE;
				}
			} else if(GEInterfaces.CONFIRM_NEW_OFFER.isVisible()) {
				//We are on an offer screen, check that it is the right type
				if(GEInterfaces.BUY_WINDOW.isVisible())
					if(buy == false)
						return OfferState.OFFER_SCREEN_TYPE_WRONG;
				
				if(GEInterfaces.SELL_WINDOW.isVisible())
					if(buy == true)
						return OfferState.OFFER_SCREEN_TYPE_WRONG;
				
				//The type is correct, check if the item is correct
				if(GEInterfaces.OFFER_ITEM.get().getComponentItem() == itemID) {
					//The item is correct, check if the price is correct
					int currentPrice = InfoHelper.stringToInt(GEInterfaces.OFFER_PRICE.get().getText(), " coins",",");
					if(price == -1) {
						int avrPrice = InfoHelper.stringToInt(GEInterfaces.OFFER_AVR_PRICE.get().getText(), ",");
						if(buy == true) {
							Double targ = avrPrice * 1.2;
							int target = targ.intValue();
							if(currentPrice > target) {
								//The price is correct, check if the quantity is correct
								int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
								if(currentQuantity == quantity) {
									//The quantity is correct, return confirm offer
									return OfferState.OFFER_SCREEN_OFFER_CORRECT;
								} else {
									//No the quantity isn't correct, return quantity wrong
									return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
								}
							} else {
								//the price is wrong
								return OfferState.OFFER_SCREEN_PRICE_WRONG;
							}
						} else {
							Double targ = avrPrice * 0.67;
							int target = targ.intValue();
							if(currentPrice < target) {
								//The price is correct, check if the quantity is correct
								int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
								if(currentQuantity == quantity) {
									//The quantity is correct, return confirm offer
									return OfferState.OFFER_SCREEN_OFFER_CORRECT;
								} else {
									//No the quantity isn't correct, return quantity wrong
									return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
								}
							} else {
								//the price is wrong
								return OfferState.OFFER_SCREEN_PRICE_WRONG;
							}
						}
					} else if(currentPrice == price) {
						//The price is correct, check if the quantity is correct
						int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
						if(currentQuantity == quantity) {
							//The quantity is correct, return confirm offer
							return OfferState.OFFER_SCREEN_OFFER_CORRECT;
						} else {
							//No the quantity isn't correct, return quantity wrong
							return OfferState.OFFER_SCREEN_QUANTITY_WRONG;
						}
					} else {
						//No the price isn't correct, return price wrong
						return OfferState.OFFER_SCREEN_PRICE_WRONG;
					}
				} else {
					//The item isn't correct
					return OfferState.OFFER_SCREEN_ITEM_WRONG;
				}
			} else if(GEInterfaces.HISTORY_WINDOW.isVisible()){
				//We are on the history screen, return on history screen
				return OfferState.HISTORY_SCREEN;
			} else {
				return OfferState.LOADING_SCREENS;
			}
		} else {
			return OfferState.GE_CLOSED;
		}
	}
	
	public static enum QuantityState {
		PLUS_1000, PLUS_100, PLUS_10, PLUS_1, CUSTOM, PLUS, MINUS, CORRECT
	}

	public static QuantityState getQuantityState(int goal, int current) {
		if(goal == current)
			return QuantityState.CORRECT;
		if(goal > current + 998)
			return QuantityState.PLUS_1000;
		if(goal > current + 98)
			return QuantityState.PLUS_100;
		if(goal > current + 9)
			return QuantityState.PLUS_10;
		if(goal > current)
			return General.random(1, 10) > 2 ? QuantityState.PLUS_1 : QuantityState.PLUS;
		if(goal + 10 < current)
			return QuantityState.CUSTOM;
		return QuantityState.MINUS;
	}
	
	public enum OfferState {
		 GE_CLOSED,
		 SELECTION_SCREEN_OFFER_ACTIVE,
		 SELECTION_SCREEN_CAN_MAKE_OFFER,
		 SELECTION_SCREEN_CAN_COLLECT,
		 SELECTION_SCREEN_SHOULD_RETURN_TRUE,
		 SELECTION_SCREEN_SHOULD_CANCEL_OFFER,
		 SELECTION_SCREEN_SHOULD_WAIT,
		 OFFER_SCREEN_TYPE_WRONG,
		 OFFER_SCREEN_ITEM_WRONG,
		 OFFER_SCREEN_PRICE_WRONG,
		 OFFER_SCREEN_QUANTITY_WRONG,
		 OFFER_SCREEN_OFFER_CORRECT,
		 HISTORY_SCREEN,
		 LOADING_SCREENS
	}
	
	public enum WindowState {
		CLOSED, SELECTION_SCREEN, BUY_SCREEN, SELL_SCREEN, HISTORY_SCREEN
	}
	
	public static WindowState getWindowState() {
		if(GEInterfaces.SELECTION_WINDOW.isVisible())
			return WindowState.SELECTION_SCREEN;
		
		if(GEInterfaces.HISTORY_WINDOW.isVisible())
			return WindowState.HISTORY_SCREEN;
		
		if(GEInterfaces.BUY_WINDOW.isVisible())
			return WindowState.BUY_SCREEN;
		
		if(GEInterfaces.SELL_WINDOW.isVisible())
			return WindowState.SELL_SCREEN;
		
		return WindowState.CLOSED;
	}
	
	public static void handleCancellingOffer() {
		for(int i = 7; i < 15 ; i++) {
			RSInterface type = Interfaces.get(465, i, 16);
			if(type != null && !type.isHidden()) {
				if(type.getText().contains("Sell")) {
					RSInterface slot = Interfaces.get(465, i, 2);
					if(slot != null && !slot.isHidden()) {
						if(slot.click("Abort offer")) {
							Timing.waitCondition(GEConditions.canCollect(), General.random(4000, 7000));
						}
					}
				}
			}
		}
	}
	
	public static void handleMakingOffer(String name, boolean buy) {
		if(buy == true) {
			for(int i = 7; i < 15 ; i++) {
				RSInterface type = Interfaces.get(465, i, 16);
				if(type != null && !type.isHidden()) {
					if(type.getText().contains("Empty")) {
						RSInterface buyBtn = Interfaces.get(465, i, 3);
						if(buyBtn != null && !buyBtn.isHidden()) {
							if(buyBtn.click()) {
								Timing.waitCondition(GEConditions.GEBuyWindowVisible(), General.random(4000, 7000));
							}
						}
					}
				}
			}
		} else {
			RSItem[] target = Inventory.find(name);
			if(target != null && target.length > 0) {
				if(target[0].click()) {
					Timing.waitCondition(GEConditions.GESellWindowVisible(), General.random(4000, 7000));
				}
			}
		}
	}
	
	public static void handleWrongOfferPrice(int price, boolean buy) {
		if(GEInterfaces.OFFER_AVR_PRICE.isVisible()) {
			if(price == -1) {
				if(buy == true) {
					GEInterfaces.PRICE_PLUS_5.get().click();
					return;
				} else {
					GEInterfaces.PRICE_MINUS_5.get().click();
					return;
				}
			}
		}
		
		if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
			Keyboard.typeSend(Integer.toString(price));
			Timing.waitCondition(GEConditions.GESearchBoxDissapeared(), General.random(4000, 7000));
			return;
		} 
		
		if(GEInterfaces.PRICE_CUSTOM.isVisible()) {
			if(GEInterfaces.PRICE_CUSTOM.get().click()) {
				Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
				return;
			}
		}
	}
	
	public static void handleWrongOfferQuantity(int quantity) {
		// quantity isn't correct
		if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
			Keyboard.typeSend(Integer.toString(quantity));
			Timing.waitCondition(GEConditions.GESearchBoxDissapeared(), General.random(4000, 7000));
			return;
		} 
		int currentQuantity = InfoHelper.stringToInt(GEInterfaces.OFFER_QUANTITY.get().getText(), ",");
		switch(getQuantityState(quantity, currentQuantity)) {
		case CORRECT:
			break;
		case CUSTOM:
			if(GEInterfaces.QUAN_CUSTOM.isVisible()) {
				GEInterfaces.QUAN_CUSTOM.get().click();
				Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
			}
			break;
		case MINUS:
			if(GEInterfaces.QUAN_MINUS.isVisible())
				GEInterfaces.QUAN_MINUS.get().click();
			break;
		case PLUS:
			if(GEInterfaces.QUAN_PLUS.isVisible())
				GEInterfaces.QUAN_PLUS.get().click();
			break;
		case PLUS_1:
			if(GEInterfaces.QUAN_PLUS_1.isVisible())
				GEInterfaces.QUAN_PLUS_1.get().click();
			break;
		case PLUS_10:
			if(GEInterfaces.QUAN_PLUS_10.isVisible())
				GEInterfaces.QUAN_PLUS_10.get().click();
			break;
		case PLUS_100:
			if(GEInterfaces.QUAN_PLUS_100.isVisible())
				GEInterfaces.QUAN_PLUS_100.get().click();
			break;
		case PLUS_1000:
			if(GEInterfaces.QUAN_PLUS_1000.isVisible())
				GEInterfaces.QUAN_PLUS_1000.get().click();
			break;
		}
	}
	
	public static void handleWrongOfferItem(String name, int itemID, boolean buy) {
		if(buy == true) {
			if(GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible()) {
				if(GEInterfaces.SEARCH_ITEM_RESULTS_CONTAINER.isVisible()) {
					if(hasSearchTarget(itemID)) {
						if(clickSearchTarget(itemID)) {
							General.sleep(1300, 2100);
							return;
						}
					} else {
						String alreadyTyped = GEInterfaces.SEARCH_ITEM_INPUT_TEXT.get().getText();
						String trimmed = alreadyTyped.substring(46, alreadyTyped.length()-1);
						Keyboard.typeString(InfoHelper.partNameToType(name, trimmed.replace("*", "")));
						General.sleep(600,900);
						return;
					}
					
				}
			}
			
			if(GEInterfaces.OFFER_ITEM.isVisible()) {
				if(GEInterfaces.OFFER_ITEM.get().click()) {
					Timing.waitCondition(GEConditions.GESearchBoxAppeared(), General.random(4000, 7000));
					return;
				}
			}
		} else {
			RSItem[] target = Inventory.find(itemID);
			if(target != null && target.length < 0) {
				if(target[0].click()) {
					General.sleep(900, 2100);
				}
			}
		}
	}
	
	public static boolean hasSearchTarget(int itemID) {
		if(GEInterfaces.SEARCH_RESULT_1.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_1.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_2.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_2.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_3.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_3.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_4.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_4.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_5.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_5.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_6.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_6.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_7.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_7.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_8.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_8.get().getComponentItem() == itemID) {
				return true;
			}
		}
		if(GEInterfaces.SEARCH_RESULT_9.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_9.get().getComponentItem() == itemID) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean clickSearchTarget(int itemID) {
		if(GEInterfaces.SEARCH_RESULT_1.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_1.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_1.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_2.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_2.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_2.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_3.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_3.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_3.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_4.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_4.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_4.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_5.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_5.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_5.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_6.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_6.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_6.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_7.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_7.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_7.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_8.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_8.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_8.get().click();
			}
		}
		if(GEInterfaces.SEARCH_RESULT_9.isVisible()) {
			if(GEInterfaces.SEARCH_RESULT_9.get().getComponentItem() == itemID) {
				return GEInterfaces.SEARCH_RESULT_9.get().click();
			}
		}
		return false;
	}
	
	public static void exitHistoryScreen() {
		if(GEInterfaces.EXCHANGE_BTN.isVisible()) {
			if(GEInterfaces.EXCHANGE_BTN.get().click()) {
				Timing.waitCondition(GEConditions.GESelectionWindowVisible(), General.random(4000, 7000));
			}
		}
	}
	
	public static boolean isOpen() {
		return GEInterfaces.MASTER.isVisible() || GEInterfaces.HISTORY_WINDOW.isVisible();
	}
	
	public static boolean open() {
		if(isOpen()) return true;
		
		RSNPC[] geClerks = NPCs.findNearest("Grand Exchange Clerk");
		if (geClerks.length > 0)
			if(Clicking.click("Exchange Grand Exchange Clerk", geClerks[0])) 
				Timing.waitCondition(GEConditions.GEOpen(), General.random(3000, 7000));
				return isOpen();
	}

}

 

GEInterfaces Class

  Reveal hidden contents

package scripts.api.data;

import org.tribot.api2007.Interfaces;
import org.tribot.api2007.types.RSInterface;

public enum GEInterfaces {

	MASTER(465), SELECTION_WINDOW(465, 7, 16), HISTORY_WINDOW(383, 3, 0), BUY_WINDOW(465, 24, 19, 1118), SELL_WINDOW(465, 24, 19, 1119),
	
	SLOT(465, 7), SLOT_ACTIVE(465, 7, 2), SLOT_TYPE(465, 7, 16), SLOT_ITEM(465, 7, 18), SLOT_NAME(465, 7, 19), 
	SLOT_PROGRESS_WIDTH(465, 7, 22), SLOT_PRICE(465, 7, 25), SLOT_BUY_BTN(465, 7, 3), SLOT_SELL_BTN(465, 7, 4),
	
	SEARCH_ITEM_RESULTS_CONTAINER(162, 46), SEARCH_ITEM_INPUT_TEXT(162, 38),
	SEARCH_RESULT_1(162, 46, 2), SEARCH_RESULT_2(162, 46, 5), SEARCH_RESULT_3(162, 46, 8), SEARCH_RESULT_4(162, 46, 11), 
	SEARCH_RESULT_5(162, 46, 14), SEARCH_RESULT_6(162, 46, 17), SEARCH_RESULT_7(162, 46, 20), SEARCH_RESULT_8(162, 46, 23),
	SEARCH_RESULT_9(162, 46, 26),
	
	OFFER_NAME(465, 24, 25), OFFER_ITEM(465, 24, 21), OFFER_PRICE(465, 24, 39), OFFER_QUANTITY(465, 24, 32), OFFER_TOTAL(465, 24, 43),
	OFFER_AVR_PRICE(465, 26),
	
	QUAN_MINUS(465, 24, 1), QUAN_PLUS(465, 24, 2), QUAN_PLUS_1(465, 24, 3), QUAN_PLUS_10(465, 24, 4), QUAN_PLUS_100(465, 24, 5),
	QUAN_PLUS_1000(465, 24, 6), QUAN_CUSTOM(465, 24, 7),
	
	PRICE_MINUS(465, 24, 8), PRICE_PLUS(465, 24, 9), PRICE_MINUS_5(465, 24, 10), PRICE_CUSTOM(465, 24, 12), PRICE_PLUS_5(465, 24, 13),
	
	CONFIRM_NEW_OFFER(465, 27), 
	
	HISTORY_BTN(465, 3), EXCHANGE_BTN(383,2), COLLECT_BTN(465, 6, 0),
	
	CLOSE_OFFER(465, 2, 11), CLOSE_HISTORY(383, 1, 11), BACK_BTN(465, 4);
	
	
	private int parent, child, component, texture;
	private int[] id;
	
	GEInterfaces(int... ids){
		this.id = ids;
		switch(id.length) {
		case 1:
			this.parent = id[0];
			break;
		case 2:
			this.parent = id[0];
			this.child = id[1];
			break;
		case 3:
			this.parent = id[0];
			this.child = id[1];
			this.component = id[2];
			break;
		case 4:
			this.parent = id[0];
			this.child = id[1];
			this.component = id[2];
			this.texture = id[3];
		}
	}
	
	public boolean isVisible() {
		switch(id.length) {
		case 1:
			return Interfaces.get(parent) != null && !Interfaces.get(parent).isHidden();
		case 2:
			return Interfaces.get(parent, child) != null && !Interfaces.get(parent, child).isHidden();
		case 3:
			return Interfaces.get(parent, child, component) != null && !Interfaces.get(parent, child, component).isHidden();
		case 4:
			return Interfaces.get(parent, child, component) != null && !Interfaces.get(parent, child, component).isHidden() && Interfaces.get(parent, child, component).getTextureID() == texture;
		}
			
		return false;
	}
	
	public int[] getID() {
		switch(id.length) {
		case 1:
			return new int[] {parent};
		case 2:
			return new int[] {parent, child};
		}
		return new int[] {parent, child, component};
	}
	
	public RSInterface get() {
		switch(id.length) {
		case 1:
			return Interfaces.get(parent);
			
		case 2:
			return Interfaces.get(parent, child);
		}
		return Interfaces.get(parent, child, component);
	}
}

 

GEConditions Class

  Reveal hidden contents

package scripts.api.utils.conditions;

import scripts.api.data.GEInterfaces;
import scripts.api.utils.grandexchange.Exchange;

public class GEConditions {

	public static Condition hasCollected() {
		return new Condition(() -> !GEInterfaces.COLLECT_BTN.isVisible());
	}
	
	public static Condition canCollect() {
		return new Condition(() -> GEInterfaces.COLLECT_BTN.isVisible());
	}
	
	public static Condition GEOpen() {
		return new Condition(() -> Exchange.isOpen());
	}
	
	public static Condition GEClosed() {
		return new Condition(() -> !Exchange.isOpen());
	}
	
	public static Condition GEBuyWindowVisible() {
		return new Condition(() -> GEInterfaces.BUY_WINDOW.isVisible());
	}
	
	public static Condition GESellWindowVisible() {
		return new Condition(() -> GEInterfaces.SELL_WINDOW.isVisible());
	}
	
	public static Condition GESelectionWindowVisible() {
		return new Condition(() -> GEInterfaces.SELECTION_WINDOW.isVisible());
	}
	
	public static Condition GESearchBoxDissapeared() {
		return new Condition(() -> !GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible());
	}
	
	public static Condition GESearchBoxAppeared() {
		return new Condition(() -> GEInterfaces.SEARCH_ITEM_INPUT_TEXT.isVisible());
	}
	
	private interface BooleanLambda{
        boolean active();
    }

    private static class Condition extends org.tribot.api.types.generic.Condition{
        private BooleanLambda lambda;

        public Condition(BooleanLambda lambda){
            super();
            this.lambda = lambda;
        }

        @Override
        public boolean active() {
            return lambda.active();
        }
    }
	
}

 

InfoHelper Class

  Reveal hidden contents

package scripts.api.utils.helpers;

import org.tribot.api.General;
import org.tribot.api2007.types.RSItemDefinition;

public class InfoHelper {

	public static int stringToInt(String input, String... toRemove) {
		String[] forRemoving = toRemove;
		switch(forRemoving.length) {
		case 1:
			return Integer.parseInt(input.replace(forRemoving[0], ""));
		case 2:
			String first = input.replace(forRemoving[0], "");
			return Integer.parseInt(first.replace(forRemoving[1], ""));
		case 3:
			String first2 = input.replace(forRemoving[0], "");
			String second = first2.replace(forRemoving[1], "");
			return Integer.parseInt(second.replace(forRemoving[2], ""));
		default:
			return -1;
		}
	}
	
	public static String partNameToType(String fullName, String alreadyTyped) {
		String remaining = fullName.replaceFirst(alreadyTyped, "");
		return remaining.length() > 2 ? remaining.substring(0, General.random(1, 2)) : remaining;
	}
	
	public static String getItemNameFromID(int itemID){
        RSItemDefinition itemDef  = RSItemDefinition.get(itemID);
        if(itemDef !=null){
            String itemName = itemDef.getName();
            if(itemName!=null){
                return itemName;
            }
        }
        return "";
	}
	
}

 

 

Had a look and change some Interface IDs as well as added a couple things,

Couldn't buy a "knife" with the original setup as even if you type the full word "knife" it was still way past the first 9 search results. I added up to 27 results as well as a check that if the item's name has been fully typed and its still not there then scroll down. Added a failsafe for if the script starts searching before interface is fully loaded(would once in a while catch it writing nife, then it would try to write knife on to and would end up with nifeknifeknifeknife). Now if the first char type doesn't match the first char of the item name it will backspace first.

I'm going to try to keep maintaining it, I put it on my github in case anyone else wants to look at what I changed. GrandExchangeSnippet

Share this post


Link to post
Share on other sites
On 11/7/2019 at 10:33 PM, kryptonite93 said:

Had a look and change some Interface IDs as well as added a couple things,

Couldn't buy a "knife" with the original setup as even if you type the full word "knife" it was still way past the first 9 search results. I added up to 27 results as well as a check that if the item's name has been fully typed and its still not there then scroll down. Added a failsafe for if the script starts searching before interface is fully loaded(would once in a while catch it writing nife, then it would try to write knife on to and would end up with nifeknifeknifeknife). Now if the first char type doesn't match the first char of the item name it will backspace first.

I'm going to try to keep maintaining it, I put it on my github in case anyone else wants to look at what I changed. GrandExchangeSnippet

Thats great man, thank you.

Share this post


Link to post
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.


  • Our picks

    • Over the past few months, I’ve been working diligently on a new project - TRiBot X. Everything has been written from the ground up, with all of the best practices of software engineering. Every aspect of TRiBot has been re-imagined to support three main goals: flexibility, useability, and reliability.
        • Like
      • 31 replies
    • Come give us feedback on the next version of TRiBot!
        • Thanks
        • Like
      • 74 replies
    • TRiBot is looking to improve a lot of its customer relationship management, customer on boarding process, customer experience, design elements, community engagement and pretty much everything else you can imagine when it comes to marketing.

      Our goal: To ensure that the marketing done TRULY reflects the experience and does not shine an inaccurate light on what TRiBot is lacking in.

      So I ask, what do you love about TRiBot and what do you hate about TRiBot? What does O S Bot, Rune M8, PowR Bot and Dre amBot do better? (yes I purposely didn't spell it right 😂).

      Love, 

      RileyZ
        • Like
      • 23 replies
    • Over the last three weeks, I've been working on upgrading our server infrastructure. It's finally ready and is now live!

      Why?

      Increased reliability - less server errors


      Increased availability - less downtime


      Increased security - keeping us and you secure


      Increased capacity - ability to serve you better


      Increased speed - less waiting for things to load


      Faster development - server and service updates will come faster


      What are the changes?

      Move from a single AWS EC2 instance to AWS ECS (Elastic Container Service)


      Distributed computing


      Load balancing


      Git management of server files and filesystem


      Redis caching


      How?

      AWS ECS (with 10 EC2 instances)


      AWS ElastiCache (Redis)


      AWS Load Balancing


      AWS EFS (Elastic file system)


      Please bare with us as I continue to tune the server for maximum performance. Slow loading speeds may occur temporarily. I thank everyone for their patience.

      Please post on this thread if you experience any issues other than slow loading times.
        • Like
      • 51 replies
    • This release will:

      Fix prayers and world hopper API (Thanks @JoeDezzy1 and @erickho123)


      Improve banking API (Thanks @Encoded)


      Adds methods for returning and using Java Lists, rather than arrays


      Slightly randomizes some hardcoded behaviour


      Removes sleeps from waitConditions; the efficiency saving potential is negligible in these use-cases, therefore cleaner code is preferable


      Other back-end improvements





      Note: If you are using LG, please restart both the RS client and TRiBot.
        • Sad
        • Haha
        • Thanks
        • Like
      • 90 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...