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

NeuroGenix

Grand Exchange API - Help

Recommended Posts

Post rewritten after rewritting and updating the code multiple times.

So I decided to give writing my own GE API a go and this is what I've come up with so far, using Exchange#offer(name, price, quantity, buy) will do the following:

  1. If the GE is closed, it will open it and continue making the offer.
  2. If the price is set to -1 then it will use the buttons to increase or decrease the price, depending on whether it is a buy or sell offer, until it is at a price that will buy/sell instantly. Otherwise it will use the custom input button to set the price.
  3. It will set the quantity using the 1/10/100/1000 buttons. I plan on updating this to randomise between using them and the custom input method shortly. Edit* I hadn't even remembered implementing this until I saw it do it whilst testing the method, and it was beautiful, but if it goes over the buy quantity accidently, in the example I saw it was clicking +100 and clicked it again too fast so instead of stopping before its target of 875 it got to 900, it will then use the custom amount interface to input 875, beautiful.
  4. It will prioritise buy offers over sell offers so that if there isn't an empty slot available, or any items to collect, then it will cancel a sell offer, collect it and continue now it has a free slot.
  5. If there isn't a free slot available and we are trying to sell something it will return true, this is so that in my scripts it will remove the item from a toSell HashMap and put it back into the bank to sell later because it has bought the items it needs to continue botting. If it is instead trying to buy something and there are no empty slots or sell offers to cancel then it will wait for something to buy and continue once it can collect something and therefore has an empty slot.
  6. Update* It will now search for the item 1-3 words at a time checking the first 9 results each time and will choose the item as soon as it is visible as a human would. I might update this so that it randomises more, sometimes entering the whole first word of an items name straight away, because I sometimes do that, most of the time though I enter as few characters as I need to, I think, thoughts?

Let me know what you think, the code is probably disgusting to look at for some of you but for others just starting out like me it could be a valuable learning tool, for how not to code ;) All feedback and constructive criticism appreciated.

Exchange 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),
	
	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),
	
	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 "";
	}
	
}

 

Thank you to everyone that has read this far, it is appreciated :)

Rewritten, if you have read again, even more appreciation! ;)

Edited by NeuroGenix
Completely rewritten, renamed, added more functions/features, rewrote topic

Share this post


Link to post
Share on other sites

I just realised I should probably null check the getNameFromItemDefinition method in the beginning of the GE#Offer method.

- Also there is a lot of over lapping code between the Buy and Sell Screen - Setting the price, quantity and confirming the offer. This could probably be trimmed down a lot, as the interface ID's are identical in both scenarios; I haven't gotten around to neatening it all up yet but that will be a goal.

Share this post


Link to post
Share on other sites

To determine if an item is "collectable", I'd say it is a better approach to use the RSGEOffer#getAmountTransferred() and compare it to the amount you posted the offer for.

I've noticed things to get way messier when relying on the collection button being visible to determine when to collect items, it makes things harder to track.

 

Also another thing, make your logic less restricted.

You're example:

If we have no free slot -> if we have nothing to collect -> if we are trying to buy something and there is a sell offer it will cancel it -> if we are trying to sell something it will return true 

 

A less restricted approach could be anything, here's a crappy example:

public static EXAMPLE_ENUM_STATE getState() {

    if (forAllOffers_If_AmountTransferred_IsEqualTo_AmountOffered_Or_isEqualTo_AmountTransferredToCollect_Threshold()) {

        return COLLECTIONS_PENDING;

    }

    If (getEmptySlots() > 0) {

        if (weHave_EnoughItems_ToSell() && weStill_WantToSell())

            return SELL_ITEMS;

        if ( weHave_Not-EnoughItems_WeWant() && weHave_EnoughCoins_ToBuy_whatWeWant())

            return BUY_ITEMS;

    }

    return NOTHING_TO_DO;

}

 

Edited by JoeDezzy1
  • Thanks 1

Share this post


Link to post
Share on other sites

