Jump to content

GE Data (get price etc. by item name) no external libraries required


Explv

Recommended Posts

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 by Explv
  • Like 15
Link to comment
Share on other sites

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)

 

:doge:

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 :feels: versus an optimized cache which takes up like 1000 less memory (without data loss)

Link to comment
Share on other sites

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)

:doge:

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 :feels: 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 :)

  • Like 1
Link to comment
Share on other sites

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)

 

doge.png

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 feels.png 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 :doge:

  • Like 1
Link to comment
Share on other sites

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)

 

doge.png

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 feels.png 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.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

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.

Link to comment
Share on other sites

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 by Explv
Link to comment
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.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...