The client is offline due to RuneScape update. You may see instance errors but this is due to the update and not actual instance errors. This should be resolved soon. Join our Discord for more information.

Open Source Price Checker


  • Director

    Small class to lookup item price by name or id from RSBuddy GE API. Refreshes every 30 minutes by default to keep prices updated.

    package org.rspeer.runetek.api.commons;
    
    import com.acuitybotting.common.utils.ExecutorUtil;
    import com.allatori.annotations.DoNotRename;
    import com.google.gson.Gson;
    import com.google.gson.JsonObject;
    import com.google.gson.annotations.SerializedName;
    import com.mashape.unirest.http.HttpResponse;
    import com.mashape.unirest.http.Unirest;
    import com.mashape.unirest.http.exceptions.UnirestException;
    import org.rspeer.ui.Log;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.ScheduledFuture;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class PriceCheck {
    
        private static Gson g = new Gson();
        private static Map<String, Integer> itemNameMapping = new HashMap<>();
        private static Map<Integer, ItemPrice> prices = new HashMap<>();
        private static int reloadMinutes = 30;
        private static boolean isReloadEnabled = true;
    
        private static ScheduledThreadPoolExecutor executor = ExecutorUtil.newScheduledExecutorPool(1, Throwable::printStackTrace);
        private static ScheduledFuture<?> task;
    
        public static ItemPrice getPrice(String name) {
            if(prices.size() == 0) {
                reload();
            }
            int id = itemNameMapping.getOrDefault(name.toLowerCase(), -1);
            return id == -1 ? null : getPrice(id);
        }
    
        public static ItemPrice getPrice(int id) {
            if(prices.size() == 0) {
                reload();
            }
            return prices.getOrDefault(id, null);
        }
    
        public static void reload() {
            if(!isReloadEnabled && prices.size() > 0) {
                return;
            }
            if(task == null && isReloadEnabled) {
                task = executor.scheduleAtFixedRate(PriceCheck::reload, reloadMinutes, reloadMinutes, TimeUnit.MINUTES);
            }
            try {
                HttpResponse<String> node = Unirest.get("https://rsbuddy.com/exchange/summary.json").asString();
                if(node.getStatus() != 200) {
                    System.out.println(node.getBody());
                    Log.severe("PriceCheck", "Failed to load prices. Result: " + node.getBody());
                    return;
                }
                JsonObject o = g.fromJson(node.getBody(), JsonObject.class);
                for (String s : o.keySet()) {
                    ItemPrice price = g.fromJson(o.get(s).getAsJsonObject(), ItemPrice.class);
                    int id = Integer.parseInt(s);
                    String name = price.name.toLowerCase();
                    itemNameMapping.remove(name);
                    itemNameMapping.put(name, id);
                    prices.remove(id);
                    prices.put(id, price);
                }
            } catch (UnirestException e) {
                e.printStackTrace();
               Log.severe(e);
            }
        }
    
        public static void dispose() {
            task.cancel(true);
            executor.shutdown();
        }
    
        public static void setShouldReload(boolean value) {
            isReloadEnabled = value;
        }
    
        @DoNotRename
        public class ItemPrice {
    
            @DoNotRename
            private String name;
            @DoNotRename
            private boolean members;
            @DoNotRename
            @SerializedName("buy_average")
            private int buyAverage;
            @DoNotRename
            @SerializedName("sell_average")
            private int sellAverage;
            @DoNotRename
            @SerializedName("overall_average")
            private int overallAverage;
    
            public String getName() {
                return name;
            }
    
            public boolean isMembers() {
                return members;
            }
    
            public int getBuyAverage() {
                return buyAverage;
            }
    
            public int getSellAverage() {
                return sellAverage;
            }
    
            public int getOverallAverage() {
                return overallAverage;
            }
        }
    }
    


  • thanks really good one



  • @MadDev is it normal that there are NPEs when the http update request fails on the server side ?

    [09:35:14] EXCEPTION SEVERE com.mashape.unirest.http.exceptions.UnirestException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:143)
    at com.mashape.unirest.request.BaseRequest.asString(BaseRequest.java:56)
    at PriceCheck.reload(PriceCheck.java:51)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
    Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at java.base/sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:526)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:462)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:138)
    ... 8 more


  • Script Writer

    For anyone looking to use this in an SDN script, you will need to break the ItemPrice class into its own class in a separate file, rather than as an inner class. Otherwise, you will get an java.lang.InternalError: Malformed class name when people run your script from SDN. Credit to @Asta for figuring this out.


 

55
Online

16.6k
Users

1.4k
Topics

19.2k
Posts