Also yes, always null check. Read the API docs if you're unsure what a method can return to see if you need to null check.

 

Most getters in the API should be null checked (After it is stored into a variable), and mostly everything except a few things which return an array, should be bounds checked as array.length > 0 (After it is stored into a variable)

Share this post


Link to post
Share on other sites
1 minute ago, IceKontroI said:

@NeuroGenix I'm not sure if you just wanted your own implementation of this, but Tribot already does have all the GE constants set up (not sure if they dynamically change with updates).

And Yes, I've just pushed an update addressing issues that were previously posted, it is not live yet but it should be soon.

Although I give him props for doing it himself, I did so as well a while ago :D

Turned out to be a good thing!

Share this post


Link to post
Share on other sites
1 hour ago, JoeDezzy1 said:

To determine if an item is "collectable", I'd say it is a better approach to use the RSGEOffer#getAmountTransferred() and compare it to the amount you posted the offer for.

I've noticed things to get way messier when relying on the collection button being visible to determine when to collect items, it makes things harder to track.

 

Also another thing, make your logic less restricted.

You're example:

If we have no free slot -> if we have nothing to collect -> if we are trying to buy something and there is a sell offer it will cancel it -> if we are trying to sell something it will return true 

 

A less restricted approach could be anything, here's a crappy example:

public static EXAMPLE_ENUM_STATE getState() {

    if (forAllOffers_If_AmountTransferred_IsEqualTo_AmountOffered_Or_isEqualTo_AmountTransferredToCollect_Threshold()) {

        return COLLECTIONS_PENDING;

    }

    If (getEmptySlots() > 0) {

        if (weHave_EnoughItems_ToSell() && weStill_WantToSell())

            return SELL_ITEMS;

        if ( weHave_Not-EnoughItems_WeWant() && weHave_EnoughCoins_ToBuy_whatWeWant())

            return BUY_ITEMS;

    }

    return NOTHING_TO_DO;

}

 

Thank you, I'll keep you suggestion in mind if I run into any problems with detecting when items are collectable, right now it seems to be working well - Unless it remove sleeps and it changes states before the interface has loaded, I imagine that would be an issue with your suggestion as well though?

That is a good idea about making my script more flexible, I am actually rewritting it all right now and had already began implementing a similar idea (I think). I'll edit my post in an hour or so when it's finished and tested and it'd be helpful to know if it's what you mean.

1 hour ago, IceKontroI said:

@NeuroGenix I'm not sure if you just wanted your own implementation of this, but Tribot already does have all the GE constants set up (not sure if they dynamically change with updates).

I wanted my own class so I could update it and not have to rely on the Tribot API being up to date. I also feel like it gives me more flexibility, it's really easy to null check and click using that GEInterface class I made, I'm not sure if it is that simple when using the Tribot API?

1 hour ago, JoeDezzy1 said:

Also yes, always null check. Read the API docs if you're unsure what a method can return to see if you need to null check.

 

Most getters in the API should be null checked (After it is stored into a variable), and mostly everything except a few things which return an array, should be bounds checked as array.length > 0 (After it is stored into a variable)

I have updated that in the new version, I think I have done it correct but if I haven't can you let me know when I edit this post later please :)

1 hour ago, JoeDezzy1 said:

And Yes, I've just pushed an update addressing issues that were previously posted, it is not live yet but it should be soon.

Although I give him props for doing it himself, I did so as well a while ago :D

Turned out to be a good thing!

Thats good to hear.

Thank you man, I'm sure it'll turn out to be a good thing for me too :)

Share this post


Link to post
Share on other sites

Updated again, it will now use the +/-5% buttons to increase/decrease the price accordingly until it has reached a price in which it will instantly buy/sell if you set the price to -1 in Exchange#offer(int itemID, int price, int quantity, boolean buy).

I'm really chuffed with how it's turned out so far, the only thing I really need to add to it is antiban. I'm not familiar with implementing abc, could someone tell me whether or not I could use the human reaction times for something like this or not? Because if I remember correctly its not to be used in situations where the reaction time is low, and I'm thinking the GE is one of those situations?

