diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java index 17784dd67b..0e34a05742 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java @@ -26,6 +26,7 @@ package net.runelite.http.api.item; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; +import io.reactivex.Observable; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; @@ -112,7 +113,7 @@ public class ItemClient } } - public BufferedImage getIcon(int itemId) throws IOException + public Observable getIcon(int itemId) { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -126,23 +127,26 @@ public class ItemClient .url(url) .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error grabbing icon {}: {}", itemId, response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error grabbing icon {}: {}", itemId, response); + return Observable.just(null); + } - InputStream in = response.body().byteStream(); - synchronized (ImageIO.class) - { - return ImageIO.read(in); + InputStream in = response.body().byteStream(); + synchronized (ImageIO.class) + { + return Observable.just(ImageIO.read(in)); + } } - } + }); } - public SearchResult search(String itemName) throws IOException + public Observable search(String itemName) { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -152,28 +156,31 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error looking up item {}: {}", itemName, response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error looking up item {}: {}", itemName, response); + return Observable.just(null); + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SearchResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SearchResult.class)); + } + catch (JsonParseException ex) + { + return Observable.error(ex); + } + }); } - public ItemPrice[] getPrices() throws IOException + public Observable getPrices() { HttpUrl.Builder urlBuilder = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -183,28 +190,32 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.warn("Error looking up prices: {}", response); - return null; - } + if (!response.isSuccessful()) + { + logger.warn("Error looking up prices: {}", response); + return Observable.just(null); + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), ItemPrice[].class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), ItemPrice[].class)); + } + catch (JsonParseException ex) + { + return Observable.error(ex); + } + }); } - public Map getStats() throws IOException + public Observable> getStats() { HttpUrl.Builder urlBuilder = RuneLiteAPI.getStaticBase().newBuilder() .addPathSegment("item") @@ -215,27 +226,31 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.warn("Error looking up item stats: {}", response); - return null; + if (!response.isSuccessful()) + { + logger.warn("Error looking up item stats: {}", response); + return Observable.just(null); + } + + InputStream in = response.body().byteStream(); + final Type typeToken = new TypeToken>() + { + }.getType(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), typeToken)); } - - InputStream in = response.body().byteStream(); - final Type typeToken = new TypeToken>() + catch (JsonParseException ex) { - }.getType(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), typeToken); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + return Observable.error(ex); + } + }); } } diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java index 3c187552fc..1739125f8c 100644 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java +++ b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java @@ -58,7 +58,7 @@ public class OSBGrandExchangeClient { if (!response.isSuccessful()) { - throw new IOException("Error looking up item id: " + response); + return Observable.error(new IOException("Error looking up item id: " + response)); } final InputStream in = response.body().byteStream(); diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java index 668e088404..13559bdd3b 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java @@ -26,6 +26,9 @@ package net.runelite.http.api.worlds; import com.google.gson.JsonParseException; +import io.reactivex.Observable; +import java.io.InputStream; +import java.io.InputStreamReader; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; import okhttp3.Request; @@ -33,15 +36,11 @@ import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - public class WorldClient { private static final Logger logger = LoggerFactory.getLogger(WorldClient.class); - public WorldResult lookupWorlds() throws IOException + public Observable lookupWorlds() { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("worlds.js") @@ -49,24 +48,27 @@ public class WorldClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error looking up worlds: {}", response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error looking up worlds: {}", response); + return Observable.just(null); + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class)); + } + catch (JsonParseException ex) + { + return Observable.error(ex); + } + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java index 805b7a5620..8935c8118e 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java @@ -27,14 +27,16 @@ package net.runelite.client.callback; import com.google.inject.Inject; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import org.jetbrains.annotations.NotNull; @Singleton @Slf4j -public class ClientThread +public class ClientThread implements Executor { private final ConcurrentLinkedQueue invokes = new ConcurrentLinkedQueue<>(); @@ -112,4 +114,14 @@ public class ClientThread } } } + + @Override + public void execute(@NotNull Runnable r) + { + invoke(() -> + { + r.run(); + return true; + }); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 34a95e613a..9a60cf848f 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -30,9 +30,9 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import io.reactivex.schedulers.Schedulers; import java.awt.Color; import java.awt.image.BufferedImage; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; @@ -142,6 +142,7 @@ public class ItemManager private final LoadingCache itemOutlines; private Map itemPrices = Collections.emptyMap(); private Map itemStats = Collections.emptyMap(); + @Inject public ItemManager( Client client, @@ -209,43 +210,43 @@ public class ItemManager private void loadPrices() { - try - { - ItemPrice[] prices = itemClient.getPrices(); - if (prices != null) - { - ImmutableMap.Builder map = ImmutableMap.builderWithExpectedSize(prices.length); - for (ItemPrice price : prices) + itemClient.getPrices() + .subscribeOn(Schedulers.io()) + .subscribe( + (prices) -> { - map.put(price.getId(), price); - } - itemPrices = map.build(); - } + if (prices != null) + { + ImmutableMap.Builder map = ImmutableMap.builderWithExpectedSize(prices.length); + for (ItemPrice price : prices) + { + map.put(price.getId(), price); + } + itemPrices = map.build(); + } - log.debug("Loaded {} prices", itemPrices.size()); - } - catch (IOException e) - { - log.warn("error loading prices!", e); - } + log.debug("Loaded {} prices", itemPrices.size()); + }, + (e) -> log.warn("error loading prices!", e) + ); } private void loadStats() { - try - { - final Map stats = itemClient.getStats(); - if (stats != null) - { - itemStats = ImmutableMap.copyOf(stats); - } + itemClient.getStats() + .subscribeOn(Schedulers.io()) + .subscribe( + (stats) -> + { + if (stats != null) + { + itemStats = ImmutableMap.copyOf(stats); + } - log.debug("Loaded {} stats", itemStats.size()); - } - catch (IOException e) - { - log.warn("error loading stats!", e); - } + log.debug("Loaded {} stats", itemStats.size()); + }, + (e) -> log.warn("error loading stats!", e) + ); } private void onGameStateChanged(final GameStateChanged event) @@ -285,7 +286,7 @@ public class ItemManager /** * Look up an item's price * - * @param itemID item id + * @param itemID item id * @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping} * @return item price */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 4c411000a4..4d363e21ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -827,45 +827,45 @@ public class ChatCommandsPlugin extends Plugin { ItemPrice item = retrieveFromList(results, search); CLIENT.lookupItem(item.getId()) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> + { + int itemId = item.getId(); + int itemPrice = itemManager.getItemPrice(itemId); + + final ChatMessageBuilder builder = new ChatMessageBuilder(); + builder.append(ChatColorType.NORMAL); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(item.getName()); + builder.append(ChatColorType.NORMAL); + builder.append(": GE "); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(StackFormatter.formatNumber(itemPrice)); + builder.append(ChatColorType.NORMAL); + builder.append(": OSB "); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(StackFormatter.formatNumber(osbresult.getOverall_average())); + + ItemDefinition itemComposition = itemManager.getItemDefinition(itemId); + if (itemComposition != null) { - int itemId = item.getId(); - int itemPrice = itemManager.getItemPrice(itemId); + int alchPrice = itemManager.getAlchValue(itemId); + builder + .append(ChatColorType.NORMAL) + .append(" HA value ") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(alchPrice)); + } - final ChatMessageBuilder builder = new ChatMessageBuilder(); - builder.append(ChatColorType.NORMAL); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(item.getName()); - builder.append(ChatColorType.NORMAL); - builder.append(": GE "); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(StackFormatter.formatNumber(itemPrice)); - builder.append(ChatColorType.NORMAL); - builder.append(": OSB "); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(StackFormatter.formatNumber(osbresult.getOverall_average())); + String response = builder.build(); - ItemDefinition itemComposition = itemManager.getItemDefinition(itemId); - if (itemComposition != null) - { - int alchPrice = itemManager.getAlchValue(itemId); - builder - .append(ChatColorType.NORMAL) - .append(" HA value ") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(alchPrice)); - } - - String response = builder.build(); - - log.debug("Setting response {}", response); - messageNode.setRuneLiteFormatMessage(response); - chatMessageManager.update(messageNode); - client.refreshChat(); - }) + log.debug("Setting response {}", response); + messageNode.setRuneLiteFormatMessage(response); + chatMessageManager.update(messageNode); + client.refreshChat(); + } ); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java index 0999eda3c1..39614234bd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -25,13 +25,14 @@ package net.runelite.client.plugins.defaultworld; import com.google.inject.Provides; -import java.io.IOException; +import io.reactivex.schedulers.Schedulers; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionOpen; @@ -40,7 +41,6 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldClient; -import net.runelite.http.api.worlds.WorldResult; @PluginDescriptor( name = "Default World", @@ -60,6 +60,9 @@ public class DefaultWorldPlugin extends Plugin @Inject private EventBus eventBus; + @Inject + private ClientThread clientThread; + private final WorldClient worldClient = new WorldClient(); private int worldCache; private boolean worldChangeRequired; @@ -122,39 +125,39 @@ public class DefaultWorldPlugin extends Plugin return; } - try - { - final WorldResult worldResult = worldClient.lookupWorlds(); + worldClient.lookupWorlds() + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) + .subscribe( + (worldResult) -> + { + if (worldResult == null) + { + return; + } - if (worldResult == null) - { - return; - } + final World world = worldResult.findWorld(correctedWorld); - final World world = worldResult.findWorld(correctedWorld); + if (world != null) + { + final net.runelite.api.World rsWorld = client.createWorld(); + rsWorld.setActivity(world.getActivity()); + rsWorld.setAddress(world.getAddress()); + rsWorld.setId(world.getId()); + rsWorld.setPlayerCount(world.getPlayers()); + rsWorld.setLocation(world.getLocation()); + rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); - if (world != null) - { - final net.runelite.api.World rsWorld = client.createWorld(); - rsWorld.setActivity(world.getActivity()); - rsWorld.setAddress(world.getAddress()); - rsWorld.setId(world.getId()); - rsWorld.setPlayerCount(world.getPlayers()); - rsWorld.setLocation(world.getLocation()); - rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); - - client.changeWorld(rsWorld); - log.debug("Applied new world {}", correctedWorld); - } - else - { - log.warn("World {} not found.", correctedWorld); - } - } - catch (IOException e) - { - log.warn("Error looking up world {}. Error: {}", correctedWorld, e); - } + client.changeWorld(rsWorld); + log.debug("Applied new world {}", correctedWorld); + } + else + { + log.warn("World {} not found.", correctedWorld); + } + }, + (e) -> log.warn("Error looking up world {}. Error: {}", correctedWorld, e) + ); } private void applyWorld() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 3cdf71dff4..32ad61add6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -370,37 +370,37 @@ public class ExaminePlugin extends Plugin { int finalQuantity = quantity; CLIENT.lookupItem(id) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> + { + message + .append(ChatColorType.NORMAL) + .append(" GE ") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(gePrice * finalQuantity)); + + if (osbresult != null) { message .append(ChatColorType.NORMAL) - .append(" GE ") + .append(" OSB ") .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(gePrice * finalQuantity)); + .append(StackFormatter.formatNumber(osbresult.getOverall_average() * finalQuantity)); + } - if (osbresult != null) - { - message - .append(ChatColorType.NORMAL) - .append(" OSB ") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(osbresult.getOverall_average() * finalQuantity)); - } - - if (finalQuantity > 1) - { - message - .append(ChatColorType.NORMAL) - .append(" (") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(gePrice)) - .append(ChatColorType.NORMAL) - .append("ea)"); - } - }), + if (finalQuantity > 1) + { + message + .append(ChatColorType.NORMAL) + .append(" (") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(gePrice)) + .append(ChatColorType.NORMAL) + .append("ea)"); + } + }, (e) -> log.error(e.toString()) ); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 9fc24c8bab..b8ffc3c9b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -551,14 +551,14 @@ public class GrandExchangePlugin extends Plugin } CLIENT.lookupItem(itemId) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> - { - final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); - geText.setText(text); - }), + { + final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); + geText.setText(text); + }, (e) -> log.debug("Error getting price of item {}", itemId, e) ); }); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 7613e456ce..1b99c8549c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -29,8 +29,8 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; +import io.reactivex.schedulers.Schedulers; import java.awt.image.BufferedImage; -import java.io.IOException; import java.time.Duration; import java.time.Instant; import java.util.Comparator; @@ -502,22 +502,21 @@ public class WorldHopperPlugin extends Plugin { log.debug("Fetching worlds"); - try - { - WorldResult worldResult = new WorldClient().lookupWorlds(); - - if (worldResult != null) - { - worldResult.getWorlds().sort(Comparator.comparingInt(World::getId)); - this.worldResult = worldResult; - this.lastFetch = Instant.now(); - updateList(); - } - } - catch (IOException ex) - { - log.warn("Error looking up worlds", ex); - } + new WorldClient().lookupWorlds() + .subscribeOn(Schedulers.io()) + .subscribe( + (worldResult) -> + { + if (worldResult != null) + { + worldResult.getWorlds().sort(Comparator.comparingInt(World::getId)); + this.worldResult = worldResult; + this.lastFetch = Instant.now(); + updateList(); + } + }, + (ex) -> log.warn("Error looking up worlds", ex) + ); } /**