Explv Posted July 14, 2016 Share Posted July 14, 2016 (edited) Here is a simple class I have written to retrieve grand exchange information for specified osrs items, using the json file hosted by rsbuddy at: https://rsbuddy.com/exchange/summary.json Note the retrieval of this data should only be done once at the start of your script, and you should store the map for use later rather than re-calling the method. You may also get better performance using a JSON library. RSExchange.java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class RSExchange { private final String ITEMS_JSON; public RSExchange() { ITEMS_JSON = getItemsJson().orElse(""); } private Optional<String> getItemsJson() { try { URL url = new URL("https://rsbuddy.com/exchange/summary.json"); URLConnection con = url.openConnection(); con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); con.setUseCaches(true); BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); String json = br.readLine(); br.close(); return Optional.of(json); } catch (Exception e) { e.printStackTrace(); } return Optional.empty(); } public final Optional<ExchangeItem> getExchangeItem(final String itemName) { return getItemID(ITEMS_JSON, itemName).map(id -> new ExchangeItem(itemName, id)); } public final Map<String, ExchangeItem> getExchangeItems(final String... itemNames) { Map<String, ExchangeItem> exchangeItems = new HashMap<>(); for (final String itemName : itemNames) { getItemID(ITEMS_JSON, itemName).ifPresent(id -> exchangeItems.put(itemName, new ExchangeItem(itemName, id))); } return exchangeItems; } private Optional<Integer> getItemID(final String json, final String itemName) { return getItemFromJson(json, itemName).flatMap(this::getItemIDFromItemJson); } private Optional<String> getItemFromJson(final String json, final String itemName) { Matcher matcher = Pattern.compile("(\\{[^}]*\"name\"\\s*:\\s*\"" + Pattern.quote(itemName) + "\"[^}]*})").matcher(json); return matcher.find() ? Optional.of(matcher.group(1)) : Optional.empty(); } private Optional<Integer> getItemIDFromItemJson(final String json) { Matcher matcher = Pattern.compile("\"id\"\\s*:\\s*(\\d*)").matcher(json); return matcher.find() ? Optional.of(Integer.parseInt(matcher.group(1))) : Optional.empty(); } } ExchangeItem.java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class ExchangeItem { private final String name; private final int id; private int overallAverage = -1; private int buyAverage = -1; private int sellAverage = -1; private int buyingQuantity; private int sellingQuantity; public ExchangeItem(final String name, final int id) { this.name = name; this.id = id; updateRSBuddyValues(); } public final String getName() { return name; } public final int getId() { return id; } public final int getBuyAverage() { return buyAverage; } public final int getSellAverage() { return sellAverage; } public final int getBuyingQuantity() { return buyingQuantity; } public final int getSellingQuantity() { return sellingQuantity; } public void updateRSBuddyValues() { try { URL url = new URL("http://api.rsbuddy.com/grandExchange?a=guidePrice&i=" + id); URLConnection con = url.openConnection(); con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); con.setUseCaches(true); BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); String json = br.readLine(); br.close(); getItemValue("overall", json).ifPresent(overallAverage -> this.overallAverage = overallAverage); getItemValue("buying", json).ifPresent(sellAverage -> this.sellAverage = sellAverage); getItemValue("selling", json).ifPresent(buyAverage -> this.buyAverage = buyAverage); getItemValue("buyingQuantity", json).ifPresent(buyQuantity -> this.buyingQuantity = buyQuantity); getItemValue("sellingQuantity", json).ifPresent(sellingQuantity -> this.sellingQuantity = sellingQuantity); } catch (Exception e) { e.printStackTrace(); } } private Optional<Integer> getItemValue(final String key, final String json) { Matcher overallAvgMatcher = Pattern.compile("\"" + key + "\"\\s*:\\s*(\\d*)").matcher(json); if (overallAvgMatcher.find()) { return Optional.of(Integer.parseInt(overallAvgMatcher.group(1))); } return Optional.empty(); } public final String toString() { return String.format("Name: %s, ID: %d, Overall AVG: %d gp, Buying AVG: %d gp, Selling AVG: %d gp, Buying Quantity: %d, Selling Quantity:%d", name, id, overallAverage, buyAverage, sellAverage, buyingQuantity, sellingQuantity); } } Usage: final RSExchange rsExchange = new RSExchange(); rsExchange.getExchangeItem("Yew logs").ifPresent(System.out::println); This would print out Name: Yew logs, ID: 1515, Overall AVG: 355 gp, Buying AVG: 355 gp, Selling AVG: 354 gp, Buying Quantity: 90576, Selling Quantity :71726 Edited July 30, 2017 by Explv 15 Quote Link to comment Share on other sites More sharing options...
Fruity Posted July 14, 2016 Share Posted July 14, 2016 very nice, thanks for the share ^^ Quote Link to comment Share on other sites More sharing options...
IHB Posted July 14, 2016 Share Posted July 14, 2016 Peng Quote Link to comment Share on other sites More sharing options...
Token Posted July 14, 2016 Share Posted July 14, 2016 Nice one, it eliminates the item id requirement from price queries which is really annoying when not owning the specific item (it can be retrieved from an item container) You can improve the caching to make it more memory friendly as that's really important when running lots of instances and the current one may take like 10 mb memory per instance versus an optimized cache which takes up like 1000 less memory (without data loss) Quote Link to comment Share on other sites More sharing options...
Explv Posted July 14, 2016 Author Share Posted July 14, 2016 Nice one, it eliminates the item id requirement from price queries which is really annoying when not owning the specific item (it can be retrieved from an item container) You can improve the caching to make it more memory friendly as that's really important when running lots of instances and the current one may take like 10 mb memory per instance versus an optimized cache which takes up like 1000 less memory (without data loss) Yeah I will be improving this further, I just wrote this up quickly to get things started 1 Quote Link to comment Share on other sites More sharing options...
Chicken Wing Posted July 14, 2016 Share Posted July 14, 2016 Make it a singleton? Quote Link to comment Share on other sites More sharing options...
Dial Posted July 14, 2016 Share Posted July 14, 2016 nice release Quote Link to comment Share on other sites More sharing options...
Saiyan Posted July 14, 2016 Share Posted July 14, 2016 Very very nice thank you for this Quote Link to comment Share on other sites More sharing options...
Explv Posted July 14, 2016 Author Share Posted July 14, 2016 Nice one, it eliminates the item id requirement from price queries which is really annoying when not owning the specific item (it can be retrieved from an item container) You can improve the caching to make it more memory friendly as that's really important when running lots of instances and the current one may take like 10 mb memory per instance versus an optimized cache which takes up like 1000 less memory (without data loss) I've updated it. Should be a bit more memory efficient now. Still some improvements that could be made but I cba 1 Quote Link to comment Share on other sites More sharing options...
Harry Posted July 14, 2016 Share Posted July 14, 2016 tank u : ) Quote Link to comment Share on other sites More sharing options...
Explv Posted July 14, 2016 Author Share Posted July 14, 2016 Peng Peng ting innit 1 Quote Link to comment Share on other sites More sharing options...
Botre Posted July 20, 2016 Share Posted July 20, 2016 Nice one, it eliminates the item id requirement from price queries which is really annoying when not owning the specific item (it can be retrieved from an item container) You can improve the caching to make it more memory friendly as that's really important when running lots of instances and the current one may take like 10 mb memory per instance versus an optimized cache which takes up like 1000 less memory (without data loss) Unless you want to support MP3 players from 2002, 10mb is irrelevant. 1 Quote Link to comment Share on other sites More sharing options...
Solzhenitsyn Posted August 2, 2016 Share Posted August 2, 2016 If I set references to the table with all of the data to null after pulling the information from it, will it free all allocated memory? Quote Link to comment Share on other sites More sharing options...
Solzhenitsyn Posted August 2, 2016 Share Posted August 2, 2016 It shouldn't be using up too much memory. You should only load the json once, then it will read the text it saved from the site from then on to grab the correct item price. But if I set all references to null, will the object be deleted by the garbage collector? I don't know anything about Java, and losing references without manually deleting things just seems like a terrible idea. In any case, I'm already on swap so every byte counts. Quote Link to comment Share on other sites More sharing options...
Explv Posted August 2, 2016 Author Share Posted August 2, 2016 (edited) But if I set all references to null, will the object be deleted by the garbage collector? I don't know anything about Java, and losing references without manually deleting things just seems like a terrible idea. In any case, I'm already on swap so every byte counts. sigh perhaps you should read up on the Java Garbage Collector then. If you are really concerned about memory usage, then perhaps you should use a profiler to see how much memory, and where the memory is being used. It isn't really a concern though. It's just a Map containing a few objects.. Edited August 2, 2016 by Explv Quote Link to comment Share on other sites More sharing options...