Share this post


Link to post
Share on other sites
9 hours ago, NeuroGenix said:

Having an issue with the waitconditions return true too quickly, putting in an additional sleep before it recalled the offer method seems to fix it, but looks more bot like, suggestions?

This is because the logic in your wait conditions doesn't match the logic you are depending on for your actions to execute.

i.e) if (Inventory.find(item).length > 0) waitFor(Inventory.find(item).length == 0);

Share this post


Link to post
Share on other sites
2 hours ago, JoeDezzy1 said:

This is because the logic in your wait conditions doesn't match the logic you are depending on for your actions to execute.

i.e) if (Inventory.find(item).length > 0) waitFor(Inventory.find(item).length == 0);

Can you give me an example from the code I've written where this is the case? So I understand what you mean better.

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.


  • Similar Content

    • By Fluffee
      Fluffee's Server Setup 3.0
      As some of you may know, I released an automated server setup script a little over a year ago. Albeit that script worked well, I was never fully satisfied with it, as I found it to be kind of messy to use. As a result, I rewrote the script, and restructured it, to add more, and stronger support for the different versions of Debian, the different versions of CentOS and the different versions of Ubuntu. However, with so many different Operating Systems being supported, and many different server providers having different setups, it's hard for me to test every possible scenario on my own. Which is why I've been privately handing this script out, and am now publicly looking for help.

      What does the script do?
      Similar to my previous setup script, this script changes the SSH port and creates a new user for connecting and using the server and disables root SSH connections; it installs the latest version of TightVNC Server (1.3.10) and sets that up with the desired port and password. It installs JDK 102 (32 or 64 bit depending on the OS), and installs TRiBot and OSBuddy and sets up the appropriate .jar file associations.
      What operating systems does it support?
      - CentOS (6.x, 7.x, 8.x) (32 and 64 bit)
      - Debian (7.x, 8.x, 9.x, 10.x) (32 and 64 bit)
      - Ubuntu (12.x, 14.x.16.x, 18.x, 20.x) (32 and 64 bit)
      Does it work?
      As far as I know, yes it does in fact work, and it works well if I might add. However, given that I can't test every possible setup, there is the potential for differences and issues
      How do I run the script?
      Login as root to a fresh VPS/dedi running one of the supported operating systems. From there run the commands listed below and follow the onscreen instructions. For those who would like to see the script's code, it can be found on my bitbucket here. The commands to run are as follows:
      (curl -kO https://bitbucket.org/teamfluffee/fluffees-server-setup/raw/master/fluffees-server-setup.sh || wget --no-check-cert https://bitbucket.org/teamfluffee/fluffees-server-setup/raw/master/fluffees-server-setup.sh) && chmod +x fluffees-server-setup.sh && bash fluffees-server-setup.sh -v Version History
       
    • By briareos2285
      Just got a new Windows 10 Home x64 Laptop. Going through my usual install method and finding that I cant get looking glass to work. I have followed a few "old" guides, because I cant find any that are more recent. I am installing Java SE Development Kit 8u251, I am choosing the x86 version since the only OSbuddy cross platform .jar  file is 32bit. Its worked fine in the past. I then open Osbuddy, and then Open Tribot. I leave it on the default Tribot Version of 10.24.1. I select the java version for Tribot to use to be the JDK and not the jre. I changed the Heap Size to 1024 MB and login. I minimize Osbuddy, then I click New Client(Looking Glass). The Screen goes to black and says " Waiting for a Runescape client.... currently waiting for a valid client. List of detected java applications below." and there is nothing Below. I also tried a backup method that used to work as well, which was to instead click New Client (Osbuddy) and then manually select the Osbuddy .jar file which would open up Osbuddy and Create a Looking Glass Tab that mirrored Osbuddy. This no longer happens either. Ive also deleted the Hooks and Caches using Naton's Java Executable. I have also defined the correct Paths in my Computers Environment Variables.
      Im at a loss for what to do. Any help greatly appreciated
    • By Sidesteppin12
      I decided to create my own banking API that mimics tribots way of implementing the API as much as possible. Basically it would only contain nothing more than just method calls. Simple and easy to use.
      This API is a reworked version that is currently in my jHerblore script. I intend to release my GE api as well once I have finished that one up too. The API requires DaxWalker & Wastedbro's Item Price API. Other than that the rest is achieveable with standard dependencies that already comes with tribot.
      All of the method names are the same as the ones from Banking & GrandExchange class in tribot, with a few exceptions, the only difference is that these methods are called with different class names such as Banker & Exchanger, so they do not collide with the Banking & GrandExchange class of tribot and cause an ambiguity problem.
       
      List of available methods:
       
      Some of the features this API offers:
      - Methods that incorporate any form of withdrawing or depositing do not need you to first check if the bank is open nor if it is loaded. It will attempt to open the bank if it is not open before returning false, and wait for bank to load if it is not loaded yet.
      - Methods that incorporate any form of buying or selling do not need you to first check if the exchange window is open. It will attempt to open the exchange window if it is not open before returning false.
      - Deselector. All methods that require the mouse to click somewhere on the screen first check if an item or spell is selected, if it is then it will deselect whatever is selected before attempting the requested action.
      - Additional failsafes, not just the deselector. Tribots banking api does not know if what you were trying to click actually was succesfully clicked. Instead it views succesfully calling the click function as a succesfull attempt. It's kind of like playing pin the nail to the donkey game. It does not know if it pinned it at the right location, but as long as it pinned it the function returns true. This is not true for all methods, some methods do actually check if the action was succesfully performed, however they do not reattempt the action if it failed. 1 call = 1 attempt. My api will reattempt any action that might fail, several times, before returning false and will also wait until inventory count is updated. For example using the tribot banking API if you were to deposit all your items and then immediately check your available inventory space before withdrawing items then it might not work as you wish because Banker.depositAll() returns before the action of depositing has finished.
      - When banking, closes GrandExchange window if it is open.
      - When buying/selling, closes the bank screen if it is open.
      - Support for withdrawing items in noted format and with or without stack exception. Stack exception is basically if you wish to draw X amount of items in your inventory but you only had Y left, then you can choose if you wish to draw these items or not. Also supports depositing of noted item ids if you happen to pass a list with of items that contains items of unnoted item ids, but the item in your inventory is a noted version of the item in your inventory. Also will not deposit equipment or items if you have none equipped or in your inventory. There is a total of 4 different depositing methods and 16 different withdrawing methods.
      - Unique dynamic sleeping method, all methods that should sleep already have sleeps implemented so you do not need to call a sleep after executing any of the methods. Involves random varying sleeps but will occasionally, every so often, in a irregular pattern, sleep a bit longer. I use this because I prefer it over General.sleep(). Feel free to replace it with whichever method you wish. Remember before running the main loop in your script to call:
      jGeneral.get().generateSeed(); This will create a random number between 0-100 that will be added to your dynamic sleeps in milliseconds. This is so no bot has the same average reaction/sleeping time.
      - When buying items on the GE, if the bot does not have any money or too little money in the inventory, it will check if you have enough of the missing amount in the bank and withdraw that amount.
      - Custom buying method that checks for an exact string match of the item you wish to buy and chooses that one from the returned items in the buy window search box. The standard GE api does not do this and will for instance click the wrong herb when it searches for "Guam leaf" in the grand exhcange, this is because more than one item contains "guam leaf" in their name. Such as Grimy guam leaf and so on.
      - Profit tracking when buying/selling items on the GE. This is optional.
       
      GET THE SOURCE HERE!
       
      UPDATES:
      - Pushed new updates that fix some of the methods that I've tested a bit for now, bit of logic and efficiency improvements. Also added 2 new depositing methods. Remember to replace the old java files with the new ones.
      - Pushed even more updates. Fixed interface problem for withdrawing noted items. My GE api is now also been released to the public. Enjoy!
    • By Speaker
      Request: Wine of Zamorak 2nd floor winegrabbing script, f2p.
      Description: 
      If you didn't know, there's a ladder in the normal Chaos Temple (Asgarnia). It is exclusively for players with a total level of 500+. In order to get this level, you obviously have to not be banned, which is why I think it hasn't been done before. I would like it to do the following:
      * Grab Wines of Zamorak using telegrab on the second floor.
      * It should be reasonably fast in clicking after the wine appears the first 5-10, but it should have a very rapid onset fatigue setting/antiban. I frankly want it to not be telegrabbing 5-10 minutes out of the hour. Pretend AFK, like a user having ADD and checking something, random mouse movements, mouse off screen, mouse circling the spot where the jug of wine is, mouse going crazy some of the time for no reason. It will be efficient some of the time, but then outright miss the wine other times if there are other players there. This is my experience grabbing wines myself legitimately, so I figure the bot should have the same thing.
      * Although I do want it to have random mouse movements, when it's actively trying to grab wines, it should hover over the spot after selecting telegrab.
      * Will have the option/script argument to either Teleport to Falador to bank, or manually walk there via daxwalker or something. It should then walk back to the Chaos Temple, climb the ladder, and resume telegrabbing.
      * Display paint of wines per hour, raw profit (Ge price x how many wines), net prof (raw profit - cost of law rune), magic xp gained, magic xp per hour, time ran.
      Payment Amount: We'll start at $50, and go up to $100. EDIT: Paypal would be preferable.
      Time: Variable. Sooner is better, but if it takes two weeks to create the perfect wine grabbing script, so be it.
      Additional: Support for LG OpenOSRS, since that's what I bot with. 
    • By itgottti
      I've written down almost everything in half machine language and a logic syntax so it will be easier to code it for you.
      It contains things like:
      - Checking specific Items in Bank if available
      - Withdrawing x items
      - Combining x and y item
      - Once done, sell item on GE for Price P (selected in GUI)
      - Check if sell Order done (if not lower price P by P% (selected in GUI)
      - Redo
      - Calculate max equal amount of item x and y you could buy (with prices set before in the GUI)
      - Try to Buy each item
      - Check if Order is finished
      - Else increase price N by % (set in GUI)
      start over again.
       
      As i said i wrote it down even more in detail that will be handed to the person willing to script this for me
      Add me on discord: deua#1132
    • By idkfa
      Hello my knowledgeable friends,
      Ive botted about 3 accounts to max combat and ran small gold farms but lately I really interested in learning how to script myself so I can give back to the awesome community and start goldfarming on a professional level. That being said ive got some questions.Little background check, im a total noob when in comes to programming languages.
      - ive read that learning Java is a must. But what I don't understand is do I need to learn everything about java or just parts that are relevant to scripting for Tribot. Do I have to take a course or to do a deep dive like enlisting in an education  or is learning Java just for Tribot enough?
      - If a book is preferable, do you have any recognmendations?
      - after being proficiant in Java ive read I still need to learn how to script for Tribot specifically. Is this a long process?
      - I know this is a difficult question to answer but how long do you guys recon this process will take in hours learning Java and scripting for Tribot? Ive got about 2/3 hours to spare a day and about 5/7 on weekends
      - Also is there a discord with like minded people out there looking to learn java/tribot and also one for goldfarmer (not gonna ask for methods lol)
       
      Sorry for the long and nooby questions. Hope you guys can point me in the right direction. 
      Any constructive comments are greatly appriciated.
      Cheers,
      IDKFA
    • Guest
      By Guest
      What's up guys! 
      I'm new to scripting and I want to be the best! But I need some advice and pointers. I understand the simple side of java, just really how to fit the API into it all. 
      Any links to some really good content and videos? The only videos I can really find that's solid content is from Nexus, but it's only 2 videos. 
      Anything is appreciated! I hope to soon bring everyone some crazy awesome scripts! 
  • Our picks

    • TRiBot 12 Release Candidate

      The TRiBot team has been hard at work creating the last major version of TRiBot before the TRiBot X release. We've noticed many problems with TRiBot 11 with a lot of users preferring TRiBot 10 over 11. We've heard you, so we took TRiBot 10, added the new features introduced with 11, introduced some other new things, and created TRiBot 12. So without further adieu, here's TRiBot 12.
        • Sad
        • Like
      • 17 replies
    • Gradle is a build tool used to accelerate developer productivity.

      We recently setup a Maven repository (TRiBot Central) to make it easier for scripters to create scripts. Check it out here: https://gitlab.com/trilez-software/tribot/tribot-central/-/packages

      Furthermore, we've released a simple Gradle project to make it easy to run TRiBot and develop scripts for it. Check it out here: https://gitlab.com/trilez-software/tribot/tribot-gradle-launcher

      The goals of TRiBot Central are to:

      Deliver updates to TRiBot faster


      Better organize TRiBot's dependencies (AKA dependancies)


      Make it easier to develop scripts for TRiBot


      Make it easier to use and run TRiBot


      Note: TRiBot won't be able to run scripts from within this project until TRiBot's next release.
        • Like
      • 10 replies
    • Hi everyone,

      I'd like to thank everyone for their patience in this transition period. Since last week, we've worked out the remaining bugs with this integration.

      Some users have still been having issues with connecting their forums account to their Auth0 account. To resolve this, we've imported all forums accounts into Auth0.

      Unfortunately, the accounts which were imported today were using an unsupported password hashing algorithm. Hence, random passwords were set during the import.

      What does this mean for me?

      If you've previously linked your forums account to your Auth0 account, you don't have to do anything. Nothing changes for you.


      If you haven't logged in via our new login yet,

      Try logging in with your forums email address and the last password you used


      If you are unable to login, please use the "Forgot password" tool on the login page:
      Follow the instructions to reset your password
       
        • thonking
        • Like
      • 17 replies
    • Hello everyone,

      Last week we tried to roll out Auth0 Login, but we lost that battle. Now it's time to win the war!

      Important changes

      When logging into the client, you'll now have to enter your Auth0 account credentials instead of your forums credentials

      Note: 2FA is still handled through your forums account (for the time being)



      Changes for existing users

      You'll have to link your Auth0 account to your forums account here: https://tribot.org/forums/settings/login/?service=11


      Auth0 accounts have been created for most existing users. Please use your forums email address and password to login.



      Important notes

      Make sure to verify your email address upon creating a new Auth0 account


      When we mention your Auth0 account, we mean your account used for auth.tribot.org as displayed below
      • 81 replies
    • To better support the upcoming changes (TRiBot X, new repository), we're switching our login handler to Auth0. Instead of logging in with the standard form, you'll now be required to login through our Auth0 application.

      All existing accounts which have been used within approximately the past year have been imported into Auth0 using the same email and password combination which has been stored on the forums.

      What does this mean for users?

      Your account credentials are now even more securely stored


      You'll be able to login via Facebook, Google, and others in the future


      Is there anything users have to do differently now?

      Existing users: You'll have to login with the standard login, open your Account Settings, then link your Auth0 account


      New users: You'll be redirected to our Auth0 app (auth.tribot.org) where you'll be able to create an account


      Why was this change made?

      The new apps we are creating (such as the new repository) aren't able to use the forums to handle user logins


      To centralize all user accounts in one area


      To ensure that the client login doesn't go down when the forums are having problems


      To speed up our development


      Other considerations

      There's no documentation or official support for using Invision Community combined with Auth0, so there are still a few kinks we're working out


      We're in the works of creating an account management panel specifically for Auth0 accounts (ETA August)


      It's not possible to change email addresses for the time being (this will be resolved this August)


      Changing passwords is a weird process for the time being. To change your password, you'll have to use the "Don't remember your password" tool on the Auth0 login page
        • Like
      • 11 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...