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


  • Content Count

  • Joined

  • Last visited

  • Days Won

  • Feedback


orange451 last won the day on August 30 2015

orange451 had the most liked content!

Community Reputation

49 Excellent

About orange451

  • Rank
    Experienced Botter
  • Birthday 11/24/1995


  • Sex
  • Location
    Georgia, USA
  • Bio
    I've been a programmer for 10 years.

Recent Profile Visitors

2,541 profile views
  1. Hey all, Latest Tribot update broke a LOT of dialog option checking, so I spent the evening writing some fallback code. Additionally fixed up a few things on Tutorial Island and Cooks Assistant. Update is live on the Repo
  2. Delete your hooks.dat file, and restart tribot. There was an error with the Banking API yesterday, but it's working now. Make sure you're on Tribot version 10.24.2
  3. Something I started working on today. Smelting is all done. Next task is smithing! Smithing GUI isn't as nice, but still just as functional!
  4. Internally this uses sockets, so it's just as lightweight. What this does for you, is make a super convenient way to listen or send specific types of data that needs to be communicated from one place to another. Manually writing all that stuff with sockets leads to a very bloated/messy project. This helps you keep it clean, and also respects HTTP protocol, so you can easily interface this with many other applications on the internet! Also, things like POJO serialization is super useful. An example would be, if you have a class that contains all of the skills for your player... public class PlayerStats { private String playerName; private int attack; private int strength; private int detense; // Write getters & setters // Required for deserialization } This class can be sent to your server via: PlayerStats stats = new PlayerStats("orange451", 99, 64, 50); new RequestEntity<>(HttpMethod.POST, playerStats).exchangeAsync("http://serverip/PostStats"); The server could then read your data via: server.addEndpoint(HttpMethod.POST, "/PostStats", PlayerStats.class, (request)->{ PlayerStats stats = request.getBody(); // Write some code to write these stats to a database here return new ResponseEntity<>(HttpStatus.OK); }); Much cleaner than manually doing all this!
  5. I made a little website here: https://jrest.io/ Additionally, Gson is no longer a required library, but it is still optional if you wish to serialize DTO/POJO objects. I also added FORM URL ENCODED support and cookie support.
  6. Hey all, haven't updated this in awhile. I added support for Rune Mysteries. I also went through all the quests and tweaked a lot of their logic. I updated Tutorial Island to all the new interfaces, and everything seems to be working smoothly. Since updating, I've put 13 accounts through tutorial island through 9 qp (last 2 days). Enjoy!
  7. I've tested it on Draynor, Alkharid, and Varrock rooftop agility courses so far. Works flawlessly with no code change between them! All I need is 1 generic roof-top agility solver. Here's all the setup needed to add a new rooftop course: DRAYNOR_ROOFTOP_AGILITY( Locations.DRAYNOR_ROOFTOP_AGILITY_START, "Climb", "Rough wall", 10), ALKHARID_AGILITY( Locations.ALKHARID_AGILITY_START, "Climb", "Rough wall", 20), VARROCK_AGILITY(Locations.VARROCK_AGILIRT_START, "Climb", "Rough wall", 30); private SupportedLocations(Locations loc, String interact, String name, int minAgility) { ... } Script takes care of the rest
  8. Another update. You can now specify to use HTML as a MediaType in Rest Endpoints. Server: /** * Test Endpoint. Returns static String */ this.addEndpoint(HttpMethod.GET, "/", MediaType.TEXT_HTML, (request)->{ return new ResponseEntity<String>(HttpStatus.OK, "<h1>Index! Welcome to JREST!</h1>"); }); Client:
  9. Here's a small utility I've created when working on a rooftop agility script. It scans a position for all nearby walkable tiles and non-walkable tiles. Source: package scripts.util; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.tribot.api.interfaces.Positionable; import org.tribot.api2007.PathFinding; import org.tribot.api2007.Projection; import org.tribot.api2007.types.RSTile; public class AreaBounds { /** List of walkable tiles */ private RSTile[] walkableTiles; /** List of nonwalkable tiles */ private RSTile[] nonWalkableTiles; /** Root tile used to create AreaBounds */ private RSTile root; /** Internal tile lookup map */ private Map<RSTile, Boolean> tileLookup; /** Minimum tile */ private RSTile minTile; /** Maximum tile */ private RSTile maxTile; /** Max distance area will scan for tiles from root */ private final static int MAX_DISTANCE = 24; public AreaBounds(Positionable position) { RSTile start = position.getPosition(); root = start; tileLookup = new HashMap<>(); // Compute all tiles List<RSTile> walkable = new ArrayList<>(); List<RSTile> nonWalkable = new ArrayList<>(); fillTiles(start, walkable, nonWalkable); // Find min/max files int minX,minY; int maxX,maxY; minX = minY = Integer.MAX_VALUE; maxX = maxY = Integer.MIN_VALUE; for (RSTile tile : tileLookup.keySet()) { if ( tile.getX() < minX ) minX = tile.getX(); if ( tile.getY() < minY ) minY = tile.getY(); if ( tile.getX() > maxX ) maxX = tile.getX(); if ( tile.getY() > maxY ) maxY = tile.getY(); } minTile = new RSTile(minX, minY, root.getPlane()); maxTile = new RSTile(maxX, maxY, root.getPlane()); // Update public tile info this.walkableTiles = walkable.toArray(new RSTile[walkable.size()]); this.nonWalkableTiles = nonWalkable.toArray(new RSTile[nonWalkable.size()]); } private void fillTiles(RSTile tile, List<RSTile> walkable, List<RSTile> nonWalkable) { if ( tile == null ) return; if ( tile.distanceTo(root) > MAX_DISTANCE ) return; Boolean isWalkable = tileLookup.get(tile); if ( isWalkable == null ) isWalkable = PathFinding.isTileWalkable(tile); if ( !tileLookup.containsKey(tile) ) if ( isWalkable ) walkable.add(tile); else nonWalkable.add(tile); else return; tileLookup.put(tile, isWalkable); if ( isWalkable ) { fillTiles(offset(tile, -1, 0), walkable, nonWalkable); fillTiles(offset(tile, 1, 0), walkable, nonWalkable); fillTiles(offset(tile, 0, 1), walkable, nonWalkable); fillTiles(offset(tile, 0, -1), walkable, nonWalkable); } } private RSTile offset(RSTile tile, int x, int y) { return new RSTile(tile.getX() + x, tile.getY() + y, tile.getPlane(), tile.getType()); } /** * Returns a list of walkable tiles in this area. * @return */ public RSTile[] getWalkableTiles() { return walkableTiles; } /** * Returns a list of non-walkable tiles in this area. * @return */ public RSTile[] getNonWalkableTiles() { return nonWalkableTiles; } /** * Returns whether a tile is inside this area bounds. * @param positionable * @return */ public boolean contains(Positionable positionable) { RSTile position = positionable.getPosition(); return tileLookup.containsKey(position); } /** * Returns whether a tile is touching the perimeter of the bounds. * @param positionable * @return */ public boolean isTouching(Positionable positionable) { RSTile nonwalk = chestAdjacentNonWalkableTile(positionable.getPosition()); if ( nonwalk == null ) nonwalk = checkAdjacentWalkableTile(positionable.getPosition()); return nonwalk != null; } /** * Returns the overall amount of tiles within this area. * @return */ public int size() { return tileLookup.size(); } public void debugPaint(Graphics g) { Graphics2D g2d = (Graphics2D) g; for (RSTile tile : getWalkableTiles()) { if (tile.isOnScreen()) { g2d.setColor(new Color(0.1f, 0.8f, 0.1f, 0.2f)); g2d.fill(Projection.getTileBoundsPoly(tile.getPosition(), 0)); g2d.setColor(new Color(0.1f, 0.8f, 0.1f, 0.66f)); g2d.draw(Projection.getTileBoundsPoly(tile.getPosition(), 0)); } } for (RSTile tile : getNonWalkableTiles()) { if (tile.isOnScreen()) { g2d.setColor(new Color(0.8f, 0.1f, 0.1f, 0.2f)); g2d.fill(Projection.getTileBoundsPoly(tile.getPosition(), 0)); g2d.setColor(new Color(0.8f, 0.1f, 0.1f, 0.66f)); g2d.draw(Projection.getTileBoundsPoly(tile.getPosition(), 0)); } } } /** * Returns the tile that was used to build this AreaBounds originally. * @return */ public RSTile getRoot() { return this.root; } /** * Return the nearest walkable tile to a given RSTile within the area. * @param position * @return */ public RSTile checkAdjacentWalkableTile(RSTile position) { if ( position == null ) return null; if ( tileLookup.get(position) != null && tileLookup.get(position).booleanValue() ) return position; RSTile t1 = offset(position, -1, 0); if ( tileLookup.get(t1) != null && tileLookup.get(t1).booleanValue() ) return t1; RSTile t2 = offset(position, 1, 0); if ( tileLookup.get(t2) != null && tileLookup.get(t2).booleanValue() ) return t2; RSTile t3 = offset(position, 0, -1); if ( tileLookup.get(t3) != null && tileLookup.get(t3).booleanValue() ) return t3; RSTile t4 = offset(position, 0, 1); if ( tileLookup.get(t4) != null && tileLookup.get(t4).booleanValue() ) return t4; return null; } /** * Returns the nearest nonwalkable RSTile within the area. * @param position * @return */ public RSTile chestAdjacentNonWalkableTile(RSTile position) { if ( position == null ) return null; if ( tileLookup.get(position) != null && !tileLookup.get(position).booleanValue() ) return position; RSTile t1 = offset(position, -1, 0); if ( tileLookup.get(t1) != null && !tileLookup.get(t1).booleanValue() ) return t1; RSTile t2 = offset(position, 1, 0); if ( tileLookup.get(t2) != null && !tileLookup.get(t2).booleanValue() ) return t2; RSTile t3 = offset(position, 0, -1); if ( tileLookup.get(t3) != null && !tileLookup.get(t3).booleanValue() ) return t3; RSTile t4 = offset(position, 0, 1); if ( tileLookup.get(t4) != null && !tileLookup.get(t4).booleanValue() ) return t4; return null; } @Override public boolean equals(Object object) { if ( object == null ) return false; if (!(object instanceof AreaBounds)) return false; AreaBounds bounds = (AreaBounds)object; return this.minTile.equals(bounds.minTile) && this.maxTile.equals(bounds.maxTile) && this.size() == bounds.size(); } }
  10. Started working on a simple Roofstop agility script today. It works by automatically scanning all possible tiles in the course: This is useful, because all I have to define is the starting location, and the starting intractable object. With no extra configurations (i think) most roof-top courses should work!
  11. Small update. I added a way to specify what type of data is expected for a given REST Endpoint. Example: Server: /** * Test Post endpoint. Returns your posted data back to you. */ this.addEndpoint(HttpMethod.POST, "/GetEmployee", JsonObject.class, (request)->{ JsonObject payload = request.getBody(); int id = payload.get("id").getAsInt(); String[] names = { "Frank", "Jeff", "Oliver", "Maxwell" }; JsonObject response = new JsonObject(); response.addProperty("id", id); response.addProperty("name", names[id-1]); return new ResponseEntity<JsonObject>(HttpStatus.OK, response); }); Client: JsonObject body = new JsonObject(); body.addProperty("id", 1); RequestEntity<JsonObject> request = new RequestEntity<>(HttpMethod.POST, body); request.exchangeAsync("http://localhost/GetEmployee", JsonObject.class, (response)->{ JsonObject payload = response.getBody(); System.out.println("Employee data: "); System.out.println("\tid: " + payload.get("id").getAsInt()); System.out.println("\tname: " + payload.get("name")); }); [EDIT] Another update. Allows you to return DTO objects public class TestDTO { public TestDTO() throws MalformedURLException { // Create payload JsonObject body = new JsonObject(); body.addProperty("id", 1); // Create request object RequestEntity<JsonObject> request = new RequestEntity<>(HttpMethod.POST, body); // Send request to server request.exchangeAsync("http://localhost/GetEmployee", Employee.class, (response)->{ Employee employee = response.getBody(); System.out.println("Employee data: "); System.out.println("\tid: " + employee.getId()); System.out.println("\tname: " + employee.getName()); }); } public static void main(String[] args) throws MalformedURLException, IOException { new TestDTO(); } } /** * DTO used to represent employee information sent from server. */ class Employee { private int id; private String name; public Employee() { // } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } }
  12. Hey all, For a project I'm working on in Tribot, I found I needed to make some rest calls to a back-end server. While in the enterprise world I'd normally use Spring or some other large library, they wont work in Tribot due to their heavy use of reflection and massive startup-times. I've written a pretty light-weight REST call library and wanted to share it here for anyone interested! This library is super tiny (1 package) and starts almost instantly, so it's very bot friendly. A lot of other restful libraries take a long time to turn on, which gets in the way of starting scripts. Website: https://jrest.io/ Source: https://github.com/orange451/JRest With it, you can either host your own rest-server endpoints, or make a call to any rest endpoint. I should note, that by Dependency-less, I mean that it doesn't need any other dependencies to function. However DTO/POJO serialization/deserialization requires Gson (in Tribot dependencies folder) What could you benefit from using REST calls? What can you do with them? Simplify your client/server communication protocols Make global statistics for your scripts easier! Communicate to Muels/other clients Here's some examples: Synchronous GET Request: RequestEntity<String> request = new RequestEntity<>(HttpMethod.GET); ResponseEntity<String> response = request.exchange("http://localhost/testAPI", String.class); System.out.println(response.getBody()); Asynchronous GET Request: RequestEntity<JsonObject> request = new RequestEntity<>(HttpMethod.GET); request.exchangeAsync("http://localhost/testJson", JsonObject.class, (response)->{ System.out.println(response.getBody()); }); REST Server: public class TestServer extends RestServer { public TestServer() { /** * Test Endpoint. Returns static String */ this.addEndpoint(HttpMethod.GET, "/testAPI", (request)->{ return new ResponseEntity<String>(HttpStatus.OK, "Hello From Server!"); }); /** * Test Post endpoint. Returns your posted data back to you. */ this.addEndpoint(HttpMethod.POST, "/testPost", MediaType.ALL, MediaType.ALL, (request)->{ return new ResponseEntity<String>(HttpStatus.OK, request.getBody().toString()); }); /** * Test JSON endpoint. Returns a JSON object. */ this.addEndpoint(HttpMethod.GET, "/testJson", MediaType.ALL, MediaType.APPLICATION_JSON, (request)->{ JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("TestKey", "Hello World!"); return new ResponseEntity<JsonObject>(HttpStatus.OK, jsonObject); }); } @Override public int getPort() { return 80; } public static void main(String[] args) { new TestServer(); } } Any feedback is welcome! Some notes: By default data is sent over the network as a String. The rest endpoint methods and exchange methods contain a generic T class type operator that lets you better control what type of data you are sending. Strings, Lists, and Maps can be sent over the network out-of-the box. If you use DaxWalker, you can use JSONObject and JSONArray as they extend Map and list (see above) Custom DTO objects and JsonElement types can be sent over network using GSON Library (Comes with tribot) This can be used to not only make REST calls, but also host REST Endpoints It follows standard HTTP protocol, so your hosted REST Endpoints also work as a Web Server (NOT TESTED WITH HTTPS)
  13. Hiah! If you're like me, you find yourself using DPathNavigator to traverse small and contained locations, you probably know how unreliable it can be. I was playing around with DaxWalker's API earlier, and found it has a nice method: WalkerEngine#walkPath(ArrayList<RSTile>, WalkingCondition) You can easily combine this with Tribot's PathFinding/DPathNavigator class like this: RSTile[] path = PathFinding.generatePath(Player.getPosition(), tile.getPosition(), true); if ( path != null && path.length > 0 ) { WalkerEngine.getInstance().walkPath(new ArrayList<>(Arrays.asList(path))); } From my testing, this works much smoother than DPathNavigator traverse method, and doesn't get stuck nearly as often. Works especially well on tutorial island! DPathNavigator gets me stuck on nearly half the doors. Also, since you're just using the WalkerEngine method, this doesn't use up one of your API calls for DaxWalker.
  14. Here's a small snippet I wrote for my personal use. This makes querying GE items DTO friendly. public class GrandExchangeUtil { /** Internal GE data */ private static JSONObject priceData; /** Last timestamp GE data was downloaded */ private static long lastUpdateTime; /** Rate at which we refresh internally stored GE data */ public static long REFRESH_GE_TIME = 1000 * 60; /** * Force fetches all the price data for GE Items. */ public static void forceUpdateGEPriceData() { try { String address = "https://rsbuddy.com/exchange/summary.json"; URL url = new URL(address); URLConnection connection = url.openConnection(); InputStream inputStream = connection.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(reader); String jsonSource = bufferedReader.readLine(); bufferedReader.close(); JSONParser parser = new JSONParser(); priceData = (JSONObject) parser.parse(jsonSource); lastUpdateTime = System.currentTimeMillis(); } catch(Exception e ) { e.printStackTrace(); } } private static void updateGEPriceData() { if ( priceData == null || System.currentTimeMillis()-lastUpdateTime > REFRESH_GE_TIME ) forceUpdateGEPriceData(); } /** * Get GEItem from OSRS item ID * @param id * @return */ public static GEItem getItemData(int id) { updateGEPriceData(); JSONObject data = (JSONObject) priceData.get(Integer.toString(id)); if ( data == null ) return null; return new GEItem(data); } /** * Get GEItem from RSItem * @param id * @return */ public static GEItem getItemData(RSItem item) { return getItemData(item.getID()); } } public class GEItem { /** ID of the item */ private int id; /** Display name of the item */ private String name; /** Is item Members only */ private boolean members; /** Average price bought */ private int buyAverage; /** Average quantity bought */ private int buyQuantity; /** Average price sold */ private int sellAverage; /** Average quantity sold */ private int sellQuantity; /** Overall average price */ private int overallAverage; /** Overall average quantity */ private int overallQuantity; /** sp */ private int sp; public GEItem(Map<String,Object> data) { this.id = toIntegerSafe(data.get("id")); this.name = toStringSafe(data.get("name")); this.members = toBooleanSafe(data.get("members")); this.buyAverage = toIntegerSafe(data.get("buy_average")); this.buyQuantity = toIntegerSafe(data.get("buy_quantity")); this.sellAverage = toIntegerSafe(data.get("sell_average")); this.sellQuantity = toIntegerSafe(data.get("sell_quantity")); this.overallAverage = toIntegerSafe(data.get("overall_average")); this.overallQuantity = toIntegerSafe(data.get("overall_quantity")); this.sp = toIntegerSafe(data.get("sp")); } public void setId(int id) { this.id = id; } public int getId() { return this.id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public boolean isMembers() { return this.members; } public void setMembers(boolean members) { this.members = members; } public int getBuyAverage() { return this.buyAverage; } public void setBuyAverage(int average) { this.buyAverage = average; } public int getBuyQuantity() { return this.buyQuantity; } public void setBuyQuantity(int buyQuantity) { this.buyQuantity = buyQuantity; } public int getSellAverage() { return this.sellAverage; } public void setSellAverage(int average) { this.sellAverage = average; } public int getSellQuantity() { return this.sellQuantity; } public void setSellQuantity(int quantity) { this.sellQuantity = quantity; } public int getOverallAverage() { return this.overallAverage; } public void setOverallAverage(int average) { this.overallAverage = average; } public int getOverallQuantity() { return this.overallQuantity; } public void setOverallQuantity(int quantity) { this.overallQuantity = quantity; } public int getSP() { return this.sp; } private int toIntegerSafe(Object object) { if ( object instanceof String ) { try { return (int)Double.parseDouble(object.toString()); } catch(Exception e) { e.printStackTrace(); return 0; } } if ( object instanceof Number ) return ((Number)object).intValue(); return 0; } private String toStringSafe(Object object) { if ( object == null ) return ""; return object.toString(); } private boolean toBooleanSafe(Object object) { if ( object == null ) return false; if ( !(object instanceof Boolean) ) return false; return ((Boolean)object).booleanValue(); } @SuppressWarnings("unchecked") public JSONObject toJSON() { JSONObject json = new JSONObject(); json.put("id", this.getId()); json.put("name", this.getName()); json.put("members", this.isMembers()); json.put("sp", this.getSP()); json.put("buy_average", this.getBuyAverage()); json.put("buy_quantity", this.getBuyQuantity()); json.put("sell_average", this.getSellAverage()); json.put("sell_quantity", this.getSellQuantity()); json.put("overall_average", this.getOverallAverage()); json.put("overall_quantity", this.getOverallQuantity()); return json; } }
  15. As per new GE trade restrictions, we need 100 total level, 10 qp, and 20 hours played. First two are easy to check, what about hours played?
  • Create New...